early-access version 2847

This commit is contained in:
pineappleEA
2022-07-19 05:48:31 +02:00
parent ba74a2373c
commit 05e3c38e7f
498 changed files with 16027 additions and 27028 deletions

View File

@@ -47,7 +47,6 @@
#include "SDL_bits.h"
#include "SDL_revision.h"
#include "SDL_assert_c.h"
#include "SDL_log_c.h"
#include "events/SDL_events_c.h"
#include "haptic/SDL_haptic_c.h"
#include "joystick/SDL_joystick_c.h"
@@ -62,26 +61,6 @@ extern int SDL_HelperWindowCreate(void);
extern int SDL_HelperWindowDestroy(void);
#endif
#ifdef SDL_BUILD_MAJOR_VERSION
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MAJOR_VERSION,
SDL_MAJOR_VERSION == SDL_BUILD_MAJOR_VERSION);
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MINOR_VERSION,
SDL_MINOR_VERSION == SDL_BUILD_MINOR_VERSION);
SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MICRO_VERSION,
SDL_PATCHLEVEL == SDL_BUILD_MICRO_VERSION);
#endif
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_min, SDL_MAJOR_VERSION >= 0);
/* Limited only by the need to fit in SDL_version */
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_max, SDL_MAJOR_VERSION <= 255);
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_min, SDL_MINOR_VERSION >= 0);
/* Limited only by the need to fit in SDL_version */
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_max, SDL_MINOR_VERSION <= 255);
SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_min, SDL_PATCHLEVEL >= 0);
/* Limited by its encoding in SDL_VERSIONNUM and in the ABI versions */
SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_max, SDL_PATCHLEVEL <= 99);
/* This is not declared in any header, although it is shared between some
parts of SDL, because we don't want anything calling it without an
@@ -174,11 +153,10 @@ SDL_InitSubSystem(Uint32 flags)
Uint32 flags_initialized = 0;
if (!SDL_MainIsReady) {
return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
return -1;
}
SDL_LogInit();
/* Clear the error message */
SDL_ClearError();
@@ -230,7 +208,7 @@ SDL_InitSubSystem(Uint32 flags)
/* Initialize the timer subsystem */
if ((flags & SDL_INIT_TIMER)){
#if !SDL_TIMERS_DISABLED && !SDL_TIMER_DUMMY
#if !SDL_TIMERS_DISABLED
if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
if (SDL_TimerInit() < 0) {
goto quit_and_error;
@@ -339,8 +317,6 @@ SDL_InitSubSystem(Uint32 flags)
#endif
}
(void) flags_initialized; /* make static analysis happy, since this only gets used in error cases. */
return (0);
quit_and_error:
@@ -426,7 +402,7 @@ SDL_QuitSubSystem(Uint32 flags)
}
#endif
#if !SDL_TIMERS_DISABLED && !SDL_TIMER_DUMMY
#if !SDL_TIMERS_DISABLED
if ((flags & SDL_INIT_TIMER)) {
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
SDL_TimerQuit();
@@ -493,13 +469,12 @@ SDL_Quit(void)
SDL_ClearHints();
SDL_AssertionsQuit();
SDL_LogResetPriorities();
#if SDL_USE_LIBDBUS
SDL_DBus_Quit();
#endif
SDL_LogQuit();
/* Now that every subsystem has been quit, we reset the subsystem refcount
* and the list of initialized subsystems.
*/
@@ -583,14 +558,10 @@ SDL_GetPlatform(void)
return "tvOS";
#elif __IPHONEOS__
return "iOS";
#elif __PS2__
return "PlayStation 2";
#elif __PSP__
return "PlayStation Portable";
#elif __VITA__
return "PlayStation Vita";
#elif __NGAGE__
return "Nokia N-Gage";
#else
return "Unknown (see SDL_platform.h)";
#endif

View File

@@ -45,8 +45,6 @@
#include <emscripten.h>
#endif
/* The size of the stack buffer to use for rendering assert messages. */
#define SDL_MAX_ASSERT_MESSAGE_STACK 256
static SDL_assert_state SDLCALL
SDL_PromptAssertion(const SDL_assert_data *data, void *userdata);
@@ -90,20 +88,6 @@ static void SDL_AddAssertionToReport(SDL_assert_data *data)
}
}
#ifdef __WIN32__
#define ENDLINE "\r\n"
#else
#define ENDLINE "\n"
#endif
static int SDL_RenderAssertMessage(char *buf, size_t buf_len, const SDL_assert_data *data) {
return SDL_snprintf(buf, buf_len,
"Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE " '%s'",
data->function, data->filename, data->linenum,
data->trigger_count, (data->trigger_count == 1) ? "time" : "times",
data->condition
);
}
static void SDL_GenerateAssertionReport(void)
{
@@ -153,9 +137,16 @@ static SDL_NORETURN void SDL_AbortAssertion(void)
SDL_ExitProcess(42);
}
static SDL_assert_state SDLCALL
SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
{
#ifdef __WIN32__
#define ENDLINE "\r\n"
#else
#define ENDLINE "\n"
#endif
const char *envr;
SDL_assert_state state = SDL_ASSERTION_ABORT;
SDL_Window *window;
@@ -169,46 +160,30 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" }
};
char *message;
int selected;
char stack_buf[SDL_MAX_ASSERT_MESSAGE_STACK];
char *message = stack_buf;
size_t buf_len = sizeof(stack_buf);
int len;
(void) userdata; /* unused in default handler. */
/* Assume the output will fit... */
len = SDL_RenderAssertMessage(message, buf_len, data);
/* .. and if it didn't, try to allocate as much room as we actually need. */
if (len >= (int)buf_len) {
if (SDL_size_add_overflow(len, 1, &buf_len) == 0) {
message = (char *)SDL_malloc(buf_len);
if (message) {
len = SDL_RenderAssertMessage(message, buf_len, data);
} else {
message = stack_buf;
}
}
}
/* Something went very wrong */
if (len < 0) {
if (message != stack_buf) {
SDL_free(message);
}
/* !!! FIXME: why is this using SDL_stack_alloc and not just "char message[SDL_MAX_LOG_MESSAGE];" ? */
message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
if (!message) {
/* Uh oh, we're in real trouble now... */
return SDL_ASSERTION_ABORT;
}
SDL_snprintf(message, SDL_MAX_LOG_MESSAGE,
"Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE
" '%s'",
data->function, data->filename, data->linenum,
data->trigger_count, (data->trigger_count == 1) ? "time" : "times",
data->condition);
debug_print("\n\n%s\n\n", message);
/* let env. variable override, so unit tests won't block in a GUI. */
envr = SDL_getenv("SDL_ASSERT");
if (envr != NULL) {
if (message != stack_buf) {
SDL_free(message);
}
SDL_stack_free(message);
if (SDL_strcmp(envr, "abort") == 0) {
return SDL_ASSERTION_ABORT;
@@ -326,9 +301,7 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
SDL_RestoreWindow(window);
}
if (message != stack_buf) {
SDL_free(message);
}
SDL_stack_free(message);
return state;
}

View File

@@ -25,6 +25,8 @@
#include "SDL_error.h"
#include "SDL_error_c.h"
#define SDL_ERRBUFIZE 1024
int
SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{

View File

@@ -52,7 +52,7 @@ SDL_SetHintWithPriority(const char *name, const char *value,
SDL_Hint *hint;
SDL_HintWatch *entry;
if (!name) {
if (!name || !value) {
return SDL_FALSE;
}
@@ -66,7 +66,7 @@ SDL_SetHintWithPriority(const char *name, const char *value,
if (priority < hint->priority) {
return SDL_FALSE;
}
if (((hint->value == NULL) != (value == NULL)) || (value && (SDL_strcmp(hint->value, value) != 0))) {
if (!hint->value || !value || SDL_strcmp(hint->value, value) != 0) {
for (entry = hint->callbacks; entry; ) {
/* Save the next entry in case this one is deleted */
SDL_HintWatch *next = entry->next;
@@ -178,12 +178,6 @@ SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
return;
}
hint->name = SDL_strdup(name);
if (!hint->name) {
SDL_free(entry);
SDL_free(hint);
SDL_OutOfMemory();
return;
}
hint->value = NULL;
hint->priority = SDL_HINT_DEFAULT;
hint->callbacks = NULL;

View File

@@ -43,9 +43,10 @@
#if SDL_DYNAMIC_API
#include "dynapi/SDL_dynapi_overrides.h"
/* force DECLSPEC off...it's all internal symbols now.
/* force DECLSPEC and SDLCALL off...it's all internal symbols now.
These will have actual #defines during SDL_dynapi.c only */
#define DECLSPEC
#define SDLCALL
#endif
#include "SDL_config.h"

View File

@@ -28,8 +28,6 @@
#include "SDL_error.h"
#include "SDL_log.h"
#include "SDL_mutex.h"
#include "SDL_log_c.h"
#if HAVE_STDIO_H
#include <stdio.h>
@@ -39,12 +37,6 @@
#include <android/log.h>
#endif
#include "stdlib/SDL_vacopy.h"
/* The size of the stack buffer to use for rendering log messages. */
#define SDL_MAX_LOG_MESSAGE_STACK 256
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
@@ -67,7 +59,6 @@ static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY;
static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
static void *SDL_log_userdata = NULL;
static SDL_mutex *log_function_mutex = NULL;
static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
NULL,
@@ -101,24 +92,6 @@ static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
};
#endif /* __ANDROID__ */
void
SDL_LogInit(void)
{
if (!log_function_mutex) {
/* if this fails we'll try to continue without it. */
log_function_mutex = SDL_CreateMutex();
}
}
void
SDL_LogQuit(void)
{
SDL_LogResetPriorities();
if (log_function_mutex) {
SDL_DestroyMutex(log_function_mutex);
log_function_mutex = NULL;
}
}
void
SDL_LogSetAllPriority(SDL_LogPriority priority)
@@ -291,11 +264,8 @@ GetCategoryPrefix(int category)
void
SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap)
{
char *message = NULL;
char stack_buf[SDL_MAX_LOG_MESSAGE_STACK];
size_t len_plus_term;
int len;
va_list aq;
char *message;
size_t len;
/* Nothing to do if we don't have an output function */
if (!SDL_log_function) {
@@ -312,33 +282,16 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list
return;
}
if (!log_function_mutex) {
/* this mutex creation can race if you log from two threads at startup. You should have called SDL_Init first! */
log_function_mutex = SDL_CreateMutex();
}
/* Render into stack buffer */
va_copy(aq, ap);
len = SDL_vsnprintf(stack_buf, sizeof(stack_buf), fmt, aq);
va_end(aq);
if (len < 0)
/* !!! FIXME: why not just "char message[SDL_MAX_LOG_MESSAGE];" ? */
message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
if (!message) {
return;
/* If message truncated, allocate and re-render */
if (len >= sizeof(stack_buf) && SDL_size_add_overflow(len, 1, &len_plus_term) == 0) {
/* Allocate exactly what we need, including the zero-terminator */
message = (char *)SDL_malloc(len_plus_term);
if (!message)
return;
va_copy(aq, ap);
len = SDL_vsnprintf(message, len_plus_term, fmt, aq);
va_end(aq);
} else {
message = stack_buf;
}
SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap);
/* Chop off final endline. */
len = SDL_strlen(message);
if ((len > 0) && (message[len-1] == '\n')) {
message[--len] = '\0';
if ((len > 0) && (message[len-1] == '\r')) { /* catch "\r\n", too. */
@@ -346,20 +299,8 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list
}
}
if (log_function_mutex) {
SDL_LockMutex(log_function_mutex);
}
SDL_log_function(SDL_log_userdata, category, priority, message);
if (log_function_mutex) {
SDL_UnlockMutex(log_function_mutex);
}
/* Free only if dynamically allocated */
if (message != stack_buf) {
SDL_free(message);
}
SDL_stack_free(message);
}
#if defined(__WIN32__) && !defined(HAVE_STDIO_H) && !defined(__WINRT__)
@@ -462,12 +403,19 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
#elif defined(__APPLE__) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT))
/* Technically we don't need Cocoa/UIKit, but that's where this function is defined for now.
*/
extern void SDL_NSLog(const char *prefix, const char *text);
extern void SDL_NSLog(const char *text);
{
SDL_NSLog(SDL_priority_prefixes[priority], message);
return;
char *text;
/* !!! FIXME: why not just "char text[SDL_MAX_LOG_MESSAGE];" ? */
text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
if (text) {
SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message);
SDL_NSLog(text);
SDL_stack_free(text);
return;
}
}
#elif defined(__PSP__) || defined(__PS2__)
#elif defined(__PSP__)
{
FILE* pFile;
pFile = fopen ("SDL_Log.txt", "a");

View File

@@ -40,10 +40,6 @@
#include <xmmintrin.h>
#endif
#if defined(PS2)
#include <kernel.h>
#endif
#if defined(__WATCOMC__) && defined(__386__)
SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock));
extern __inline int _SDL_xchg_watcom(volatile int *a, int v);
@@ -135,19 +131,7 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
#elif defined(__SOLARIS__) && !defined(_LP64)
/* Used for Solaris with non-gcc compilers. */
return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)lock, 0, 1) == 0);
#elif defined(PS2)
uint32_t oldintr;
SDL_bool res = SDL_FALSE;
// disable interuption
oldintr = DIntr();
if (*lock == 0) {
*lock = 1;
res = SDL_TRUE;
}
// enable interuption
if(oldintr) { EIntr(); }
return res;
#else
#error Please implement for your platform.
return SDL_FALSE;

View File

@@ -245,6 +245,11 @@ SDL_AudioThreadDeinit_Default(_THIS)
{ /* no-op. */
}
static void
SDL_AudioBeginLoopIteration_Default(_THIS)
{ /* no-op. */
}
static void
SDL_AudioWaitDevice_Default(_THIS)
{ /* no-op. */
@@ -272,6 +277,11 @@ SDL_AudioFlushCapture_Default(_THIS)
{ /* no-op. */
}
static void
SDL_AudioPrepareToClose_Default(_THIS)
{ /* no-op. */
}
static void
SDL_AudioCloseDevice_Default(_THIS)
{ /* no-op. */
@@ -289,7 +299,7 @@ SDL_AudioFreeDeviceHandle_Default(void *handle)
static int
SDL_AudioOpenDevice_Default(_THIS, const char *devname)
SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
{
return SDL_Unsupported();
}
@@ -324,6 +334,11 @@ SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
}
}
static void
SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)
{
}
static void
finish_audio_entry_points_init(void)
{
@@ -332,6 +347,14 @@ finish_audio_entry_points_init(void)
* blindly call them without having to check for validity first.
*/
if (current_audio.impl.SkipMixerLock) {
if (current_audio.impl.LockDevice == NULL) {
current_audio.impl.LockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
}
if (current_audio.impl.UnlockDevice == NULL) {
current_audio.impl.UnlockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
}
}
#define FILL_STUB(x) \
if (current_audio.impl.x == NULL) { \
@@ -341,11 +364,13 @@ finish_audio_entry_points_init(void)
FILL_STUB(OpenDevice);
FILL_STUB(ThreadInit);
FILL_STUB(ThreadDeinit);
FILL_STUB(BeginLoopIteration);
FILL_STUB(WaitDevice);
FILL_STUB(PlayDevice);
FILL_STUB(GetDeviceBuf);
FILL_STUB(CaptureFromDevice);
FILL_STUB(FlushCapture);
FILL_STUB(PrepareToClose);
FILL_STUB(CloseDevice);
FILL_STUB(LockDevice);
FILL_STUB(UnlockDevice);
@@ -404,7 +429,8 @@ add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioD
SDL_UnlockMutex(current_audio.detectionLock);
SDL_free(item->original_name);
SDL_free(item);
return SDL_OutOfMemory();
SDL_OutOfMemory();
return -1;
}
SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1);
@@ -457,7 +483,7 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
/* The audio backends call this when a new device is plugged in. */
void
SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle)
SDL_AddAudioDevice(const int iscapture, const char *name, SDL_AudioSpec *spec, void *handle)
{
const int device_index = iscapture ? add_capture_device(name, spec, handle) : add_output_device(name, spec, handle);
if (device_index != -1) {
@@ -519,7 +545,7 @@ mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *remove
/* The audio backends call this when a device is removed from the system. */
void
SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle)
SDL_RemoveAudioDevice(const int iscapture, void *handle)
{
int device_index;
SDL_AudioDevice *device = NULL;
@@ -697,6 +723,7 @@ SDL_RunAudio(void *devicep)
/* Loop, filling the audio buffers */
while (!SDL_AtomicGet(&device->shutdown)) {
current_audio.impl.BeginLoopIteration(device);
data_len = device->callbackspec.size;
/* Fill the current buffer with sound */
@@ -759,6 +786,8 @@ SDL_RunAudio(void *devicep)
}
}
current_audio.impl.PrepareToClose(device);
/* Wait for the audio to drain. */
SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
@@ -802,6 +831,8 @@ SDL_CaptureAudio(void *devicep)
int still_need;
Uint8 *ptr;
current_audio.impl.BeginLoopIteration(device);
if (SDL_AtomicGet(&device->paused)) {
SDL_Delay(delay); /* just so we don't cook the CPU. */
if (device->stream) {
@@ -925,18 +956,20 @@ SDL_GetAudioDriver(int index)
int
SDL_AudioInit(const char *driver_name)
{
int i;
SDL_bool initialized = SDL_FALSE, tried_to_init = SDL_FALSE;
int i = 0;
int initialized = 0;
int tried_to_init = 0;
if (SDL_GetCurrentAudioDriver()) {
SDL_AudioQuit(); /* shutdown driver if already running. */
}
SDL_zero(current_audio);
SDL_zeroa(open_devices);
/* Select the proper audio driver */
if (driver_name == NULL) {
driver_name = SDL_GetHint(SDL_HINT_AUDIODRIVER);
driver_name = SDL_getenv("SDL_AUDIODRIVER");
}
if (driver_name != NULL && *driver_name != 0) {
@@ -957,7 +990,7 @@ SDL_AudioInit(const char *driver_name)
for (i = 0; bootstrap[i]; ++i) {
if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) &&
(SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) {
tried_to_init = SDL_TRUE;
tried_to_init = 1;
SDL_zero(current_audio);
current_audio.name = bootstrap[i]->name;
current_audio.desc = bootstrap[i]->desc;
@@ -974,7 +1007,7 @@ SDL_AudioInit(const char *driver_name)
continue;
}
tried_to_init = SDL_TRUE;
tried_to_init = 1;
SDL_zero(current_audio);
current_audio.name = bootstrap[i]->name;
current_audio.desc = bootstrap[i]->desc;
@@ -1081,29 +1114,38 @@ SDL_GetNumAudioDevices(int iscapture)
const char *
SDL_GetAudioDeviceName(int index, int iscapture)
{
SDL_AudioDeviceItem *item;
int i;
const char *retval;
const char *retval = NULL;
if (!SDL_GetCurrentAudioDriver()) {
SDL_SetError("Audio subsystem is not initialized");
return NULL;
}
SDL_LockMutex(current_audio.detectionLock);
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
if (index >= 0 && index < i) {
for (i--; i > index; i--, item = item->next) {
SDL_assert(item != NULL);
}
SDL_assert(item != NULL);
retval = item->name;
} else {
SDL_InvalidParamError("index");
retval = NULL;
if (iscapture && !current_audio.impl.HasCaptureSupport) {
SDL_SetError("No capture support");
return NULL;
}
if (index >= 0) {
SDL_AudioDeviceItem *item;
int i;
SDL_LockMutex(current_audio.detectionLock);
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
if (index < i) {
for (i--; i > index; i--, item = item->next) {
SDL_assert(item != NULL);
}
SDL_assert(item != NULL);
retval = item->name;
}
SDL_UnlockMutex(current_audio.detectionLock);
}
if (retval == NULL) {
SDL_SetError("No such device");
}
SDL_UnlockMutex(current_audio.detectionLock);
return retval;
}
@@ -1112,33 +1154,38 @@ SDL_GetAudioDeviceName(int index, int iscapture)
int
SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec)
{
SDL_AudioDeviceItem *item;
int i, retval;
if (spec == NULL) {
return SDL_InvalidParamError("spec");
}
SDL_zerop(spec);
if (!SDL_GetCurrentAudioDriver()) {
return SDL_SetError("Audio subsystem is not initialized");
}
SDL_LockMutex(current_audio.detectionLock);
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
if (index >= 0 && index < i) {
for (i--; i > index; i--, item = item->next) {
SDL_assert(item != NULL);
}
SDL_assert(item != NULL);
SDL_memcpy(spec, &item->spec, sizeof(SDL_AudioSpec));
retval = 0;
} else {
retval = SDL_InvalidParamError("index");
if (iscapture && !current_audio.impl.HasCaptureSupport) {
return SDL_SetError("No capture support");
}
SDL_UnlockMutex(current_audio.detectionLock);
return retval;
if (index >= 0) {
SDL_AudioDeviceItem *item;
int i;
SDL_LockMutex(current_audio.detectionLock);
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
if (index < i) {
for (i--; i > index; i--, item = item->next) {
SDL_assert(item != NULL);
}
SDL_assert(item != NULL);
SDL_memcpy(spec, &item->spec, sizeof(SDL_AudioSpec));
}
SDL_UnlockMutex(current_audio.detectionLock);
}
return 0;
}
@@ -1374,7 +1421,7 @@ open_audio_device(const char *devname, int iscapture,
SDL_AtomicSet(&device->enabled, 1);
/* Create a mutex for locking the sound buffers */
if (current_audio.impl.LockDevice == SDL_AudioLockDevice_Default) {
if (!current_audio.impl.SkipMixerLock) {
device->mixer_lock = SDL_CreateMutex();
if (device->mixer_lock == NULL) {
close_audio_device(device);
@@ -1383,7 +1430,7 @@ open_audio_device(const char *devname, int iscapture,
}
}
if (current_audio.impl.OpenDevice(device, devname) < 0) {
if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) {
close_audio_device(device);
return 0;
}
@@ -1508,7 +1555,8 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
/* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
if (open_devices[0] != NULL) {
return SDL_SetError("Audio device is already opened");
SDL_SetError("Audio device is already opened");
return -1;
}
if (obtained) {
@@ -1649,6 +1697,8 @@ SDL_AudioQuit(void)
#ifdef HAVE_LIBSAMPLERATE_H
UnloadLibSampleRate();
#endif
SDL_FreeResampleFilter();
}
#define NUM_FORMATS 10

View File

@@ -70,6 +70,11 @@ extern SDL_AudioFilter SDL_Convert_F32_to_S16;
extern SDL_AudioFilter SDL_Convert_F32_to_U16;
extern SDL_AudioFilter SDL_Convert_F32_to_S32;
/* You need to call SDL_PrepareResampleFilter() before using the internal resampler.
SDL_AudioQuit() calls SDL_FreeResamplerFilter(), you should never call it yourself. */
extern int SDL_PrepareResampleFilter(void);
extern void SDL_FreeResampleFilter(void);
#endif /* SDL_audio_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -80,7 +80,7 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
Just use unaligned load/stores, if the memory at runtime is
aligned it'll be just as fast on modern processors */
while (i >= 4) { /* 4 * float32 */
_mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_loadu_ps(src), _mm_loadu_ps(src+4)), divby2));
_mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_loadu_ps(src+4)), divby2));
i -= 4; src += 8; dst += 4;
}
@@ -369,11 +369,11 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
const float surround_left_distributed = src[6] * 0.5f;
const float surround_right_distributed = src[7] * 0.5f;
dst[0] = (src[0] + surround_left_distributed) * two_thirds; /* FL */
dst[1] = (src[1] + surround_right_distributed) * two_thirds; /* FR */
dst[1] = (src[1] + surround_right_distributed) * two_thirds; /* FR */
dst[2] = src[2] * two_thirds; /* CC */
dst[3] = src[3] * two_thirds; /* LFE */
dst[4] = (src[4] + surround_left_distributed) * two_thirds; /* BL */
dst[5] = (src[5] + surround_right_distributed) * two_thirds; /* BR */
dst[5] = (src[5] + surround_right_distributed) * two_thirds; /* BR */
}
cvt->len_cvt /= 8;
@@ -398,12 +398,12 @@ SDL_Convert71To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8, dst += 7) {
dst[0] = src[3]; /* LFE */
dst[1] = src[2]; /* FC */
dst[1] = src[2]; /* FC */
dst[2] = src[1]; /* FR */
dst[3] = src[7]; /* SR */
dst[4] = (src[4] + src[5]) / 0.2f; /* BackSurround */
dst[5] = src[6]; /* SL */
dst[6] = src[0]; /* FL */
dst[6] = src[0]; /* FL */
}
cvt->len_cvt /= 8;
@@ -428,13 +428,13 @@ SDL_Convert61To71(SDL_AudioCVT * cvt, SDL_AudioFormat format)
for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7, dst += 8) {
dst[0] = src[6]; /* FL */
dst[1] = src[2]; /* FR */
dst[1] = src[2]; /* FR */
dst[2] = src[1]; /* FC */
dst[3] = src[0]; /* LFE */
dst[4] = src[4]; /* BL */
dst[5] = src[4]; /* BR */
dst[6] = src[5]; /* SL */
dst[7] = src[3]; /* SR */
dst[6] = src[5]; /* SL */
dst[7] = src[3]; /* SR */
}
cvt->len_cvt /= 7;
@@ -459,12 +459,12 @@ SDL_Convert51To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 7) {
dst[0] = src[3]; /* LFE */
dst[1] = src[2]; /* FC */
dst[1] = src[2]; /* FC */
dst[2] = src[1]; /* FR */
dst[3] = src[5]; /* SR */
dst[4] = (src[4] + src[5]) / 0.2f; /* BackSurround */
dst[5] = src[4]; /* SL */
dst[6] = src[0]; /* FL */
dst[6] = src[0]; /* FL */
}
cvt->len_cvt /= 6;
@@ -489,7 +489,7 @@ SDL_Convert61To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7, dst += 6) {
dst[0] = src[6]; /* FL */
dst[1] = src[2]; /* FR */
dst[1] = src[2]; /* FR */
dst[2] = src[1]; /* FC */
dst[3] = src[0]; /* LFE */
dst[4] = src[5]; /* BL */
@@ -614,7 +614,7 @@ SDL_ConvertQuadTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
ce = (lf + rf) * 0.5f;
/* Constant 0.571f is approx 4/7 not to saturate */
dst[0] = 0.571f * (lf + (lf - 0.5f * ce)); /* FL */
dst[1] = 0.571f * (rf + (rf - 0.5f * ce)); /* FR */
dst[1] = 0.571f * (rf + (rf - 0.5f * ce)); /* FR */
dst[2] = ce; /* FC */
dst[3] = 0; /* LFE (only meant for special LFE effects) */
dst[4] = lb; /* BL */
@@ -704,16 +704,105 @@ SDL_Convert51To71(SDL_AudioCVT * cvt, SDL_AudioFormat format)
/* SDL's resampler uses a "bandlimited interpolation" algorithm:
https://ccrma.stanford.edu/~jos/resample/ */
#include "SDL_audio_resampler_filter.h"
#define RESAMPLER_ZERO_CROSSINGS 5
#define RESAMPLER_BITS_PER_SAMPLE 16
#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1))
#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1)
/* This is a "modified" bessel function, so you can't use POSIX j0() */
static double
bessel(const double x)
{
const double xdiv2 = x / 2.0;
double i0 = 1.0f;
double f = 1.0f;
int i = 1;
while (SDL_TRUE) {
const double diff = SDL_pow(xdiv2, i * 2) / SDL_pow(f, 2);
if (diff < 1.0e-21f) {
break;
}
i0 += diff;
i++;
f *= (double) i;
}
return i0;
}
/* build kaiser table with cardinal sine applied to it, and array of differences between elements. */
static void
kaiser_and_sinc(float *table, float *diffs, const int tablelen, const double beta)
{
const int lenm1 = tablelen - 1;
const int lenm1div2 = lenm1 / 2;
int i;
table[0] = 1.0f;
for (i = 1; i < tablelen; i++) {
const double kaiser = bessel(beta * SDL_sqrt(1.0 - SDL_pow(((i - lenm1) / 2.0) / lenm1div2, 2.0))) / bessel(beta);
table[tablelen - i] = (float) kaiser;
}
for (i = 1; i < tablelen; i++) {
const float x = (((float) i) / ((float) RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) * ((float) M_PI);
table[i] *= SDL_sinf(x) / x;
diffs[i - 1] = table[i] - table[i - 1];
}
diffs[lenm1] = 0.0f;
}
static SDL_SpinLock ResampleFilterSpinlock = 0;
static float *ResamplerFilter = NULL;
static float *ResamplerFilterDifference = NULL;
int
SDL_PrepareResampleFilter(void)
{
SDL_AtomicLock(&ResampleFilterSpinlock);
if (!ResamplerFilter) {
/* if dB > 50, beta=(0.1102 * (dB - 8.7)), according to Matlab. */
const double dB = 80.0;
const double beta = 0.1102 * (dB - 8.7);
const size_t alloclen = RESAMPLER_FILTER_SIZE * sizeof (float);
ResamplerFilter = (float *) SDL_malloc(alloclen);
if (!ResamplerFilter) {
SDL_AtomicUnlock(&ResampleFilterSpinlock);
return SDL_OutOfMemory();
}
ResamplerFilterDifference = (float *) SDL_malloc(alloclen);
if (!ResamplerFilterDifference) {
SDL_free(ResamplerFilter);
ResamplerFilter = NULL;
SDL_AtomicUnlock(&ResampleFilterSpinlock);
return SDL_OutOfMemory();
}
kaiser_and_sinc(ResamplerFilter, ResamplerFilterDifference, RESAMPLER_FILTER_SIZE, beta);
}
SDL_AtomicUnlock(&ResampleFilterSpinlock);
return 0;
}
void
SDL_FreeResampleFilter(void)
{
SDL_free(ResamplerFilter);
SDL_free(ResamplerFilterDifference);
ResamplerFilter = NULL;
ResamplerFilterDifference = NULL;
}
static int
ResamplerPadding(const int inrate, const int outrate)
{
if (inrate == outrate) {
return 0;
}
if (inrate > outrate) {
return (int) SDL_ceilf(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate)));
} else if (inrate > outrate) {
return (int) SDL_ceil(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate)));
}
return RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
}
@@ -725,38 +814,33 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate,
const float *inbuf, const int inbuflen,
float *outbuf, const int outbuflen)
{
/* Note that this used to be double, but it looks like we can get by with float in most cases at
almost twice the speed on Intel processors, and orders of magnitude more
on CPUs that need a software fallback for double calculations. */
typedef float ResampleFloatType;
const ResampleFloatType finrate = (ResampleFloatType) inrate;
const ResampleFloatType outtimeincr = ((ResampleFloatType) 1.0f) / ((ResampleFloatType) outrate);
const ResampleFloatType ratio = ((float) outrate) / ((float) inrate);
const double finrate = (double) inrate;
const double outtimeincr = 1.0 / ((float) outrate);
const double ratio = ((float) outrate) / ((float) inrate);
const int paddinglen = ResamplerPadding(inrate, outrate);
const int framelen = chans * (int)sizeof (float);
const int inframes = inbuflen / framelen;
const int wantedoutframes = (int) ((inbuflen / framelen) * ratio); /* outbuflen isn't total to write, it's total available. */
const int maxoutframes = outbuflen / framelen;
const int outframes = SDL_min(wantedoutframes, maxoutframes);
ResampleFloatType outtime = 0.0f;
float *dst = outbuf;
double outtime = 0.0;
int i, j, chan;
for (i = 0; i < outframes; i++) {
const int srcindex = (int) (outtime * inrate);
const ResampleFloatType intime = ((ResampleFloatType) srcindex) / finrate;
const ResampleFloatType innexttime = ((ResampleFloatType) (srcindex + 1)) / finrate;
const ResampleFloatType indeltatime = innexttime - intime;
const ResampleFloatType interpolation1 = (indeltatime == 0.0f) ? 1.0f : (1.0f - ((innexttime - outtime) / indeltatime));
const double intime = ((double) srcindex) / finrate;
const double innexttime = ((double) (srcindex + 1)) / finrate;
const double interpolation1 = 1.0 - ((innexttime - outtime) / (innexttime - intime));
const int filterindex1 = (int) (interpolation1 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING);
const ResampleFloatType interpolation2 = 1.0f - interpolation1;
const double interpolation2 = 1.0 - interpolation1;
const int filterindex2 = (int) (interpolation2 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING);
for (chan = 0; chan < chans; chan++) {
float outsample = 0.0f;
/* do this twice to calculate the sample, once for the "left wing" and then same for the right. */
/* !!! FIXME: do both wings in one loop */
for (j = 0; (filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) {
const int srcframe = srcindex - j;
/* !!! FIXME: we can bubble this conditional out of here by doing a pre loop. */
@@ -764,15 +848,12 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate,
outsample += (float)(insample * (ResamplerFilter[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation1 * ResamplerFilterDifference[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)])));
}
/* Do the right wing! */
for (j = 0; (filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) {
const int jsamples = j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
const int srcframe = srcindex + 1 + j;
/* !!! FIXME: we can bubble this conditional out of here by doing a post loop. */
const float insample = (srcframe >= inframes) ? rpadding[((srcframe - inframes) * chans) + chan] : inbuf[(srcframe * chans) + chan];
outsample += (float)(insample * (ResamplerFilter[filterindex2 + jsamples] + (interpolation2 * ResamplerFilterDifference[filterindex2 + jsamples])));
outsample += (float)(insample * (ResamplerFilter[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation2 * ResamplerFilterDifference[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)])));
}
*(dst++) = outsample;
}
@@ -849,7 +930,9 @@ SDL_AddAudioCVTFilter(SDL_AudioCVT *cvt, const SDL_AudioFilter filter)
if (cvt->filter_index >= SDL_AUDIOCVT_MAX_FILTERS) {
return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS);
}
SDL_assert(filter != NULL);
if (filter == NULL) {
return SDL_SetError("Audio filter pointer is NULL");
}
cvt->filters[cvt->filter_index++] = filter;
cvt->filters[cvt->filter_index] = NULL; /* Moving terminator */
return 0;
@@ -860,7 +943,7 @@ SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat src_fmt)
{
int retval = 0; /* 0 == no conversion necessary. */
if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(src_fmt) > 8) {
if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) {
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
return -1;
}
@@ -937,7 +1020,7 @@ SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat dst_fmt)
retval = 1; /* added a converter. */
}
if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(dst_fmt) > 8) {
if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) {
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
return -1;
}
@@ -1037,6 +1120,10 @@ SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, const int dst_channels,
return SDL_SetError("No conversion available for these rates");
}
if (SDL_PrepareResampleFilter() < 0) {
return -1;
}
/* Update (cvt) with filter details... */
if (SDL_AddAudioCVTFilter(cvt, filter) < 0) {
return -1;
@@ -1130,26 +1217,19 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
if (!SDL_SupportedAudioFormat(src_fmt)) {
return SDL_SetError("Invalid source format");
}
if (!SDL_SupportedAudioFormat(dst_fmt)) {
} else if (!SDL_SupportedAudioFormat(dst_fmt)) {
return SDL_SetError("Invalid destination format");
}
if (!SDL_SupportedChannelCount(src_channels)) {
} else if (!SDL_SupportedChannelCount(src_channels)) {
return SDL_SetError("Invalid source channels");
}
if (!SDL_SupportedChannelCount(dst_channels)) {
} else if (!SDL_SupportedChannelCount(dst_channels)) {
return SDL_SetError("Invalid destination channels");
}
if (src_rate <= 0) {
} else if (src_rate <= 0) {
return SDL_SetError("Source rate is equal to or less than zero");
}
if (dst_rate <= 0) {
} else if (dst_rate <= 0) {
return SDL_SetError("Destination rate is equal to or less than zero");
}
if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
} else if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
return SDL_SetError("Source rate is too high");
}
if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
} else if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
return SDL_SetError("Destination rate is too high");
}
@@ -1193,9 +1273,6 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
/* just a byteswap needed? */
if ((src_fmt & ~SDL_AUDIO_MASK_ENDIAN) == (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN)) {
if (SDL_AUDIO_BITSIZE(dst_fmt) == 8) {
return 0;
}
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
return -1;
}
@@ -1589,7 +1666,6 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format,
retval = (SDL_AudioStream *) SDL_calloc(1, sizeof (SDL_AudioStream));
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
@@ -1657,6 +1733,13 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format,
return NULL;
}
if (SDL_PrepareResampleFilter() < 0) {
SDL_free(retval->resampler_state);
retval->resampler_state = NULL;
SDL_FreeAudioStream(retval);
return NULL;
}
retval->resampler_func = SDL_ResampleAudioStream;
retval->reset_resampler_func = SDL_ResetAudioStreamResampler;
retval->cleanup_resampler_func = SDL_CleanupAudioStreamResampler;
@@ -1824,14 +1907,11 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
if (!stream) {
return SDL_InvalidParamError("stream");
}
if (!buf) {
} else if (!buf) {
return SDL_InvalidParamError("buf");
}
if (len == 0) {
} else if (len == 0) {
return 0; /* nothing to do. */
}
if ((len % stream->src_sample_frame_size) != 0) {
} else if ((len % stream->src_sample_frame_size) != 0) {
return SDL_SetError("Can't add partial sample frames");
}
@@ -1937,14 +2017,11 @@ SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len)
if (!stream) {
return SDL_InvalidParamError("stream");
}
if (!buf) {
} else if (!buf) {
return SDL_InvalidParamError("buf");
}
if (len <= 0) {
} else if (len <= 0) {
return 0; /* nothing to do. */
}
if ((len % stream->dst_sample_frame_size) != 0) {
} else if ((len % stream->dst_sample_frame_size) != 0) {
return SDL_SetError("Can't request partial sample frames");
}
@@ -1990,3 +2067,4 @@ SDL_FreeAudioStream(SDL_AudioStream *stream)
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -29,6 +29,7 @@
/* This table is used to add two sound values together and pin
* the value to avoid overflow. (used with permission from ARDI)
* Changed to use 0xFE instead of 0xFF for better sound quality.
*/
static const Uint8 mix8[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -65,25 +66,24 @@ static const Uint8 mix8[] = {
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE
};
/* The volume ranges from 0 - 128 */
#define ADJUST_VOLUME(s, v) (s = (s*v)/SDL_MIX_MAXVOLUME)
#define ADJUST_VOLUME_U8(s, v) (s = (((s-128)*v)/SDL_MIX_MAXVOLUME)+128)
#define ADJUST_VOLUME_U16(s, v) (s = (((s-32768)*v)/SDL_MIX_MAXVOLUME)+32768)
void
@@ -115,8 +115,8 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
Sint8 *dst8, *src8;
Sint8 src_sample;
int dst_sample;
const int max_audioval = SDL_MAX_SINT8;
const int min_audioval = SDL_MIN_SINT8;
const int max_audioval = ((1 << (8 - 1)) - 1);
const int min_audioval = -(1 << (8 - 1));
src8 = (Sint8 *) src;
dst8 = (Sint8 *) dst;
@@ -125,11 +125,12 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
ADJUST_VOLUME(src_sample, volume);
dst_sample = *dst8 + src_sample;
if (dst_sample > max_audioval) {
dst_sample = max_audioval;
*dst8 = max_audioval;
} else if (dst_sample < min_audioval) {
dst_sample = min_audioval;
*dst8 = min_audioval;
} else {
*dst8 = dst_sample;
}
*dst8 = dst_sample;
++dst8;
++src8;
}
@@ -140,14 +141,14 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
{
Sint16 src1, src2;
int dst_sample;
const int max_audioval = SDL_MAX_SINT16;
const int min_audioval = SDL_MIN_SINT16;
const int max_audioval = ((1 << (16 - 1)) - 1);
const int min_audioval = -(1 << (16 - 1));
len /= 2;
while (len--) {
src1 = SDL_SwapLE16(*(Sint16 *)src);
src1 = ((src[1]) << 8 | src[0]);
ADJUST_VOLUME(src1, volume);
src2 = SDL_SwapLE16(*(Sint16 *)dst);
src2 = ((dst[1]) << 8 | dst[0]);
src += 2;
dst_sample = src1 + src2;
if (dst_sample > max_audioval) {
@@ -155,7 +156,9 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
} else if (dst_sample < min_audioval) {
dst_sample = min_audioval;
}
*(Sint16 *)dst = SDL_SwapLE16(dst_sample);
dst[0] = dst_sample & 0xFF;
dst_sample >>= 8;
dst[1] = dst_sample & 0xFF;
dst += 2;
}
}
@@ -165,14 +168,14 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
{
Sint16 src1, src2;
int dst_sample;
const int max_audioval = SDL_MAX_SINT16;
const int min_audioval = SDL_MIN_SINT16;
const int max_audioval = ((1 << (16 - 1)) - 1);
const int min_audioval = -(1 << (16 - 1));
len /= 2;
while (len--) {
src1 = SDL_SwapBE16(*(Sint16 *)src);
src1 = ((src[0]) << 8 | src[1]);
ADJUST_VOLUME(src1, volume);
src2 = SDL_SwapBE16(*(Sint16 *)dst);
src2 = ((dst[0]) << 8 | dst[1]);
src += 2;
dst_sample = src1 + src2;
if (dst_sample > max_audioval) {
@@ -180,7 +183,9 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
} else if (dst_sample < min_audioval) {
dst_sample = min_audioval;
}
*(Sint16 *)dst = SDL_SwapBE16(dst_sample);
dst[1] = dst_sample & 0xFF;
dst_sample >>= 8;
dst[0] = dst_sample & 0xFF;
dst += 2;
}
}
@@ -190,23 +195,21 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
{
Uint16 src1, src2;
int dst_sample;
const int max_audioval = SDL_MAX_SINT16;
const int min_audioval = SDL_MIN_SINT16;
const int max_audioval = 0xFFFF;
len /= 2;
while (len--) {
src1 = SDL_SwapLE16(*(Uint16 *)src);
ADJUST_VOLUME_U16(src1, volume);
src2 = SDL_SwapLE16(*(Uint16 *)dst);
src1 = ((src[1]) << 8 | src[0]);
ADJUST_VOLUME(src1, volume);
src2 = ((dst[1]) << 8 | dst[0]);
src += 2;
dst_sample = src1 + src2 - 32768 * 2;
dst_sample = src1 + src2;
if (dst_sample > max_audioval) {
dst_sample = max_audioval;
} else if (dst_sample < min_audioval) {
dst_sample = min_audioval;
}
dst_sample += 32768;
*(Uint16 *)dst = SDL_SwapLE16(dst_sample);
dst[0] = dst_sample & 0xFF;
dst_sample >>= 8;
dst[1] = dst_sample & 0xFF;
dst += 2;
}
}
@@ -216,23 +219,21 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
{
Uint16 src1, src2;
int dst_sample;
const int max_audioval = SDL_MAX_SINT16;
const int min_audioval = SDL_MIN_SINT16;
const int max_audioval = 0xFFFF;
len /= 2;
while (len--) {
src1 = SDL_SwapBE16(*(Uint16 *)src);
ADJUST_VOLUME_U16(src1, volume);
src2 = SDL_SwapBE16(*(Uint16 *)dst);
src1 = ((src[0]) << 8 | src[1]);
ADJUST_VOLUME(src1, volume);
src2 = ((dst[0]) << 8 | dst[1]);
src += 2;
dst_sample = src1 + src2 - 32768 * 2;
dst_sample = src1 + src2;
if (dst_sample > max_audioval) {
dst_sample = max_audioval;
} else if (dst_sample < min_audioval) {
dst_sample = min_audioval;
}
dst_sample += 32768;
*(Uint16 *)dst = SDL_SwapBE16(dst_sample);
dst[1] = dst_sample & 0xFF;
dst_sample >>= 8;
dst[0] = dst_sample & 0xFF;
dst += 2;
}
}
@@ -244,8 +245,8 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
Uint32 *dst32 = (Uint32 *) dst;
Sint64 src1, src2;
Sint64 dst_sample;
const Sint64 max_audioval = SDL_MAX_SINT32;
const Sint64 min_audioval = SDL_MIN_SINT32;
const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
len /= 4;
while (len--) {
@@ -270,8 +271,8 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
Uint32 *dst32 = (Uint32 *) dst;
Sint64 src1, src2;
Sint64 dst_sample;
const Sint64 max_audioval = SDL_MAX_SINT32;
const Sint64 min_audioval = SDL_MIN_SINT32;
const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));
len /= 4;
while (len--) {

View File

@@ -39,11 +39,11 @@ typedef struct SDL_AudioDevice SDL_AudioDevice;
/* Audio targets should call this as devices are added to the system (such as
a USB headset being plugged in), and should also be called for
for every device found during DetectDevices(). */
extern void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle);
extern void SDL_AddAudioDevice(const int iscapture, const char *name, SDL_AudioSpec *spec, void *handle);
/* Audio targets should call this as devices are removed, so SDL can update
its list of available devices. */
extern void SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle);
extern void SDL_RemoveAudioDevice(const int iscapture, void *handle);
/* Audio targets should call this if an opened audio device is lost while
being used. This can happen due to i/o errors, or a device being unplugged,
@@ -65,14 +65,16 @@ extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device);
typedef struct SDL_AudioDriverImpl
{
void (*DetectDevices) (void);
int (*OpenDevice) (_THIS, const char *devname);
int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture);
void (*ThreadInit) (_THIS); /* Called by audio thread at start */
void (*ThreadDeinit) (_THIS); /* Called by audio thread at end */
void (*BeginLoopIteration)(_THIS); /* Called by audio thread at top of loop */
void (*WaitDevice) (_THIS);
void (*PlayDevice) (_THIS);
Uint8 *(*GetDeviceBuf) (_THIS);
int (*CaptureFromDevice) (_THIS, void *buffer, int buflen);
void (*FlushCapture) (_THIS);
void (*PrepareToClose) (_THIS); /**< Called between run and draining wait for playback devices */
void (*CloseDevice) (_THIS);
void (*LockDevice) (_THIS);
void (*UnlockDevice) (_THIS);
@@ -82,11 +84,13 @@ typedef struct SDL_AudioDriverImpl
/* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */
/* Some flags to push duplicate code into the core and reduce #ifdefs. */
SDL_bool ProvidesOwnCallbackThread;
SDL_bool HasCaptureSupport;
SDL_bool OnlyHasDefaultOutputDevice;
SDL_bool OnlyHasDefaultCaptureDevice;
SDL_bool AllowsArbitraryDeviceNames;
/* !!! FIXME: these should be SDL_bool */
int ProvidesOwnCallbackThread;
int SkipMixerLock;
int HasCaptureSupport;
int OnlyHasDefaultOutputDevice;
int OnlyHasDefaultCaptureDevice;
int AllowsArbitraryDeviceNames;
} SDL_AudioDriverImpl;
@@ -174,8 +178,8 @@ typedef struct AudioBootStrap
{
const char *name;
const char *desc;
SDL_bool (*init) (SDL_AudioDriverImpl * impl);
SDL_bool demand_only; /* 1==request explicitly, or it won't be available. */
int (*init) (SDL_AudioDriverImpl * impl);
int demand_only; /* 1==request explicitly, or it won't be available. */
} AudioBootStrap;
/* Not all of these are available in a given build. Use #ifdefs, etc. */

View File

@@ -685,7 +685,7 @@ MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
state.output.pos = 0;
state.output.size = outputsize / sizeof(Sint16);
state.output.data = (Sint16 *)SDL_calloc(1, outputsize);
state.output.data = (Sint16 *)SDL_malloc(outputsize);
if (state.output.data == NULL) {
return SDL_OutOfMemory();
}

View File

@@ -71,10 +71,9 @@ void aaudio_errorCallback( AAudioStream *stream, void *userData, aaudio_result_t
#define LIB_AAUDIO_SO "libaaudio.so"
static int
aaudio_OpenDevice(_THIS, const char *devname)
aaudio_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
struct SDL_PrivateAudioData *private;
SDL_bool iscapture = this->iscapture;
aaudio_result_t res;
LOGI(__func__);
@@ -269,7 +268,7 @@ aaudio_Deinitialize(void)
LOGI("End AAUDIO %s", SDL_GetError());
}
static SDL_bool
static int
aaudio_Init(SDL_AudioDriverImpl *impl)
{
aaudio_result_t res;
@@ -281,7 +280,7 @@ aaudio_Init(SDL_AudioDriverImpl *impl)
* See https://github.com/google/oboe/issues/40 for more information.
*/
if (SDL_GetAndroidSDKVersion() < 27) {
return SDL_FALSE;
return 0;
}
SDL_zero(ctx);
@@ -316,12 +315,12 @@ aaudio_Init(SDL_AudioDriverImpl *impl)
/* and the capabilities */
impl->HasCaptureSupport = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultCaptureDevice = 1;
/* this audio target is available. */
LOGI("SDL aaudio_Init OK");
return SDL_TRUE;
return 1;
failure:
if (ctx.handle) {
@@ -332,11 +331,11 @@ failure:
}
ctx.handle = NULL;
ctx.builder = NULL;
return SDL_FALSE;
return 0;
}
AudioBootStrap aaudio_bootstrap = {
"AAudio", "AAudio audio driver", aaudio_Init, SDL_FALSE
"AAudio", "AAudio audio driver", aaudio_Init, 0
};
/* Pause (block) all non already paused audio devices by taking their mixer lock */

View File

@@ -543,10 +543,9 @@ ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params)
}
static int
ALSA_OpenDevice(_THIS, const char *devname)
ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
int status = 0;
SDL_bool iscapture = this->iscapture;
snd_pcm_t *pcm_handle = NULL;
snd_pcm_hw_params_t *hwparams = NULL;
snd_pcm_sw_params_t *swparams = NULL;
@@ -570,7 +569,7 @@ ALSA_OpenDevice(_THIS, const char *devname)
/* Open the audio device */
/* Name of device should depend on # channels in spec */
status = ALSA_snd_pcm_open(&pcm_handle,
get_audio_device(this->handle, this->spec.channels),
get_audio_device(handle, this->spec.channels),
iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
SND_PCM_NONBLOCK);
@@ -598,7 +597,10 @@ ALSA_OpenDevice(_THIS, const char *devname)
}
/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
status = -1;
for (test_format = SDL_FirstAudioFormat(this->spec.format);
test_format && (status < 0);) {
status = 0; /* if we can't support a format, it'll become -1. */
switch (test_format) {
case AUDIO_U8:
format = SND_PCM_FORMAT_U8;
@@ -631,14 +633,19 @@ ALSA_OpenDevice(_THIS, const char *devname)
format = SND_PCM_FORMAT_FLOAT_BE;
break;
default:
continue;
}
if (ALSA_snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) >= 0) {
status = -1;
break;
}
if (status >= 0) {
status = ALSA_snd_pcm_hw_params_set_format(pcm_handle,
hwparams, format);
}
if (status < 0) {
test_format = SDL_NextAudioFormat();
}
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "alsa");
if (status < 0) {
return SDL_SetError("ALSA: Couldn't find any hardware audio formats");
}
this->spec.format = test_format;
@@ -990,11 +997,11 @@ ALSA_Deinitialize(void)
UnloadALSALibrary();
}
static SDL_bool
static int
ALSA_Init(SDL_AudioDriverImpl * impl)
{
if (LoadALSALibrary() < 0) {
return SDL_FALSE;
return 0;
}
/* Set the function pointers */
@@ -1010,12 +1017,12 @@ ALSA_Init(SDL_AudioDriverImpl * impl)
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap ALSA_bootstrap = {
"alsa", "ALSA PCM audio", ALSA_Init, SDL_FALSE
"alsa", "ALSA PCM audio", ALSA_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_ALSA */

View File

@@ -36,10 +36,9 @@ static SDL_AudioDevice* audioDevice = NULL;
static SDL_AudioDevice* captureDevice = NULL;
static int
ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
SDL_AudioFormat test_format;
SDL_bool iscapture = this->iscapture;
SDL_assert((captureDevice == NULL) || !iscapture);
SDL_assert((audioDevice == NULL) || iscapture);
@@ -55,18 +54,20 @@ ANDROIDAUDIO_OpenDevice(_THIS, const char *devname)
return SDL_OutOfMemory();
}
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
test_format = SDL_FirstAudioFormat(this->spec.format);
while (test_format != 0) { /* no "UNKNOWN" constant */
if ((test_format == AUDIO_U8) ||
(test_format == AUDIO_S16) ||
(test_format == AUDIO_F32)) {
this->spec.format = test_format;
break;
}
test_format = SDL_NextAudioFormat();
}
if (!test_format) {
if (test_format == 0) {
/* Didn't find a compatible format :( */
return SDL_SetError("%s: Unsupported audio format", "android");
return SDL_SetError("No compatible audio format!");
}
if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) {
@@ -119,7 +120,7 @@ ANDROIDAUDIO_CloseDevice(_THIS)
SDL_free(this->hidden);
}
static SDL_bool
static int
ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -132,14 +133,14 @@ ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
/* and the capabilities */
impl->HasCaptureSupport = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultCaptureDevice = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap ANDROIDAUDIO_bootstrap = {
"android", "SDL Android audio driver", ANDROIDAUDIO_Init, SDL_FALSE
"android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0
};
/* Pause (block) all non already paused audio devices by taking their mixer lock */

View File

@@ -216,11 +216,11 @@ ARTS_Suspend(void)
}
static int
ARTS_OpenDevice(_THIS, const char *devname)
ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
int rc = 0;
int bits, frag_spec = 0;
SDL_AudioFormat test_format = 0;
int bits = 0, frag_spec = 0;
SDL_AudioFormat test_format = 0, format = 0;
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
@@ -231,24 +231,32 @@ ARTS_OpenDevice(_THIS, const char *devname)
SDL_zerop(this->hidden);
/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
for (test_format = SDL_FirstAudioFormat(this->spec.format);
!format && test_format;) {
#ifdef DEBUG_AUDIO
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
#endif
switch (test_format) {
case AUDIO_U8:
bits = 8;
format = 1;
break;
case AUDIO_S16LSB:
bits = 16;
format = 1;
break;
default:
continue;
format = 0;
break;
}
if (!format) {
test_format = SDL_NextAudioFormat();
}
break;
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "arts");
if (format == 0) {
return SDL_SetError("Couldn't find any hardware audio formats");
}
this->spec.format = test_format;
bits = SDL_AUDIO_BITSIZE(test_format);
if ((rc = SDL_NAME(arts_init) ()) != 0) {
return SDL_SetError("Unable to initialize ARTS: %s",
@@ -312,16 +320,16 @@ ARTS_Deinitialize(void)
}
static SDL_bool
static int
ARTS_Init(SDL_AudioDriverImpl * impl)
{
if (LoadARTSLibrary() < 0) {
return SDL_FALSE;
return 0;
} else {
if (SDL_NAME(arts_init) () != 0) {
UnloadARTSLibrary();
SDL_SetError("ARTS: arts_init failed (no audio server?)");
return SDL_FALSE;
return 0;
}
/* Play a stream so aRts doesn't crash */
@@ -342,14 +350,14 @@ ARTS_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = ARTS_GetDeviceBuf;
impl->CloseDevice = ARTS_CloseDevice;
impl->Deinitialize = ARTS_Deinitialize;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap ARTS_bootstrap = {
"arts", "Analog RealTime Synthesizer", ARTS_Init, SDL_FALSE
"arts", "Analog RealTime Synthesizer", ARTS_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_ARTS */

View File

@@ -522,12 +522,8 @@ static void
outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
{
SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData;
SDL_LockMutex(this->mixer_lock);
if (SDL_AtomicGet(&this->hidden->shutdown)) {
SDL_UnlockMutex(this->mixer_lock);
return; /* don't do anything, since we don't even want to enqueue this buffer again. */
return; /* don't do anything. */
}
if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
@@ -540,8 +536,10 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
while (remaining > 0) {
if (SDL_AudioStreamAvailable(this->stream) == 0) {
/* Generate the data */
SDL_LockMutex(this->mixer_lock);
(*this->callbackspec.callback)(this->callbackspec.userdata,
this->hidden->buffer, this->hidden->bufferSize);
SDL_UnlockMutex(this->mixer_lock);
this->hidden->bufferOffset = 0;
SDL_AudioStreamPut(this->stream, this->hidden->buffer, this->hidden->bufferSize);
}
@@ -567,8 +565,10 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
UInt32 len;
if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
/* Generate the data */
SDL_LockMutex(this->mixer_lock);
(*this->callbackspec.callback)(this->callbackspec.userdata,
this->hidden->buffer, this->hidden->bufferSize);
SDL_UnlockMutex(this->mixer_lock);
this->hidden->bufferOffset = 0;
}
@@ -587,8 +587,6 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL);
inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
SDL_UnlockMutex(this->mixer_lock);
}
static void
@@ -743,10 +741,8 @@ COREAUDIO_CloseDevice(_THIS)
#if MACOSX_COREAUDIO
static int
prepare_device(_THIS)
prepare_device(_THIS, void *handle, int iscapture)
{
void *handle = this->handle;
SDL_bool iscapture = this->iscapture;
AudioDeviceID devid = (AudioDeviceID) ((size_t) handle);
OSStatus result = noErr;
UInt32 size = 0;
@@ -987,7 +983,7 @@ audioqueue_thread(void *arg)
and quits (flagging the audioqueue for shutdown), or toggles to some other system
output device (in which case we'll try again). */
const AudioDeviceID prev_devid = this->hidden->deviceID;
if (prepare_device(this) && (prev_devid != this->hidden->deviceID)) {
if (prepare_device(this, this->handle, this->iscapture) && (prev_devid != this->hidden->deviceID)) {
AudioQueueStop(this->hidden->audioQueue, 1);
if (assign_device_to_audioqueue(this)) {
int i;
@@ -1019,11 +1015,11 @@ audioqueue_thread(void *arg)
}
static int
COREAUDIO_OpenDevice(_THIS, const char *devname)
COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
AudioStreamBasicDescription *strdesc;
SDL_AudioFormat test_format;
SDL_bool iscapture = this->iscapture;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
int valid_datatype = 0;
SDL_AudioDevice **new_open_devices;
/* Initialize all variables that we clean on shutdown */
@@ -1080,7 +1076,8 @@ COREAUDIO_OpenDevice(_THIS, const char *devname)
strdesc->mSampleRate = this->spec.freq;
strdesc->mFramesPerPacket = 1;
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
while ((!valid_datatype) && (test_format)) {
this->spec.format = test_format;
/* CoreAudio handles most of SDL's formats natively, but not U16, apparently. */
switch (test_format) {
case AUDIO_U8:
@@ -1091,32 +1088,32 @@ COREAUDIO_OpenDevice(_THIS, const char *devname)
case AUDIO_S32MSB:
case AUDIO_F32LSB:
case AUDIO_F32MSB:
valid_datatype = 1;
strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(this->spec.format);
if (SDL_AUDIO_ISBIGENDIAN(this->spec.format))
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
if (SDL_AUDIO_ISFLOAT(this->spec.format))
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
else if (SDL_AUDIO_ISSIGNED(this->spec.format))
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
break;
default:
continue;
test_format = SDL_NextAudioFormat();
break;
}
break;
}
if (!test_format) { /* shouldn't happen, but just in case... */
return SDL_SetError("%s: Unsupported audio format", "coreaudio");
if (!valid_datatype) { /* shouldn't happen, but just in case... */
return SDL_SetError("Unsupported audio format");
}
this->spec.format = test_format;
strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(test_format);
if (SDL_AUDIO_ISBIGENDIAN(test_format))
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
if (SDL_AUDIO_ISFLOAT(test_format))
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
else if (SDL_AUDIO_ISSIGNED(test_format))
strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
strdesc->mBytesPerFrame = strdesc->mChannelsPerFrame * strdesc->mBitsPerChannel / 8;
strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket;
#if MACOSX_COREAUDIO
if (!prepare_device(this)) {
if (!prepare_device(this, handle, iscapture)) {
return -1;
}
#endif
@@ -1138,7 +1135,8 @@ COREAUDIO_OpenDevice(_THIS, const char *devname)
this->hidden->ready_semaphore = NULL;
if ((this->hidden->thread != NULL) && (this->hidden->thread_error != NULL)) {
return SDL_SetError("%s", this->hidden->thread_error);
SDL_SetError("%s", this->hidden->thread_error);
return -1;
}
return (this->hidden->thread != NULL) ? 0 : -1;
@@ -1154,7 +1152,7 @@ COREAUDIO_Deinitialize(void)
#endif
}
static SDL_bool
static int
COREAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -1166,18 +1164,18 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->DetectDevices = COREAUDIO_DetectDevices;
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
#else
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultCaptureDevice = 1;
#endif
impl->ProvidesOwnCallbackThread = SDL_TRUE;
impl->HasCaptureSupport = SDL_TRUE;
impl->ProvidesOwnCallbackThread = 1;
impl->HasCaptureSupport = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap COREAUDIO_bootstrap = {
"coreaudio", "CoreAudio", COREAUDIO_Init, SDL_FALSE
"coreaudio", "CoreAudio", COREAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_COREAUDIO */

View File

@@ -98,8 +98,10 @@ DSOUND_Load(void)
static int
SetDSerror(const char *function, int code)
{
const char *error;
static const char *error;
static char errbuf[1024];
errbuf[0] = 0;
switch (code) {
case E_NOINTERFACE:
error = "Unsupported interface -- Is DirectX 8.0 or later installed?";
@@ -135,11 +137,15 @@ SetDSerror(const char *function, int code)
error = "Function not supported";
break;
default:
error = "Unknown DirectSound error";
SDL_snprintf(errbuf, SDL_arraysize(errbuf),
"%s: Unknown DirectSound error: 0x%x", function, code);
break;
}
return SDL_SetError("%s: %s (0x%x)", function, error, code);
if (!errbuf[0]) {
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
error);
}
return SDL_SetError("%s", errbuf);
}
static void
@@ -467,14 +473,14 @@ CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
}
static int
DSOUND_OpenDevice(_THIS, const char *devname)
DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
const DWORD numchunks = 8;
HRESULT result;
SDL_bool valid_format = SDL_FALSE;
SDL_bool tried_format = SDL_FALSE;
SDL_bool iscapture = this->iscapture;
SDL_AudioFormat test_format;
LPGUID guid = (LPGUID) this->handle;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
LPGUID guid = (LPGUID) handle;
DWORD bufsize;
/* Initialize all variables that we clean on shutdown */
@@ -504,7 +510,7 @@ DSOUND_OpenDevice(_THIS, const char *devname)
}
}
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
while ((!valid_format) && (test_format)) {
switch (test_format) {
case AUDIO_U8:
case AUDIO_S16:
@@ -541,21 +547,19 @@ DSOUND_OpenDevice(_THIS, const char *devname)
rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt);
if (rc == 0) {
this->hidden->num_buffers = numchunks;
break;
valid_format = SDL_TRUE;
}
}
continue;
default:
continue;
break;
}
break;
test_format = SDL_NextAudioFormat();
}
if (!test_format) {
if (!valid_format) {
if (tried_format) {
return -1; /* CreateSecondary() should have called SDL_SetError(). */
}
return SDL_SetError("%s: Unsupported audio format", "directsound");
return SDL_SetError("DirectSound: Unsupported audio format");
}
/* Playback buffers will auto-start playing in DSOUND_WaitDevice() */
@@ -571,11 +575,11 @@ DSOUND_Deinitialize(void)
}
static SDL_bool
static int
DSOUND_Init(SDL_AudioDriverImpl * impl)
{
if (!DSOUND_Load()) {
return SDL_FALSE;
return 0;
}
/* Set the function pointers */
@@ -592,11 +596,11 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap DSOUND_bootstrap = {
"directsound", "DirectSound", DSOUND_Init, SDL_FALSE
"directsound", "DirectSound", DSOUND_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_DSOUND */

View File

@@ -114,7 +114,7 @@ DISKAUDIO_CloseDevice(_THIS)
static const char *
get_filename(const SDL_bool iscapture, const char *devname)
get_filename(const int iscapture, const char *devname)
{
if (devname == NULL) {
devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE);
@@ -126,11 +126,9 @@ get_filename(const SDL_bool iscapture, const char *devname)
}
static int
DISKAUDIO_OpenDevice(_THIS, const char *devname)
DISKAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
void *handle = _this->handle;
/* handle != NULL means "user specified the placeholder name on the fake detected device list" */
SDL_bool iscapture = _this->iscapture;
const char *fname = get_filename(iscapture, handle ? NULL : devname);
const char *envr = SDL_getenv(DISKENVR_IODELAY);
@@ -179,7 +177,7 @@ DISKAUDIO_DetectDevices(void)
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *) 0x2);
}
static SDL_bool
static int
DISKAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -193,14 +191,14 @@ DISKAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->CloseDevice = DISKAUDIO_CloseDevice;
impl->DetectDevices = DISKAUDIO_DetectDevices;
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
impl->AllowsArbitraryDeviceNames = 1;
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap DISKAUDIO_bootstrap = {
"disk", "direct-to-disk audio", DISKAUDIO_Init, SDL_TRUE
"disk", "direct-to-disk audio", DISKAUDIO_Init, 1
};
#endif /* SDL_AUDIO_DRIVER_DISK */

View File

@@ -68,9 +68,8 @@ DSP_CloseDevice(_THIS)
static int
DSP_OpenDevice(_THIS, const char *devname)
DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
SDL_bool iscapture = this->iscapture;
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
int format;
int value;
@@ -302,14 +301,13 @@ look_for_devices_test(int fd)
return 0;
}
static SDL_bool
static int
DSP_Init(SDL_AudioDriverImpl * impl)
{
InitTimeDevicesExist = SDL_FALSE;
SDL_EnumUnixAudioDevices(0, look_for_devices_test);
if (!InitTimeDevicesExist) {
SDL_SetError("dsp: No such audio device");
return SDL_FALSE; /* maybe try a different backend. */
return 0; /* maybe try a different backend. */
}
/* Set the function pointers */
@@ -321,15 +319,15 @@ DSP_Init(SDL_AudioDriverImpl * impl)
impl->CaptureFromDevice = DSP_CaptureFromDevice;
impl->FlushCapture = DSP_FlushCapture;
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
impl->AllowsArbitraryDeviceNames = 1;
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap DSP_bootstrap = {
"dsp", "OSS /dev/dsp standard audio", DSP_Init, SDL_FALSE
"dsp", "OSS /dev/dsp standard audio", DSP_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_OSS */

View File

@@ -28,7 +28,7 @@
#include "SDL_dummyaudio.h"
static int
DUMMYAUDIO_OpenDevice(_THIS, const char *devname)
DUMMYAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
_this->hidden = (void *) 0x1; /* just something non-NULL */
return 0; /* always succeeds. */
@@ -45,22 +45,22 @@ DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
return buflen;
}
static SDL_bool
static int
DUMMYAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
impl->OpenDevice = DUMMYAUDIO_OpenDevice;
impl->CaptureFromDevice = DUMMYAUDIO_CaptureFromDevice;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultCaptureDevice = 1;
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap DUMMYAUDIO_bootstrap = {
"dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, SDL_TRUE
"dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, 1
};
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -28,16 +28,11 @@
#include <emscripten/emscripten.h>
/* !!! FIXME: this currently expects that the audio callback runs in the main thread,
!!! FIXME: in intervals when the application isn't running, but that may not be
!!! FIXME: true always once pthread support becomes widespread. Revisit this code
!!! FIXME: at some point and see what needs to be done for that! */
static void
FeedAudioDevice(_THIS, const void *buf, const int buflen)
{
const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels;
MAIN_THREAD_EM_ASM({
EM_ASM_ARGS({
var SDL2 = Module['SDL2'];
var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels'];
for (var c = 0; c < numChannels; ++c) {
@@ -106,7 +101,7 @@ HandleCaptureProcess(_THIS)
return;
}
MAIN_THREAD_EM_ASM({
EM_ASM_ARGS({
var SDL2 = Module['SDL2'];
var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
for (var c = 0; c < numChannels; ++c) {
@@ -152,7 +147,7 @@ HandleCaptureProcess(_THIS)
static void
EMSCRIPTENAUDIO_CloseDevice(_THIS)
{
MAIN_THREAD_EM_ASM({
EM_ASM_({
var SDL2 = Module['SDL2'];
if ($0) {
if (SDL2.capture.silenceTimer !== undefined) {
@@ -197,16 +192,16 @@ EMSCRIPTENAUDIO_CloseDevice(_THIS)
}
static int
EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
SDL_bool valid_format = SDL_FALSE;
SDL_AudioFormat test_format;
SDL_bool iscapture = this->iscapture;
int result;
/* based on parts of library_sdl.js */
/* create context */
result = MAIN_THREAD_EM_ASM_INT({
result = EM_ASM_INT({
if(typeof(Module['SDL2']) === 'undefined') {
Module['SDL2'] = {};
}
@@ -233,21 +228,22 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
return SDL_SetError("Web Audio API is not available!");
}
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
test_format = SDL_FirstAudioFormat(this->spec.format);
while ((!valid_format) && (test_format)) {
switch (test_format) {
case AUDIO_F32: /* web audio only supports floats */
this->spec.format = test_format;
valid_format = SDL_TRUE;
break;
default:
continue;
}
break;
test_format = SDL_NextAudioFormat();
}
if (!test_format) {
if (!valid_format) {
/* Didn't find a compatible format :( */
return SDL_SetError("%s: Unsupported audio format", "emscripten");
return SDL_SetError("No compatible audio format!");
}
this->spec.format = test_format;
/* Initialize all variables that we clean on shutdown */
#if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL2 namespace? --ryan. */
@@ -285,7 +281,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
feels like it's a pretty inefficient tapdance in similar ways,
to be honest. */
MAIN_THREAD_EM_ASM({
EM_ASM_({
var SDL2 = Module['SDL2'];
var have_microphone = function(stream) {
//console.log('SDL audio capture: we have a microphone! Replacing silence callback.');
@@ -328,7 +324,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
}, this->spec.channels, this->spec.samples, HandleCaptureProcess, this);
} else {
/* setup a ScriptProcessorNode */
MAIN_THREAD_EM_ASM({
EM_ASM_ARGS({
var SDL2 = Module['SDL2'];
SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
@@ -343,47 +339,43 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
return 0;
}
static void
EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)
{
}
static SDL_bool
static int
EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
{
SDL_bool available, capture_available;
int available;
int capture_available;
/* Set the function pointers */
impl->OpenDevice = EMSCRIPTENAUDIO_OpenDevice;
impl->CloseDevice = EMSCRIPTENAUDIO_CloseDevice;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
/* no threads here */
impl->LockDevice = impl->UnlockDevice = EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock;
impl->ProvidesOwnCallbackThread = SDL_TRUE;
impl->SkipMixerLock = 1;
impl->ProvidesOwnCallbackThread = 1;
/* check availability */
available = MAIN_THREAD_EM_ASM_INT({
available = EM_ASM_INT_V({
if (typeof(AudioContext) !== 'undefined') {
return true;
return 1;
} else if (typeof(webkitAudioContext) !== 'undefined') {
return true;
return 1;
}
return false;
return 0;
});
if (!available) {
SDL_SetError("No audio context available");
}
capture_available = available && MAIN_THREAD_EM_ASM_INT({
capture_available = available && EM_ASM_INT_V({
if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) {
return true;
return 1;
} else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') {
return true;
return 1;
}
return false;
return 0;
});
impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE;
@@ -393,7 +385,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
}
AudioBootStrap EMSCRIPTENAUDIO_bootstrap = {
"emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, SDL_FALSE
"emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */

View File

@@ -208,7 +208,7 @@ get_progname(void)
static int
ESD_OpenDevice(_THIS, const char *devname)
ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
esd_format_t format = (ESD_STREAM | ESD_PLAY);
SDL_AudioFormat test_format = 0;
@@ -293,11 +293,11 @@ ESD_Deinitialize(void)
UnloadESDLibrary();
}
static SDL_bool
static int
ESD_Init(SDL_AudioDriverImpl * impl)
{
if (LoadESDLibrary() < 0) {
return SDL_FALSE;
return 0;
} else {
int connection = 0;
@@ -308,7 +308,7 @@ ESD_Init(SDL_AudioDriverImpl * impl)
if (connection < 0) {
UnloadESDLibrary();
SDL_SetError("ESD: esd_open_sound failed (no audio server?)");
return SDL_FALSE;
return 0;
}
SDL_NAME(esd_close) (connection);
}
@@ -320,14 +320,14 @@ ESD_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = ESD_GetDeviceBuf;
impl->CloseDevice = ESD_CloseDevice;
impl->Deinitialize = ESD_Deinitialize;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap ESD_bootstrap = {
"esd", "Enlightened Sound Daemon", ESD_Init, SDL_FALSE
"esd", "Enlightened Sound Daemon", ESD_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_ESD */

View File

@@ -174,10 +174,10 @@ SDL_FS_CloseDevice(_THIS)
static int
SDL_FS_OpenDevice(_THIS, const char *devname)
SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
int bytes;
SDL_AudioFormat test_format;
SDL_AudioFormat test_format = 0, format = 0;
FSSampleFormat fs_format;
FSStreamDescription desc;
DirectResult ret;
@@ -191,34 +191,45 @@ SDL_FS_OpenDevice(_THIS, const char *devname)
SDL_zerop(this->hidden);
/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
for (test_format = SDL_FirstAudioFormat(this->spec.format);
!format && test_format;) {
#ifdef DEBUG_AUDIO
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
#endif
switch (test_format) {
case AUDIO_U8:
fs_format = FSSF_U8;
bytes = 1;
format = 1;
break;
case AUDIO_S16SYS:
fs_format = FSSF_S16;
bytes = 2;
format = 1;
break;
case AUDIO_S32SYS:
fs_format = FSSF_S32;
bytes = 4;
format = 1;
break;
case AUDIO_F32SYS:
fs_format = FSSF_FLOAT;
bytes = 4;
format = 1;
break;
default:
continue;
format = 0;
break;
}
if (!format) {
test_format = SDL_NextAudioFormat();
}
break;
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "fusionsound");
if (format == 0) {
return SDL_SetError("Couldn't find any hardware audio formats");
}
this->spec.format = test_format;
bytes = SDL_AUDIO_BITSIZE(test_format) / 8;
/* Retrieve the main sound interface. */
ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs);
@@ -277,11 +288,11 @@ SDL_FS_Deinitialize(void)
}
static SDL_bool
static int
SDL_FS_Init(SDL_AudioDriverImpl * impl)
{
if (LoadFusionSoundLibrary() < 0) {
return SDL_FALSE;
return 0;
} else {
DirectResult ret;
@@ -291,7 +302,7 @@ SDL_FS_Init(SDL_AudioDriverImpl * impl)
SDL_SetError
("FusionSound: SDL_FS_init failed (FusionSoundInit: %d)",
ret);
return SDL_FALSE;
return 0;
}
}
@@ -302,14 +313,14 @@ SDL_FS_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = SDL_FS_GetDeviceBuf;
impl->CloseDevice = SDL_FS_CloseDevice;
impl->Deinitialize = SDL_FS_Deinitialize;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap FUSIONSOUND_bootstrap = {
"fusionsound", "FusionSound", SDL_FS_Init, SDL_FALSE
"fusionsound", "FusionSound", SDL_FS_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_FUSIONSOUND */

View File

@@ -49,40 +49,39 @@ FillSound(void *device, void *stream, size_t len,
SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
SDL_AudioCallback callback = audio->callbackspec.callback;
SDL_LockMutex(audio->mixer_lock);
/* Only do something if audio is enabled */
if (!SDL_AtomicGet(&audio->enabled) || SDL_AtomicGet(&audio->paused)) {
if (audio->stream) {
SDL_AudioStreamClear(audio->stream);
}
SDL_memset(stream, audio->spec.silence, len);
} else {
SDL_assert(audio->spec.size == len);
if (audio->stream == NULL) { /* no conversion necessary. */
callback(audio->callbackspec.userdata, (Uint8 *) stream, len);
} else { /* streaming/converting */
const int stream_len = audio->callbackspec.size;
const int ilen = (int) len;
while (SDL_AudioStreamAvailable(audio->stream) < ilen) {
callback(audio->callbackspec.userdata, audio->work_buffer, stream_len);
if (SDL_AudioStreamPut(audio->stream, audio->work_buffer, stream_len) == -1) {
SDL_AudioStreamClear(audio->stream);
SDL_AtomicSet(&audio->enabled, 0);
break;
}
}
const int got = SDL_AudioStreamGet(audio->stream, stream, ilen);
SDL_assert((got < 0) || (got == ilen));
if (got != ilen) {
SDL_memset(stream, audio->spec.silence, len);
}
}
return;
}
SDL_UnlockMutex(audio->mixer_lock);
SDL_assert(audio->spec.size == len);
if (audio->stream == NULL) { /* no conversion necessary. */
SDL_LockMutex(audio->mixer_lock);
callback(audio->callbackspec.userdata, (Uint8 *) stream, len);
SDL_UnlockMutex(audio->mixer_lock);
} else { /* streaming/converting */
const int stream_len = audio->callbackspec.size;
const int ilen = (int) len;
while (SDL_AudioStreamAvailable(audio->stream) < ilen) {
callback(audio->callbackspec.userdata, audio->work_buffer, stream_len);
if (SDL_AudioStreamPut(audio->stream, audio->work_buffer, stream_len) == -1) {
SDL_AudioStreamClear(audio->stream);
SDL_AtomicSet(&audio->enabled, 0);
break;
}
}
const int got = SDL_AudioStreamGet(audio->stream, stream, ilen);
SDL_assert((got < 0) || (got == ilen));
if (got != ilen) {
SDL_memset(stream, audio->spec.silence, len);
}
}
}
static void
@@ -121,10 +120,11 @@ UnmaskSignals(sigset_t * omask)
static int
HAIKUAUDIO_OpenDevice(_THIS, const char *devname)
HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
int valid_datatype = 0;
media_raw_audio_format format;
SDL_AudioFormat test_format;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
/* Initialize all variables that we clean on shutdown */
_this->hidden = new SDL_PrivateAudioData;
@@ -138,7 +138,9 @@ HAIKUAUDIO_OpenDevice(_THIS, const char *devname)
format.byte_order = B_MEDIA_LITTLE_ENDIAN;
format.frame_rate = (float) _this->spec.freq;
format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */
for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
while ((!valid_datatype) && (test_format)) {
valid_datatype = 1;
_this->spec.format = test_format;
switch (test_format) {
case AUDIO_S8:
format.format = media_raw_audio_format::B_AUDIO_CHAR;
@@ -176,15 +178,15 @@ HAIKUAUDIO_OpenDevice(_THIS, const char *devname)
break;
default:
continue;
valid_datatype = 0;
test_format = SDL_NextAudioFormat();
break;
}
break;
}
if (!test_format) { /* shouldn't happen, but just in case... */
return SDL_SetError("%s: Unsupported audio format", "haiku");
if (!valid_datatype) { /* shouldn't happen, but just in case... */
return SDL_SetError("Unsupported audio format");
}
_this->spec.format = test_format;
/* Calculate the final parameters for this audio specification */
SDL_CalculateAudioSpec(&_this->spec);
@@ -214,22 +216,22 @@ HAIKUAUDIO_Deinitialize(void)
SDL_QuitBeApp();
}
static SDL_bool
static int
HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Initialize the Be Application, if it's not already started */
if (SDL_InitBeApp() < 0) {
return SDL_FALSE;
return 0;
}
/* Set the function pointers */
impl->OpenDevice = HAIKUAUDIO_OpenDevice;
impl->CloseDevice = HAIKUAUDIO_CloseDevice;
impl->Deinitialize = HAIKUAUDIO_Deinitialize;
impl->ProvidesOwnCallbackThread = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->ProvidesOwnCallbackThread = 1;
impl->OnlyHasDefaultOutputDevice = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
extern "C"
@@ -237,7 +239,7 @@ extern "C"
extern AudioBootStrap HAIKUAUDIO_bootstrap;
}
AudioBootStrap HAIKUAUDIO_bootstrap = {
"haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, SDL_FALSE
"haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_HAIKU */

View File

@@ -280,13 +280,12 @@ JACK_CloseDevice(_THIS)
}
static int
JACK_OpenDevice(_THIS, const char *devname)
JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
/* Note that JACK uses "output" for capture devices (they output audio
data to us) and "input" for playback (we input audio data to them).
Likewise, SDL's playback port will be "output" (we write data out)
and capture will be "input" (we read data in). */
SDL_bool iscapture = this->iscapture;
const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
@@ -406,18 +405,18 @@ JACK_Deinitialize(void)
UnloadJackLibrary();
}
static SDL_bool
static int
JACK_Init(SDL_AudioDriverImpl * impl)
{
if (LoadJackLibrary() < 0) {
return SDL_FALSE;
return 0;
} else {
/* Make sure a JACK server is running and available. */
jack_status_t status;
jack_client_t *client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
if (client == NULL) {
UnloadJackLibrary();
return SDL_FALSE;
return 0;
}
JACK_jack_client_close(client);
}
@@ -434,11 +433,11 @@ JACK_Init(SDL_AudioDriverImpl * impl)
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap JACK_bootstrap = {
"jack", "JACK Audio Connection Kit", JACK_Init, SDL_FALSE
"jack", "JACK Audio Connection Kit", JACK_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_JACK */

View File

@@ -49,8 +49,8 @@ static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta
const int len = (int) buffer_size;
SDL_AudioDevice* _this = (SDL_AudioDevice*) data;
SDL_AudioCallback callback = _this->callbackspec.callback;
SDL_LockMutex(_this->mixer_lock);
SDL_LockMutex(private->mutex); /* !!! FIXME: is this mutex necessary? */
/* Only do something if audio is enabled */
if (!SDL_AtomicGet(&_this->enabled) || SDL_AtomicGet(&_this->paused)) {
@@ -58,31 +58,34 @@ static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta
SDL_AudioStreamClear(_this->stream);
}
SDL_memset(stream, _this->spec.silence, len);
} else {
SDL_assert(_this->spec.size == len);
return;
}
if (_this->stream == NULL) { /* no conversion necessary. */
callback(_this->callbackspec.userdata, stream, len);
} else { /* streaming/converting */
const int stream_len = _this->callbackspec.size;
while (SDL_AudioStreamAvailable(_this->stream) < len) {
callback(_this->callbackspec.userdata, _this->work_buffer, stream_len);
if (SDL_AudioStreamPut(_this->stream, _this->work_buffer, stream_len) == -1) {
SDL_AudioStreamClear(_this->stream);
SDL_AtomicSet(&_this->enabled, 0);
break;
}
}
SDL_assert(_this->spec.size == len);
const int got = SDL_AudioStreamGet(_this->stream, stream, len);
SDL_assert((got < 0) || (got == len));
if (got != len) {
SDL_memset(stream, _this->spec.silence, len);
if (_this->stream == NULL) { /* no conversion necessary. */
SDL_LockMutex(_this->mixer_lock);
callback(_this->callbackspec.userdata, stream, len);
SDL_UnlockMutex(_this->mixer_lock);
} else { /* streaming/converting */
const int stream_len = _this->callbackspec.size;
while (SDL_AudioStreamAvailable(_this->stream) < len) {
callback(_this->callbackspec.userdata, _this->work_buffer, stream_len);
if (SDL_AudioStreamPut(_this->stream, _this->work_buffer, stream_len) == -1) {
SDL_AudioStreamClear(_this->stream);
SDL_AtomicSet(&_this->enabled, 0);
break;
}
}
const int got = SDL_AudioStreamGet(_this->stream, stream, len);
SDL_assert((got < 0) || (got == len));
if (got != len) {
SDL_memset(stream, _this->spec.silence, len);
}
}
SDL_UnlockMutex(_this->mixer_lock);
SDL_UnlockMutex(private->mutex);
}
static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) {
@@ -91,11 +94,12 @@ static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) {
SDL_PrivateAudioData *hidden = (SDL_PrivateAudioData *) device->hidden;
ppb_audio->StopPlayback(hidden->audio);
SDL_DestroyMutex(hidden->mutex);
core->ReleaseResource(hidden->audio);
}
static int
NACLAUDIO_OpenDevice(_THIS, const char *devname) {
NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
PP_Instance instance = PSGetInstanceId();
const PPB_Audio *ppb_audio = PSInterfaceAudio();
const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
@@ -105,6 +109,7 @@ NACLAUDIO_OpenDevice(_THIS, const char *devname) {
return SDL_OutOfMemory();
}
private->mutex = SDL_CreateMutex();
_this->spec.freq = 44100;
_this->spec.format = AUDIO_S16LSB;
_this->spec.channels = 2;
@@ -128,18 +133,18 @@ NACLAUDIO_OpenDevice(_THIS, const char *devname) {
return 0;
}
static SDL_bool
static int
NACLAUDIO_Init(SDL_AudioDriverImpl * impl)
{
if (PSGetInstanceId() == 0) {
return SDL_FALSE;
return 0;
}
/* Set the function pointers */
impl->OpenDevice = NACLAUDIO_OpenDevice;
impl->CloseDevice = NACLAUDIO_CloseDevice;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->ProvidesOwnCallbackThread = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
impl->ProvidesOwnCallbackThread = 1;
/*
* impl->WaitDevice = NACLAUDIO_WaitDevice;
* impl->GetDeviceBuf = NACLAUDIO_GetDeviceBuf;
@@ -147,12 +152,12 @@ NACLAUDIO_Init(SDL_AudioDriverImpl * impl)
* impl->Deinitialize = NACLAUDIO_Deinitialize;
*/
return SDL_TRUE;
return 1;
}
AudioBootStrap NACLAUDIO_bootstrap = {
NACLAUDIO_DRIVER_NAME, "SDL NaCl Audio Driver",
NACLAUDIO_Init, SDL_FALSE
NACLAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_NACL */

View File

@@ -34,7 +34,8 @@
#define private _this->hidden
typedef struct SDL_PrivateAudioData {
PP_Resource audio;
SDL_mutex* mutex;
PP_Resource audio;
} SDL_PrivateAudioData;
#endif /* SDL_naclaudio_h_ */

View File

@@ -237,6 +237,26 @@ NAS_CloseDevice(_THIS)
SDL_free(this->hidden);
}
static unsigned char
sdlformat_to_auformat(unsigned int fmt)
{
switch (fmt) {
case AUDIO_U8:
return AuFormatLinearUnsigned8;
case AUDIO_S8:
return AuFormatLinearSigned8;
case AUDIO_U16LSB:
return AuFormatLinearUnsigned16LSB;
case AUDIO_U16MSB:
return AuFormatLinearUnsigned16MSB;
case AUDIO_S16LSB:
return AuFormatLinearSigned16LSB;
case AUDIO_S16MSB:
return AuFormatLinearSigned16MSB;
}
return AuNone;
}
static AuBool
event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd)
{
@@ -311,12 +331,11 @@ find_device(_THIS)
}
static int
NAS_OpenDevice(_THIS, const char *devname)
NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
AuElement elms[3];
int buffer_size;
SDL_bool iscapture = this->iscapture;
SDL_AudioFormat test_format, format = 0;
SDL_AudioFormat test_format, format;
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
@@ -327,33 +346,16 @@ NAS_OpenDevice(_THIS, const char *devname)
SDL_zerop(this->hidden);
/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
switch (test_format) {
case AUDIO_U8:
format = AuFormatLinearUnsigned8;
break;
case AUDIO_S8:
format = AuFormatLinearSigned8;
break;
case AUDIO_U16LSB:
format = AuFormatLinearUnsigned16LSB;
break;
case AUDIO_U16MSB:
format = AuFormatLinearUnsigned16MSB;
break;
case AUDIO_S16LSB:
format = AuFormatLinearSigned16LSB;
break;
case AUDIO_S16MSB:
format = AuFormatLinearSigned16MSB;
break;
default:
continue;
format = 0;
for (test_format = SDL_FirstAudioFormat(this->spec.format);
!format && test_format;) {
format = sdlformat_to_auformat(test_format);
if (format == AuNone) {
test_format = SDL_NextAudioFormat();
}
break;
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "nas");
if (format == 0) {
return SDL_SetError("NAS: Couldn't find any hardware audio formats");
}
this->spec.format = test_format;
@@ -421,16 +423,16 @@ NAS_Deinitialize(void)
UnloadNASLibrary();
}
static SDL_bool
static int
NAS_Init(SDL_AudioDriverImpl * impl)
{
if (LoadNASLibrary() < 0) {
return SDL_FALSE;
return 0;
} else {
AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
if (aud == NULL) {
SDL_SetError("NAS: AuOpenServer() failed (no audio server?)");
return SDL_FALSE;
return 0;
}
NAS_AuCloseServer(aud);
}
@@ -445,15 +447,15 @@ NAS_Init(SDL_AudioDriverImpl * impl)
impl->CloseDevice = NAS_CloseDevice;
impl->Deinitialize = NAS_Deinitialize;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultCaptureDevice = 1;
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap NAS_bootstrap = {
"nas", "Network Audio System", NAS_Init, SDL_FALSE
"nas", "Network Audio System", NAS_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_NAS */

View File

@@ -56,7 +56,7 @@ static void
NETBSDAUDIO_Status(_THIS)
{
#ifdef DEBUG_AUDIO
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */
audio_info_t info;
const struct audio_prinfo *prinfo;
@@ -118,7 +118,7 @@ NETBSDAUDIO_Status(_THIS)
"",
this->spec.format,
this->spec.size);
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */
#endif /* DEBUG_AUDIO */
}
@@ -202,11 +202,9 @@ NETBSDAUDIO_CloseDevice(_THIS)
}
static int
NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
SDL_bool iscapture = this->iscapture;
SDL_AudioFormat test_format;
int encoding = AUDIO_ENCODING_NONE;
SDL_AudioFormat format = 0;
audio_info_t info, hwinfo;
struct audio_prinfo *prinfo = iscapture ? &info.record : &info.play;
@@ -246,46 +244,54 @@ NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
}
#endif
prinfo->encoding = AUDIO_ENCODING_NONE;
prinfo->sample_rate = this->spec.freq;
prinfo->channels = this->spec.channels;
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
switch (test_format) {
for (format = SDL_FirstAudioFormat(this->spec.format); format;) {
switch (format) {
case AUDIO_U8:
encoding = AUDIO_ENCODING_ULINEAR;
prinfo->encoding = AUDIO_ENCODING_ULINEAR;
prinfo->precision = 8;
break;
case AUDIO_S8:
encoding = AUDIO_ENCODING_SLINEAR;
prinfo->encoding = AUDIO_ENCODING_SLINEAR;
prinfo->precision = 8;
break;
case AUDIO_S16LSB:
encoding = AUDIO_ENCODING_SLINEAR_LE;
prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
prinfo->precision = 16;
break;
case AUDIO_S16MSB:
encoding = AUDIO_ENCODING_SLINEAR_BE;
prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
prinfo->precision = 16;
break;
case AUDIO_U16LSB:
encoding = AUDIO_ENCODING_ULINEAR_LE;
prinfo->encoding = AUDIO_ENCODING_ULINEAR_LE;
prinfo->precision = 16;
break;
case AUDIO_U16MSB:
encoding = AUDIO_ENCODING_ULINEAR_BE;
prinfo->encoding = AUDIO_ENCODING_ULINEAR_BE;
prinfo->precision = 16;
break;
case AUDIO_S32LSB:
encoding = AUDIO_ENCODING_SLINEAR_LE;
prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
prinfo->precision = 32;
break;
case AUDIO_S32MSB:
encoding = AUDIO_ENCODING_SLINEAR_BE;
prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
prinfo->precision = 32;
break;
default:
continue;
}
break;
if (prinfo->encoding != AUDIO_ENCODING_NONE) {
break;
}
format = SDL_NextAudioFormat();
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "netbsd");
if (prinfo->encoding == AUDIO_ENCODING_NONE) {
return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
}
prinfo->encoding = encoding;
prinfo->precision = SDL_AUDIO_BITSIZE(test_format);
info.hiwat = 5;
info.lowat = 3;
@@ -298,7 +304,7 @@ NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
}
/* Final spec used for the device. */
this->spec.format = test_format;
this->spec.format = format;
this->spec.freq = prinfo->sample_rate;
this->spec.channels = prinfo->channels;
@@ -320,7 +326,7 @@ NETBSDAUDIO_OpenDevice(_THIS, const char *devname)
return 0;
}
static SDL_bool
static int
NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -333,14 +339,14 @@ NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->FlushCapture = NETBSDAUDIO_FlushCapture;
impl->HasCaptureSupport = SDL_TRUE;
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
impl->AllowsArbitraryDeviceNames = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap NETBSDAUDIO_bootstrap = {
"netbsd", "NetBSD audio", NETBSDAUDIO_Init, SDL_FALSE
"netbsd", "NetBSD audio", NETBSDAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_NETBSD */

View File

@@ -407,7 +407,6 @@ openslES_CreatePCMPlayer(_THIS)
{
struct SDL_PrivateAudioData *audiodata = this->hidden;
SLDataFormat_PCM format_pcm;
SLAndroidDataFormat_PCM_EX format_pcm_ex;
SLresult result;
int i;
@@ -415,30 +414,31 @@ openslES_CreatePCMPlayer(_THIS)
it can be done as described here:
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
*/
if(SDL_GetAndroidSDKVersion() >= 21) {
SDL_AudioFormat test_format;
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
if (SDL_AUDIO_ISSIGNED(test_format)) {
break;
}
#if 1
/* Just go with signed 16-bit audio as it's the most compatible */
this->spec.format = AUDIO_S16SYS;
#else
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
while (test_format != 0) {
if (SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format)) {
break;
}
if (!test_format) {
/* Didn't find a compatible format : */
LOGI( "No compatible audio format, using signed 16-bit audio" );
test_format = AUDIO_S16SYS;
}
this->spec.format = test_format;
} else {
/* Just go with signed 16-bit audio as it's the most compatible */
this->spec.format = AUDIO_S16SYS;
test_format = SDL_NextAudioFormat();
}
if (test_format == 0) {
/* Didn't find a compatible format : */
LOGI( "No compatible audio format, using signed 16-bit audio" );
test_format = AUDIO_S16SYS;
}
this->spec.format = test_format;
#endif
/* Update the fragment size as size in bytes */
SDL_CalculateAudioSpec(&this->spec);
LOGI("Try to open %u hz %s %u bit chan %u %s samples %u",
this->spec.freq, SDL_AUDIO_ISFLOAT(this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(this->spec.format),
LOGI("Try to open %u hz %u bit chan %u %s samples %u",
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
/* configure audio source */
@@ -489,19 +489,7 @@ openslES_CreatePCMPlayer(_THIS)
break;
}
if(SDL_AUDIO_ISFLOAT(this->spec.format)) {
/* Copy all setup into PCM EX structure */
format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
format_pcm_ex.endianness = format_pcm.endianness;
format_pcm_ex.channelMask = format_pcm.channelMask;
format_pcm_ex.numChannels = format_pcm.numChannels;
format_pcm_ex.sampleRate = format_pcm.samplesPerSec;
format_pcm_ex.bitsPerSample = format_pcm.bitsPerSample;
format_pcm_ex.containerSize = format_pcm.containerSize;
format_pcm_ex.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
}
SLDataSource audioSrc = { &loc_bufq, SDL_AUDIO_ISFLOAT(this->spec.format) ? (void*)&format_pcm_ex : (void*)&format_pcm };
SLDataSource audioSrc = { &loc_bufq, &format_pcm };
/* configure audio sink */
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
@@ -595,14 +583,14 @@ failed:
}
static int
openslES_OpenDevice(_THIS, const char *devname)
openslES_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
if (this->hidden == NULL) {
return SDL_OutOfMemory();
}
if (this->iscapture) {
if (iscapture) {
LOGI("openslES_OpenDevice() %s for capture", devname);
return openslES_CreatePCMRecorder(this);
} else {
@@ -726,13 +714,13 @@ openslES_CloseDevice(_THIS)
SDL_free(this->hidden);
}
static SDL_bool
static int
openslES_Init(SDL_AudioDriverImpl * impl)
{
LOGI("openslES_Init() called");
if (!openslES_CreateEngine()) {
return SDL_FALSE;
return 0;
}
LOGI("openslES_Init() - set pointers");
@@ -748,18 +736,18 @@ openslES_Init(SDL_AudioDriverImpl * impl)
impl->Deinitialize = openslES_DestroyEngine;
/* and the capabilities */
impl->HasCaptureSupport = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->HasCaptureSupport = 1;
impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultCaptureDevice = 1;
LOGI("openslES_Init() - success");
/* this audio target is available. */
return SDL_TRUE;
return 1;
}
AudioBootStrap openslES_bootstrap = {
"openslES", "opensl ES audio driver", openslES_Init, SDL_FALSE
"openslES", "opensl ES audio driver", openslES_Init, 0
};
void openslES_ResumeDevices(void)

View File

@@ -248,28 +248,29 @@ static void OS2_CloseDevice(_THIS)
SDL_free(pAData);
}
static int OS2_OpenDevice(_THIS, const char *devname)
static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
int iscapture)
{
SDL_PrivateAudioData *pAData;
SDL_AudioFormat test_format;
SDL_AudioFormat SDLAudioFmt;
MCI_AMP_OPEN_PARMS stMCIAmpOpen;
MCI_BUFFER_PARMS stMCIBuffer;
ULONG ulRC;
ULONG ulIdx;
BOOL new_freq;
SDL_bool iscapture = _this->iscapture;
new_freq = FALSE;
SDL_zero(stMCIAmpOpen);
SDL_zero(stMCIBuffer);
for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
if (test_format == AUDIO_U8 || test_format == AUDIO_S16)
for (SDLAudioFmt = SDL_FirstAudioFormat(_this->spec.format);
SDLAudioFmt != 0; SDLAudioFmt = SDL_NextAudioFormat()) {
if (SDLAudioFmt == AUDIO_U8 || SDLAudioFmt == AUDIO_S16)
break;
}
if (!test_format) {
if (SDLAudioFmt == 0) {
debug_os2("Unsupported audio format, AUDIO_S16 used");
test_format = AUDIO_S16;
SDLAudioFmt = AUDIO_S16;
}
pAData = (SDL_PrivateAudioData *) SDL_calloc(1, sizeof(struct SDL_PrivateAudioData));
@@ -284,7 +285,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
}
/* Open audio device */
stMCIAmpOpen.usDeviceID = (_this->handle != NULL) ? ((ULONG)_this->handle - 1) : 0;
stMCIAmpOpen.usDeviceID = (handle != NULL) ? ((ULONG)handle - 1) : 0;
stMCIAmpOpen.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
ulRC = mciSendCommand(0, MCI_OPEN,
(_getEnvULong("SDL_AUDIO_SHARE", 1, 0) != 0)?
@@ -297,7 +298,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
}
pAData->usDeviceId = stMCIAmpOpen.usDeviceID;
if (iscapture) {
if (iscapture != 0) {
MCI_CONNECTOR_PARMS stMCIConnector;
MCI_AMP_SET_PARMS stMCIAmpSet;
BOOL fLineIn = _getEnvULong("SDL_AUDIO_LINEIN", 1, 0);
@@ -329,7 +330,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
&stMCIAmpSet, 0);
}
_this->spec.format = test_format;
_this->spec.format = SDLAudioFmt;
_this->spec.channels = _this->spec.channels > 1 ? 2 : 1;
if (_this->spec.freq < 8000) {
_this->spec.freq = 8000;
@@ -341,11 +342,11 @@ static int OS2_OpenDevice(_THIS, const char *devname)
/* Setup mixer. */
pAData->stMCIMixSetup.ulFormatTag = MCI_WAVE_FORMAT_PCM;
pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(test_format);
pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(SDLAudioFmt);
pAData->stMCIMixSetup.ulSamplesPerSec = _this->spec.freq;
pAData->stMCIMixSetup.ulChannels = _this->spec.channels;
pAData->stMCIMixSetup.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
if (!iscapture) {
if (iscapture == 0) {
pAData->stMCIMixSetup.ulFormatMode= MCI_PLAY;
pAData->stMCIMixSetup.pmixEvent = cbAudioWriteEvent;
} else {
@@ -422,7 +423,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
}
static SDL_bool OS2_Init(SDL_AudioDriverImpl * impl)
static int OS2_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
impl->DetectDevices = OS2_DetectDevices;
@@ -437,12 +438,12 @@ static SDL_bool OS2_Init(SDL_AudioDriverImpl * impl)
impl->FlushCapture = ;
impl->HasCaptureSupport = SDL_TRUE;
*/
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap OS2AUDIO_bootstrap = {
"DART", "OS/2 DART", OS2_Init, SDL_FALSE
"DART", "OS/2 DART", OS2_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_OS2 */

View File

@@ -223,12 +223,12 @@ PAUDIO_CloseDevice(_THIS)
}
static int
PAUDIO_OpenDevice(_THIS, const char *devname)
PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
const char *workaround = SDL_getenv("SDL_DSP_NOSELECT");
char audiodev[1024];
const char *err = NULL;
int flags;
int format;
int bytes_per_sample;
SDL_AudioFormat test_format;
audio_init paud_init;
@@ -316,44 +316,63 @@ PAUDIO_OpenDevice(_THIS, const char *devname)
paud_init.channels = this->spec.channels;
/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
format = 0;
for (test_format = SDL_FirstAudioFormat(this->spec.format);
!format && test_format;) {
#ifdef DEBUG_AUDIO
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
#endif
switch (test_format) {
case AUDIO_U8:
flags = TWOS_COMPLEMENT | FIXED;
bytes_per_sample = 1;
paud_init.bits_per_sample = 8;
paud_init.flags = TWOS_COMPLEMENT | FIXED;
format = 1;
break;
case AUDIO_S8:
flags = SIGNED | TWOS_COMPLEMENT | FIXED;
bytes_per_sample = 1;
paud_init.bits_per_sample = 8;
paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
format = 1;
break;
case AUDIO_S16LSB:
flags = SIGNED | TWOS_COMPLEMENT | FIXED;
bytes_per_sample = 2;
paud_init.bits_per_sample = 16;
paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED;
format = 1;
break;
case AUDIO_S16MSB:
flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED;
bytes_per_sample = 2;
paud_init.bits_per_sample = 16;
paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED;
format = 1;
break;
case AUDIO_U16LSB:
flags = TWOS_COMPLEMENT | FIXED;
bytes_per_sample = 2;
paud_init.bits_per_sample = 16;
paud_init.flags = TWOS_COMPLEMENT | FIXED;
format = 1;
break;
case AUDIO_U16MSB:
flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED;
bytes_per_sample = 2;
paud_init.bits_per_sample = 16;
paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED;
format = 1;
break;
default:
continue;
break;
}
if (!format) {
test_format = SDL_NextAudioFormat();
}
break;
}
if (!test_format) {
if (format == 0) {
#ifdef DEBUG_AUDIO
fprintf(stderr, "Couldn't find any hardware audio formats\n");
#endif
return SDL_SetError("%s: Unsupported audio format", "paud");
return SDL_SetError("Couldn't find any hardware audio formats");
}
this->spec.format = test_format;
paud_init.bits_per_sample = SDL_AUDIO_BITSIZE(test_format);
bytes_per_sample = SDL_AUDIO_BITSIZE(test_format) / 8;
paud_init.flags = flags;
/*
* We know the buffer size and the max number of subsequent writes
@@ -387,25 +406,28 @@ PAUDIO_OpenDevice(_THIS, const char *devname)
if (ioctl(fd, AUDIO_INIT, &paud_init) < 0) {
switch (paud_init.rc) {
case 1:
err = "DSP can't do play requests";
err = "Couldn't set audio format: DSP can't do play requests";
break;
case 2:
err = "DSP can't do record requests";
err = "Couldn't set audio format: DSP can't do record requests";
break;
case 4:
err = "request was invalid";
err = "Couldn't set audio format: request was invalid";
break;
case 5:
err = "conflict with open's flags";
err = "Couldn't set audio format: conflict with open's flags";
break;
case 6:
err = "out of DSP MIPS or memory";
err = "Couldn't set audio format: out of DSP MIPS or memory";
break;
default:
err = "not documented in sys/audio.h";
err = "Couldn't set audio format: not documented in sys/audio.h";
break;
}
return SDL_SetError("paud: Couldn't set audio format (%s)", err);
}
if (err != NULL) {
return SDL_SetError("Paudio: %s", err);
}
/* Allocate mixing buffer */
@@ -463,14 +485,14 @@ PAUDIO_OpenDevice(_THIS, const char *devname)
return 0;
}
static SDL_bool
static int
PAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* !!! FIXME: not right for device enum? */
int fd = OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
if (fd < 0) {
SDL_SetError("PAUDIO: Couldn't open audio device");
return SDL_FALSE;
return 0;
}
close(fd);
@@ -480,13 +502,13 @@ PAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->PlayDevice = PAUDIO_WaitDevice;
impl->GetDeviceBuf = PAUDIO_GetDeviceBuf;
impl->CloseDevice = PAUDIO_CloseDevice;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE; /* !!! FIXME: add device enum! */
impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: add device enum! */
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap PAUDIO_bootstrap = {
"paud", "AIX Paudio", PAUDIO_Init, SDL_FALSE
"paud", "AIX Paudio", PAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_PAUDIO */

View File

@@ -31,22 +31,8 @@
#include <pipewire/extensions/metadata.h>
#include <spa/param/audio/format-utils.h>
/*
* The following keys are defined for compatability when building against older versions of Pipewire
* prior to their introduction and can be removed if the minimum required Pipewire version is increased
* to or beyond their point of introduction.
*/
/*
* Introduced in 0.3.22
* Taken from /src/pipewire/keys.h
*/
#ifndef PW_KEY_CONFIG_NAME
#define PW_KEY_CONFIG_NAME "config.name"
#endif
/*
* Introduced in 0.3.33
/* Older versions of Pipewire may not define this, but it's safe to pass at
* runtime even if older installations don't recognize it.
* Taken from src/pipewire/keys.h
*/
#ifndef PW_KEY_NODE_RATE
@@ -54,22 +40,19 @@
#endif
/*
* This seems to be a sane lower limit as Pipewire
* uses it in several of it's own modules.
* These seem to be sane limits as Pipewire
* uses them in several of it's own modules.
*
* NOTE: 8192 is a hard upper limit in Pipewire and
* increasing this value can lead to buffer overflows.
*/
#define PW_MIN_SAMPLES 32 /* About 0.67ms at 48kHz */
#define PW_MIN_SAMPLES 32 /* About 0.67ms at 48kHz */
#define PW_MAX_SAMPLES 8192 /* About 170.6ms at 48kHz */
#define PW_BASE_CLOCK_RATE 48000
#define PW_POD_BUFFER_LENGTH 1024
#define PW_THREAD_NAME_BUFFER_LENGTH 128
enum PW_READY_FLAGS
{
PW_READY_FLAG_BUFFER_ADDED = 0x1,
PW_READY_FLAG_STREAM_READY = 0x2,
PW_READY_FLAG_ALL_BITS = 0x3
};
#define PW_ID_TO_HANDLE(x) (void *)((uintptr_t)x)
#define PW_HANDLE_TO_ID(x) (uint32_t)((uintptr_t)x)
@@ -103,13 +86,14 @@ static enum pw_stream_state (*PIPEWIRE_pw_stream_get_state)(struct pw_stream *st
static struct pw_buffer *(*PIPEWIRE_pw_stream_dequeue_buffer)(struct pw_stream *);
static int (*PIPEWIRE_pw_stream_queue_buffer)(struct pw_stream *, struct pw_buffer *);
static struct pw_properties *(*PIPEWIRE_pw_properties_new)(const char *, ...)SPA_SENTINEL;
static void (*PIPEWIRE_pw_properties_free)(struct pw_properties *);
static int (*PIPEWIRE_pw_properties_set)(struct pw_properties *, const char *, const char *);
static int (*PIPEWIRE_pw_properties_setf)(struct pw_properties *, const char *, const char *, ...) SPA_PRINTF_FUNC(3, 4);
#ifdef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC
static const char *pipewire_library = SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC;
static void *pipewire_handle = NULL;
static void * pipewire_handle = NULL;
static int
pipewire_dlsym(const char *fn, void **addr)
@@ -192,6 +176,7 @@ load_pipewire_syms()
SDL_PIPEWIRE_SYM(pw_stream_dequeue_buffer);
SDL_PIPEWIRE_SYM(pw_stream_queue_buffer);
SDL_PIPEWIRE_SYM(pw_properties_new);
SDL_PIPEWIRE_SYM(pw_properties_free);
SDL_PIPEWIRE_SYM(pw_properties_set);
SDL_PIPEWIRE_SYM(pw_properties_setf);
@@ -254,16 +239,16 @@ struct io_node
/* The global hotplug thread and associated objects. */
static struct pw_thread_loop *hotplug_loop;
static struct pw_core *hotplug_core;
static struct pw_context *hotplug_context;
static struct pw_registry *hotplug_registry;
static struct pw_core * hotplug_core;
static struct pw_context * hotplug_context;
static struct pw_registry * hotplug_registry;
static struct spa_hook hotplug_registry_listener;
static struct spa_hook hotplug_core_listener;
static struct spa_list hotplug_pending_list;
static struct spa_list hotplug_io_list;
static int hotplug_init_seq_val;
static SDL_bool hotplug_init_complete;
static SDL_bool hotplug_events_enabled;
static SDL_atomic_t hotplug_init_complete;
static SDL_atomic_t hotplug_events_enabled;
static Uint32 pipewire_default_sink_id = SPA_ID_INVALID;
static Uint32 pipewire_default_source_id = SPA_ID_INVALID;
@@ -275,6 +260,8 @@ io_list_check_add(struct io_node *node)
struct io_node *n;
SDL_bool ret = SDL_TRUE;
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
/* See if the node is already in the list */
spa_list_for_each (n, &hotplug_io_list, link) {
if (n->id == node->id) {
@@ -286,12 +273,14 @@ io_list_check_add(struct io_node *node)
/* Add to the list if the node doesn't already exist */
spa_list_append(&hotplug_io_list, &node->link);
if (hotplug_events_enabled) {
if (SDL_AtomicGet(&hotplug_events_enabled)) {
SDL_AddAudioDevice(node->is_capture, node->name, &node->spec, PW_ID_TO_HANDLE(node->id));
}
dup_found:
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
return ret;
}
@@ -300,12 +289,14 @@ io_list_remove(Uint32 id)
{
struct io_node *n, *temp;
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
/* Find and remove the node from the list */
spa_list_for_each_safe (n, temp, &hotplug_io_list, link) {
if (n->id == id) {
spa_list_remove(&n->link);
if (hotplug_events_enabled) {
if (SDL_AtomicGet(&hotplug_events_enabled)) {
SDL_RemoveAudioDevice(n->is_capture, PW_ID_TO_HANDLE(id));
}
@@ -314,6 +305,8 @@ io_list_remove(Uint32 id)
break;
}
}
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
}
static void
@@ -322,6 +315,8 @@ io_list_sort()
struct io_node *default_sink = NULL, *default_source = NULL;
struct io_node *n, *temp;
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
/* Find and move the default nodes to the beginning of the list */
spa_list_for_each_safe (n, temp, &hotplug_io_list, link) {
if (n->id == pipewire_default_sink_id) {
@@ -340,6 +335,8 @@ io_list_sort()
if (default_sink) {
spa_list_prepend(&hotplug_io_list, &default_sink->link);
}
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
}
static void
@@ -398,7 +395,7 @@ pending_list_clear()
static void *
node_object_new(Uint32 id, const char *type, Uint32 version, const void *funcs, const struct pw_core_events *core_events)
{
struct pw_proxy *proxy;
struct pw_proxy * proxy;
struct node_object *node;
/* Create the proxy object */
@@ -433,7 +430,7 @@ core_events_hotplug_init_callback(void *object, uint32_t id, int seq)
spa_hook_remove(&hotplug_core_listener);
/* Signal that the initial I/O list is populated */
hotplug_init_complete = SDL_TRUE;
SDL_AtomicSet(&hotplug_init_complete, 1);
PIPEWIRE_pw_thread_loop_signal(hotplug_loop, false);
}
}
@@ -442,7 +439,7 @@ static void
core_events_interface_callback(void *object, uint32_t id, int seq)
{
struct node_object *node = object;
struct io_node *io = node->userdata;
struct io_node * io = node->userdata;
if (id == PW_ID_CORE && seq == node->seq) {
/*
@@ -482,7 +479,7 @@ hotplug_core_sync(struct node_object *node)
node->seq = pw_core_sync(hotplug_core, PW_ID_CORE, node->seq);
}
if (!hotplug_init_complete) {
if (!SDL_AtomicGet(&hotplug_init_complete)) {
hotplug_init_seq_val = pw_core_sync(hotplug_core, PW_ID_CORE, hotplug_init_seq_val);
}
}
@@ -492,7 +489,7 @@ static SDL_bool
get_range_param(const struct spa_pod *param, Uint32 key, int *def, int *min, int *max)
{
const struct spa_pod_prop *prop;
struct spa_pod *value;
struct spa_pod * value;
Uint32 n_values, choice;
prop = spa_pod_find_prop(param, NULL, key);
@@ -546,8 +543,8 @@ static void
node_event_info(void *object, const struct pw_node_info *info)
{
struct node_object *node = object;
struct io_node *io = node->userdata;
const char *prop_val;
struct io_node * io = node->userdata;
const char * prop_val;
Uint32 i;
if (info) {
@@ -569,7 +566,7 @@ static void
node_event_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param)
{
struct node_object *node = object;
struct io_node *io = node->userdata;
struct io_node * io = node->userdata;
/* Get the default frequency */
if (io->spec.freq == 0) {
@@ -622,7 +619,7 @@ registry_event_global_callback(void *object, uint32_t id, uint32_t permissions,
const char *media_class = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
if (media_class) {
const char *node_desc;
const char * node_desc;
struct io_node *io;
SDL_bool is_capture;
int str_buffer_len;
@@ -741,30 +738,23 @@ hotplug_loop_destroy()
pending_list_clear();
io_list_clear();
hotplug_init_complete = SDL_FALSE;
hotplug_events_enabled = SDL_FALSE;
pipewire_default_sink_id = SPA_ID_INVALID;
pipewire_default_source_id = SPA_ID_INVALID;
SDL_AtomicSet(&hotplug_init_complete, 0);
SDL_AtomicSet(&hotplug_events_enabled, 0);
if (hotplug_registry) {
PIPEWIRE_pw_proxy_destroy((struct pw_proxy *)hotplug_registry);
hotplug_registry = NULL;
}
if (hotplug_core) {
PIPEWIRE_pw_core_disconnect(hotplug_core);
hotplug_core = NULL;
}
if (hotplug_context) {
PIPEWIRE_pw_context_destroy(hotplug_context);
hotplug_context = NULL;
}
if (hotplug_loop) {
PIPEWIRE_pw_thread_loop_destroy(hotplug_loop);
hotplug_loop = NULL;
}
}
@@ -776,7 +766,7 @@ PIPEWIRE_DetectDevices()
PIPEWIRE_pw_thread_loop_lock(hotplug_loop);
/* Wait until the initial registry enumeration is complete */
if (!hotplug_init_complete) {
if (!SDL_AtomicGet(&hotplug_init_complete)) {
PIPEWIRE_pw_thread_loop_wait(hotplug_loop);
}
@@ -787,7 +777,7 @@ PIPEWIRE_DetectDevices()
SDL_AddAudioDevice(io->is_capture, io->name, &io->spec, PW_ID_TO_HANDLE(io->id));
}
hotplug_events_enabled = SDL_TRUE;
SDL_AtomicSet(&hotplug_events_enabled, 1);
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
}
@@ -800,14 +790,14 @@ static const enum spa_audio_channel PIPEWIRE_channel_map_4[] = { SPA_AUDIO_CHANN
SPA_AUDIO_CHANNEL_RR };
static const enum spa_audio_channel PIPEWIRE_channel_map_5[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR };
static const enum spa_audio_channel PIPEWIRE_channel_map_6[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
static const enum spa_audio_channel PIPEWIRE_channel_map_6[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR };
static const enum spa_audio_channel PIPEWIRE_channel_map_7[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
static const enum spa_audio_channel PIPEWIRE_channel_map_7[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RC, SPA_AUDIO_CHANNEL_RL,
SPA_AUDIO_CHANNEL_RR };
static const enum spa_audio_channel PIPEWIRE_channel_map_8[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
static const enum spa_audio_channel PIPEWIRE_channel_map_8[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC,
SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR,
SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR };
SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR };
#define COPY_CHANNEL_MAP(c) SDL_memcpy(info->position, PIPEWIRE_channel_map_##c, sizeof(PIPEWIRE_channel_map_##c))
@@ -882,9 +872,9 @@ initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info_raw *info)
static void
output_callback(void *data)
{
struct pw_buffer *pw_buf;
struct pw_buffer * pw_buf;
struct spa_buffer *spa_buf;
Uint8 *dst;
Uint8 * dst;
_THIS = (SDL_AudioDevice *)data;
struct pw_stream *stream = this->hidden->stream;
@@ -910,7 +900,6 @@ output_callback(void *data)
* and run the callback with the work buffer to keep the callback
* firing regularly in case the audio is being used as a timer.
*/
SDL_LockMutex(this->mixer_lock);
if (!SDL_AtomicGet(&this->paused)) {
if (SDL_AtomicGet(&this->enabled)) {
dst = spa_buf->datas[0].data;
@@ -920,13 +909,18 @@ output_callback(void *data)
}
if (!this->stream) {
SDL_LockMutex(this->mixer_lock);
this->callbackspec.callback(this->callbackspec.userdata, dst, this->callbackspec.size);
SDL_UnlockMutex(this->mixer_lock);
} else {
int got;
/* Fire the callback until we have enough to fill a buffer */
while (SDL_AudioStreamAvailable(this->stream) < this->spec.size) {
SDL_LockMutex(this->mixer_lock);
this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size);
SDL_UnlockMutex(this->mixer_lock);
SDL_AudioStreamPut(this->stream, this->work_buffer, this->callbackspec.size);
}
@@ -936,7 +930,6 @@ output_callback(void *data)
} else {
SDL_memset(spa_buf->datas[0].data, this->spec.silence, this->spec.size);
}
SDL_UnlockMutex(this->mixer_lock);
spa_buf->datas[0].chunk->offset = 0;
spa_buf->datas[0].chunk->stride = this->hidden->stride;
@@ -948,9 +941,9 @@ output_callback(void *data)
static void
input_callback(void *data)
{
struct pw_buffer *pw_buf;
struct pw_buffer * pw_buf;
struct spa_buffer *spa_buf;
Uint8 *src;
Uint8 * src;
_THIS = (SDL_AudioDevice *)data;
struct pw_stream *stream = this->hidden->stream;
@@ -992,71 +985,35 @@ input_callback(void *data)
this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size);
SDL_UnlockMutex(this->mixer_lock);
}
} else if (this->hidden->buffer) { /* Flush the buffer when paused */
} else { /* Flush the buffer when paused */
if (SDL_CountDataQueue(this->hidden->buffer) != 0) {
SDL_ClearDataQueue(this->hidden->buffer, this->hidden->input_buffer_packet_size);
SDL_ClearDataQueue(this->hidden->buffer, this->hidden->buffer_period_size * 2);
}
}
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
}
static void
stream_add_buffer_callback(void *data, struct pw_buffer *buffer)
{
_THIS = data;
if (this->iscapture == SDL_FALSE) {
/*
* Clamp the output spec samples and size to the max size of the Pipewire buffer.
* If they exceed the maximum size of the Pipewire buffer, double buffering will be used.
*/
if (this->spec.size > buffer->buffer->datas[0].maxsize) {
this->spec.samples = buffer->buffer->datas[0].maxsize / this->hidden->stride;
this->spec.size = buffer->buffer->datas[0].maxsize;
}
} else if (this->hidden->buffer == NULL) {
/*
* The latency of source nodes can change, so buffering is always required.
*
* Ensure that the intermediate input buffer is large enough to hold the requested
* application packet size or a full buffer of data from Pipewire, whichever is larger.
*
* A packet size of 2 periods should be more than is ever needed.
*/
this->hidden->input_buffer_packet_size = SPA_MAX(this->spec.size, buffer->buffer->datas[0].maxsize) * 2;
this->hidden->buffer = SDL_NewDataQueue(this->hidden->input_buffer_packet_size, this->hidden->input_buffer_packet_size);
}
this->hidden->stream_init_status |= PW_READY_FLAG_BUFFER_ADDED;
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
}
static void
stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error)
{
_THIS = data;
if (state == PW_STREAM_STATE_STREAMING) {
this->hidden->stream_init_status |= PW_READY_FLAG_STREAM_READY;
}
if (state == PW_STREAM_STATE_STREAMING || state == PW_STREAM_STATE_ERROR) {
SDL_AtomicSet(&this->hidden->stream_initialized, 1);
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
}
}
static const struct pw_stream_events stream_output_events = { PW_VERSION_STREAM_EVENTS,
.state_changed = stream_state_changed_callback,
.add_buffer = stream_add_buffer_callback,
.process = output_callback };
static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_EVENTS,
.state_changed = stream_state_changed_callback,
.add_buffer = stream_add_buffer_callback,
.process = input_callback };
.state_changed = stream_state_changed_callback,
.process = input_callback };
static int
PIPEWIRE_OpenDevice(_THIS, const char *devname)
PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
/*
* NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream
@@ -1071,22 +1028,23 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
Uint8 pod_buffer[PW_POD_BUFFER_LENGTH];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(pod_buffer, sizeof(pod_buffer));
struct spa_audio_info_raw spa_info = { 0 };
const struct spa_pod *params = NULL;
const struct spa_pod * params = NULL;
struct SDL_PrivateAudioData *priv;
struct pw_properties *props;
const char *app_name, *stream_name, *stream_role, *error;
const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
SDL_bool iscapture = this->iscapture;
struct pw_properties * props;
const char * app_name, *stream_name, *stream_role, *error;
const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
enum pw_stream_state state;
int res;
/* Clamp the period size to sane values */
const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1);
const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1);
const int adjusted_samples = SPA_CLAMP(this->spec.samples, min_period, PW_MAX_SAMPLES);
/* Get the hints for the application name, stream name and role */
app_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
if (!app_name || *app_name == '\0') {
app_name = SDL_GetHint(SDL_HINT_APP_NAME);
if (!app_name || *app_name == '\0') {
if (!app_name || *app_name == '\0') {
app_name = "SDL Application";
}
}
@@ -1119,34 +1077,38 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
/* Size of a single audio frame in bytes */
priv->stride = (SDL_AUDIO_BITSIZE(this->spec.format) >> 3) * this->spec.channels;
if (this->spec.samples < min_period) {
this->spec.samples = min_period;
if (this->spec.samples != adjusted_samples && !iscapture) {
this->spec.samples = adjusted_samples;
this->spec.size = this->spec.samples * priv->stride;
}
SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)this->handle);
/* The latency of source nodes can change, so buffering is required. */
if (iscapture) {
priv->buffer_period_size = SPA_MAX(this->spec.samples, adjusted_samples) * priv->stride;
/* A packet size of 4 periods should be more than is ever needed (no more than 2 should be queued in practice). */
priv->buffer = SDL_NewDataQueue(priv->buffer_period_size * 4, priv->buffer_period_size * 2);
if (priv->buffer == NULL) {
return SDL_SetError("Pipewire: Failed to allocate source buffer");
}
}
SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)handle);
priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL);
if (priv->loop == NULL) {
return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno);
}
/*
* Load the realtime module so Pipewire can set the loop thread to the appropriate priority.
*
* NOTE: Pipewire versions 0.3.22 or higher require the PW_KEY_CONFIG_NAME property (with client-rt.conf),
* lower versions require explicitly specifying the 'rtkit' module.
*
* PW_KEY_CONTEXT_PROFILE_MODULES is deprecated and can be safely removed if the minimum required
* Pipewire version is increased to 0.3.22 or higher at some point.
*/
props = PIPEWIRE_pw_properties_new(PW_KEY_CONFIG_NAME, "client-rt.conf",
PW_KEY_CONTEXT_PROFILE_MODULES, "default,rtkit", NULL);
/* Load the rtkit module so Pipewire can set the loop thread to the appropriate priority */
props = PIPEWIRE_pw_properties_new(PW_KEY_CONTEXT_PROFILE_MODULES, "default,rtkit", NULL);
if (props == NULL) {
return SDL_SetError("Pipewire: Failed to create stream context properties (%i)", errno);
}
/* On success, the context owns the properties object and will free it at destruction time. */
priv->context = PIPEWIRE_pw_context_new(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), props, 0);
if (priv->context == NULL) {
PIPEWIRE_pw_properties_free(props);
return SDL_SetError("Pipewire: Failed to create stream context (%i)", errno);
}
@@ -1161,14 +1123,18 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
PIPEWIRE_pw_properties_set(props, PW_KEY_APP_NAME, app_name);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, stream_name);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, stream_name);
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", this->spec.samples, this->spec.freq);
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", adjusted_samples, this->spec.freq);
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", this->spec.freq);
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
/* Create the new stream */
/*
* Create the new stream
* On success, the stream owns the properties object and will free it at destruction time.
*/
priv->stream = PIPEWIRE_pw_stream_new_simple(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), stream_name, props,
iscapture ? &stream_input_events : &stream_output_events, this);
if (priv->stream == NULL) {
PIPEWIRE_pw_properties_free(props);
return SDL_SetError("Pipewire: Failed to create stream (%i)", errno);
}
@@ -1183,21 +1149,17 @@ PIPEWIRE_OpenDevice(_THIS, const char *devname)
return SDL_SetError("Pipewire: Failed to start stream loop");
}
/* Wait until all init flags are set or the stream has failed. */
/* Wait until the stream is either running or failed */
PIPEWIRE_pw_thread_loop_lock(priv->loop);
while (priv->stream_init_status != PW_READY_FLAG_ALL_BITS &&
PIPEWIRE_pw_stream_get_state(priv->stream, NULL) != PW_STREAM_STATE_ERROR) {
if (!SDL_AtomicGet(&priv->stream_initialized)) {
PIPEWIRE_pw_thread_loop_wait(priv->loop);
}
PIPEWIRE_pw_thread_loop_unlock(priv->loop);
if (PIPEWIRE_pw_stream_get_state(priv->stream, &error) == PW_STREAM_STATE_ERROR) {
return SDL_SetError("Pipewire: Stream error: %s", error);
}
state = PIPEWIRE_pw_stream_get_state(priv->stream, &error);
/* If this is a capture stream, make sure the intermediate buffer was successfully allocated. */
if (iscapture && priv->buffer == NULL) {
return SDL_SetError("Pipewire: Failed to allocate source buffer");
if (state == PW_STREAM_STATE_ERROR) {
return SDL_SetError("Pipewire: Stream error: %s", error);
}
return 0;
@@ -1238,19 +1200,19 @@ PIPEWIRE_Deinitialize()
}
}
static SDL_bool
static int
PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
{
if (!pipewire_initialized) {
if (init_pipewire_library() < 0) {
return SDL_FALSE;
return 0;
}
pipewire_initialized = SDL_TRUE;
if (hotplug_loop_init() < 0) {
PIPEWIRE_Deinitialize();
return SDL_FALSE;
return 0;
}
}
@@ -1260,13 +1222,13 @@ PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
impl->CloseDevice = PIPEWIRE_CloseDevice;
impl->Deinitialize = PIPEWIRE_Deinitialize;
impl->HasCaptureSupport = SDL_TRUE;
impl->ProvidesOwnCallbackThread = SDL_TRUE;
impl->HasCaptureSupport = 1;
impl->ProvidesOwnCallbackThread = 1;
return SDL_TRUE;
return 1;
}
AudioBootStrap PIPEWIRE_bootstrap = { "pipewire", "Pipewire", PIPEWIRE_Init, SDL_FALSE };
AudioBootStrap PIPEWIRE_bootstrap = { "pipewire", "Pipewire", PIPEWIRE_Init, 0 };
#endif /* SDL_AUDIO_DRIVER_PIPEWIRE */

View File

@@ -37,9 +37,9 @@ struct SDL_PrivateAudioData
struct pw_context *context;
struct SDL_DataQueue *buffer;
size_t input_buffer_packet_size;
Sint32 stride; /* Bytes-per-frame */
int stream_init_status;
size_t buffer_period_size;
Sint32 stride; /* Bytes-per-frame */
SDL_atomic_t stream_initialized;
};
#endif /* SDL_pipewire_h_ */

View File

@@ -42,7 +42,7 @@
#define PSPAUDIO_DRIVER_NAME "psp"
static int
PSPAUDIO_OpenDevice(_THIS, const char *devname)
PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
int format, mixlen, i;
@@ -158,7 +158,7 @@ static void PSPAUDIO_ThreadInit(_THIS)
}
}
static SDL_bool
static int
PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -170,16 +170,16 @@ PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->ThreadInit = PSPAUDIO_ThreadInit;
/* PSP audio device */
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = 1;
/*
impl->HasCaptureSupport = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->HasCaptureSupport = 1;
impl->OnlyHasDefaultCaptureDevice = 1;
*/
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap PSPAUDIO_bootstrap = {
"psp", "PSP audio driver", PSPAUDIO_Init, SDL_FALSE
"psp", "PSP audio driver", PSPAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_PSP */

View File

@@ -107,6 +107,8 @@ static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *,
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (const pa_stream *);
static size_t (*PULSEAUDIO_pa_stream_writable_size) (const pa_stream *);
static size_t (*PULSEAUDIO_pa_stream_readable_size) (const pa_stream *);
static int (*PULSEAUDIO_pa_stream_begin_write) (pa_stream *, void **, size_t*);
static int (*PULSEAUDIO_pa_stream_cancel_write) (pa_stream *);
static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t,
pa_free_cb_t, int64_t, pa_seek_mode_t);
static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
@@ -117,7 +119,6 @@ static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *,
pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *);
static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *);
static void (*PULSEAUDIO_pa_stream_set_write_callback)(pa_stream *, pa_stream_request_cb_t, void *);
static int load_pulseaudio_syms(void);
@@ -221,6 +222,8 @@ load_pulseaudio_syms(void)
SDL_PULSEAUDIO_SYM(pa_stream_writable_size);
SDL_PULSEAUDIO_SYM(pa_stream_readable_size);
SDL_PULSEAUDIO_SYM(pa_stream_write);
SDL_PULSEAUDIO_SYM(pa_stream_begin_write);
SDL_PULSEAUDIO_SYM(pa_stream_cancel_write);
SDL_PULSEAUDIO_SYM(pa_stream_drain);
SDL_PULSEAUDIO_SYM(pa_stream_disconnect);
SDL_PULSEAUDIO_SYM(pa_stream_peek);
@@ -229,7 +232,6 @@ load_pulseaudio_syms(void)
SDL_PULSEAUDIO_SYM(pa_stream_unref);
SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto);
SDL_PULSEAUDIO_SYM(pa_strerror);
SDL_PULSEAUDIO_SYM(pa_stream_set_write_callback);
return 0;
}
@@ -356,57 +358,52 @@ ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
/* This function waits until it is possible to write a full sound buffer */
static void
PULSEAUDIO_WaitDevice(_THIS)
{
/* this is a no-op; we wait in PULSEAUDIO_PlayDevice now. */
}
static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata)
{
struct SDL_PrivateAudioData *h = (struct SDL_PrivateAudioData *) userdata;
/*printf("PULSEAUDIO WRITE CALLBACK! nbytes=%u\n", (unsigned int) nbytes);*/
h->bytes_requested += nbytes;
}
static void
PULSEAUDIO_PlayDevice(_THIS)
{
struct SDL_PrivateAudioData *h = this->hidden;
int available = h->mixlen;
int written = 0;
int cpy;
/*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/
while (SDL_AtomicGet(&this->enabled) && (available > 0)) {
cpy = SDL_min(h->bytes_requested, available);
if (cpy) {
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf + written, cpy, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
SDL_OpenedAudioDeviceDisconnected(this);
return;
}
/*printf("PULSEAUDIO FEED! nbytes=%u\n", (unsigned int) cpy);*/
h->bytes_requested -= cpy;
written += cpy;
available -= cpy;
}
/* let WriteCallback fire if necessary. */
/*printf("PULSEAUDIO ITERATE!\n");*/
while (SDL_AtomicGet(&this->enabled)) {
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
SDL_OpenedAudioDeviceDisconnected(this);
return;
}
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= (h->mixlen/8)) {
return;
}
}
}
/*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/
static void
PULSEAUDIO_PlayDevice(_THIS)
{
/* Write the audio data */
struct SDL_PrivateAudioData *h = this->hidden;
if (SDL_AtomicGet(&this->enabled)) {
if (PULSEAUDIO_pa_stream_write(h->stream, h->pabuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
SDL_OpenedAudioDeviceDisconnected(this);
}
}
}
static Uint8 *
PULSEAUDIO_GetDeviceBuf(_THIS)
{
return this->hidden->mixbuf;
struct SDL_PrivateAudioData *h = this->hidden;
size_t nbytes = h->mixlen;
int ret;
ret = PULSEAUDIO_pa_stream_begin_write(h->stream, &h->pabuf, &nbytes);
if (ret != 0) {
/* fall back it intermediate buffer */
h->pabuf = h->mixbuf;
} else if (nbytes < h->mixlen) {
PULSEAUDIO_pa_stream_cancel_write(h->stream);
h->pabuf = h->mixbuf;
}
return (Uint8 *)h->pabuf;
}
@@ -525,7 +522,7 @@ SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, vo
}
static SDL_bool
FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool iscapture, void *handle)
FindDeviceName(struct SDL_PrivateAudioData *h, const int iscapture, void *handle)
{
const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1;
@@ -547,17 +544,16 @@ FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool iscapture, void *h
}
static int
PULSEAUDIO_OpenDevice(_THIS, const char *devname)
PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
struct SDL_PrivateAudioData *h = NULL;
SDL_AudioFormat test_format;
Uint16 test_format = 0;
pa_sample_spec paspec;
pa_buffer_attr paattr;
pa_channel_map pacmap;
pa_stream_flags_t flags = 0;
const char *name = NULL;
SDL_bool iscapture = this->iscapture;
int state = 0, format = PA_SAMPLE_INVALID;
int state = 0;
int rc = 0;
/* Initialize all variables that we clean on shutdown */
@@ -568,45 +564,53 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname)
}
SDL_zerop(this->hidden);
paspec.format = PA_SAMPLE_INVALID;
/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
for (test_format = SDL_FirstAudioFormat(this->spec.format);
(paspec.format == PA_SAMPLE_INVALID) && test_format;) {
#ifdef DEBUG_AUDIO
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
#endif
switch (test_format) {
case AUDIO_U8:
format = PA_SAMPLE_U8;
paspec.format = PA_SAMPLE_U8;
break;
case AUDIO_S16LSB:
format = PA_SAMPLE_S16LE;
paspec.format = PA_SAMPLE_S16LE;
break;
case AUDIO_S16MSB:
format = PA_SAMPLE_S16BE;
paspec.format = PA_SAMPLE_S16BE;
break;
case AUDIO_S32LSB:
format = PA_SAMPLE_S32LE;
paspec.format = PA_SAMPLE_S32LE;
break;
case AUDIO_S32MSB:
format = PA_SAMPLE_S32BE;
paspec.format = PA_SAMPLE_S32BE;
break;
case AUDIO_F32LSB:
format = PA_SAMPLE_FLOAT32LE;
paspec.format = PA_SAMPLE_FLOAT32LE;
break;
case AUDIO_F32MSB:
format = PA_SAMPLE_FLOAT32BE;
paspec.format = PA_SAMPLE_FLOAT32BE;
break;
default:
continue;
paspec.format = PA_SAMPLE_INVALID;
break;
}
if (paspec.format == PA_SAMPLE_INVALID) {
test_format = SDL_NextAudioFormat();
}
break;
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "pulseaudio");
if (paspec.format == PA_SAMPLE_INVALID) {
return SDL_SetError("Couldn't find any hardware audio formats");
}
this->spec.format = test_format;
paspec.format = format;
/* Calculate the final parameters for this audio specification */
#ifdef PA_STREAM_ADJUST_LATENCY
this->spec.samples /= 2; /* Mix in smaller chunck to avoid underruns */
#endif
SDL_CalculateAudioSpec(&this->spec);
/* Allocate mixing buffer */
@@ -623,18 +627,28 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname)
paspec.rate = this->spec.freq;
/* Reduced prebuffering compared to the defaults. */
#ifdef PA_STREAM_ADJUST_LATENCY
paattr.fragsize = this->spec.size;
paattr.tlength = h->mixlen;
/* 2x original requested bufsize */
paattr.tlength = h->mixlen * 4;
paattr.prebuf = -1;
paattr.maxlength = -1;
paattr.minreq = -1;
flags |= PA_STREAM_ADJUST_LATENCY;
/* -1 can lead to pa_stream_writable_size() >= mixlen never being true */
paattr.minreq = h->mixlen;
flags = PA_STREAM_ADJUST_LATENCY;
#else
paattr.fragsize = this->spec.size;
paattr.tlength = h->mixlen*2;
paattr.prebuf = h->mixlen*2;
paattr.maxlength = h->mixlen*2;
paattr.minreq = h->mixlen;
#endif
if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) {
return SDL_SetError("Could not connect to PulseAudio server");
}
if (!FindDeviceName(h, iscapture, this->handle)) {
if (!FindDeviceName(h, iscapture, handle)) {
return SDL_SetError("Requested PulseAudio sink/source missing?");
}
@@ -665,7 +679,6 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname)
if (iscapture) {
rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags);
} else {
PULSEAUDIO_pa_stream_set_write_callback(h->stream, WriteCallback, h);
rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL);
}
@@ -819,16 +832,16 @@ PULSEAUDIO_Deinitialize(void)
UnloadPulseAudioLibrary();
}
static SDL_bool
static int
PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
{
if (LoadPulseAudioLibrary() < 0) {
return SDL_FALSE;
return 0;
}
if (ConnectToPulseServer(&hotplug_mainloop, &hotplug_context) < 0) {
UnloadPulseAudioLibrary();
return SDL_FALSE;
return 0;
}
include_monitors = SDL_GetHintBoolean(SDL_HINT_AUDIO_INCLUDE_MONITORS, SDL_FALSE);
@@ -846,11 +859,11 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap PULSEAUDIO_bootstrap = {
"pulseaudio", "PulseAudio", PULSEAUDIO_Init, SDL_FALSE
"pulseaudio", "PulseAudio", PULSEAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO */

View File

@@ -43,7 +43,11 @@ struct SDL_PrivateAudioData
Uint8 *mixbuf;
int mixlen;
int bytes_requested; /* bytes of data the hardware wants _now_. */
/* Pointer to the actual buffer in use in the current
GetDeviceBuf() -> PlayDevice() iteration.
Can be either the pointer returned by pa_stream_begin_write()
or mixbuf */
void *pabuf;
const Uint8 *capturebuf;
int capturelen;

View File

@@ -121,7 +121,7 @@ QSA_WaitDevice(_THIS)
/* For example, Vortex 8820 audio driver stucks on second DAC because */
/* it doesn't exist ! */
result = SDL_IOReady(this->hidden->audio_fd,
this->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
this->hidden->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
2 * 1000);
switch (result) {
case -1:
@@ -180,7 +180,7 @@ QSA_PlayDevice(_THIS)
} else {
if ((errno == EINVAL) || (errno == EIO)) {
SDL_zero(cstatus);
if (!this->iscapture) {
if (!this->hidden->iscapture) {
cstatus.channel = SND_PCM_CHANNEL_PLAYBACK;
} else {
cstatus.channel = SND_PCM_CHANNEL_CAPTURE;
@@ -196,7 +196,7 @@ QSA_PlayDevice(_THIS)
if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) ||
(cstatus.status == SND_PCM_STATUS_READY)) {
if (!this->iscapture) {
if (!this->hidden->iscapture) {
status =
snd_pcm_plugin_prepare(this->hidden->
audio_handle,
@@ -240,7 +240,7 @@ static void
QSA_CloseDevice(_THIS)
{
if (this->hidden->audio_handle != NULL) {
if (!this->iscapture) {
if (!this->hidden->iscapture) {
/* Finish playing available samples */
snd_pcm_plugin_flush(this->hidden->audio_handle,
SND_PCM_CHANNEL_PLAYBACK);
@@ -257,13 +257,13 @@ QSA_CloseDevice(_THIS)
}
static int
QSA_OpenDevice(_THIS, const char *devname)
QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
const QSA_Device *device = (const QSA_Device *) this->handle;
SDL_Bool iscapture = this->iscapture;
const QSA_Device *device = (const QSA_Device *) handle;
int status = 0;
int format = 0;
SDL_AudioFormat test_format;
SDL_AudioFormat test_format = 0;
int found = 0;
snd_pcm_channel_setup_t csetup;
snd_pcm_channel_params_t cparams;
@@ -280,6 +280,9 @@ QSA_OpenDevice(_THIS, const char *devname)
/* Initialize channel transfer parameters to default */
QSA_InitAudioParams(&cparams);
/* Initialize channel direction: capture or playback */
this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
if (device != NULL) {
/* Open requested audio device */
this->hidden->deviceno = device->deviceno;
@@ -302,49 +305,89 @@ QSA_OpenDevice(_THIS, const char *devname)
}
/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
format = 0;
/* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */
found = 0;
for (test_format = SDL_FirstAudioFormat(this->spec.format); !found;) {
/* if match found set format to equivalent QSA format */
switch (test_format) {
case AUDIO_U8:
format = SND_PCM_SFMT_U8;
{
format = SND_PCM_SFMT_U8;
found = 1;
}
break;
case AUDIO_S8:
format = SND_PCM_SFMT_S8;
{
format = SND_PCM_SFMT_S8;
found = 1;
}
break;
case AUDIO_S16LSB:
format = SND_PCM_SFMT_S16_LE;
{
format = SND_PCM_SFMT_S16_LE;
found = 1;
}
break;
case AUDIO_S16MSB:
format = SND_PCM_SFMT_S16_BE;
{
format = SND_PCM_SFMT_S16_BE;
found = 1;
}
break;
case AUDIO_U16LSB:
format = SND_PCM_SFMT_U16_LE;
{
format = SND_PCM_SFMT_U16_LE;
found = 1;
}
break;
case AUDIO_U16MSB:
format = SND_PCM_SFMT_U16_BE;
{
format = SND_PCM_SFMT_U16_BE;
found = 1;
}
break;
case AUDIO_S32LSB:
format = SND_PCM_SFMT_S32_LE;
{
format = SND_PCM_SFMT_S32_LE;
found = 1;
}
break;
case AUDIO_S32MSB:
format = SND_PCM_SFMT_S32_BE;
{
format = SND_PCM_SFMT_S32_BE;
found = 1;
}
break;
case AUDIO_F32LSB:
format = SND_PCM_SFMT_FLOAT_LE;
{
format = SND_PCM_SFMT_FLOAT_LE;
found = 1;
}
break;
case AUDIO_F32MSB:
format = SND_PCM_SFMT_FLOAT_BE;
{
format = SND_PCM_SFMT_FLOAT_BE;
found = 1;
}
break;
default:
continue;
{
break;
}
}
if (!found) {
test_format = SDL_NextAudioFormat();
}
break;
}
/* assumes test_format not 0 on success */
/* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "qsa");
if (test_format == 0) {
return SDL_SetError("QSA: Couldn't find any hardware audio formats");
}
this->spec.format = test_format;
/* Set the audio format */
@@ -364,7 +407,7 @@ QSA_OpenDevice(_THIS, const char *devname)
/* Make sure channel is setup right one last time */
SDL_zero(csetup);
if (!this->iscapture) {
if (!this->hidden->iscapture) {
csetup.channel = SND_PCM_CHANNEL_PLAYBACK;
} else {
csetup.channel = SND_PCM_CHANNEL_CAPTURE;
@@ -400,7 +443,7 @@ QSA_OpenDevice(_THIS, const char *devname)
this->hidden->pcm_len);
/* get the file descriptor */
if (!this->iscapture) {
if (!this->hidden->iscapture) {
this->hidden->audio_fd =
snd_pcm_file_descriptor(this->hidden->audio_handle,
SND_PCM_CHANNEL_PLAYBACK);
@@ -415,7 +458,7 @@ QSA_OpenDevice(_THIS, const char *devname)
}
/* Prepare an audio channel */
if (!this->iscapture) {
if (!this->hidden->iscapture) {
/* Prepare audio playback */
status =
snd_pcm_plugin_prepare(this->hidden->audio_handle,
@@ -592,7 +635,7 @@ QSA_Deinitialize(void)
qsa_capture_devices = 0;
}
static SDL_bool
static int
QSA_Init(SDL_AudioDriverImpl * impl)
{
/* Clear devices array */
@@ -612,14 +655,20 @@ QSA_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = QSA_GetDeviceBuf;
impl->CloseDevice = QSA_CloseDevice;
impl->Deinitialize = QSA_Deinitialize;
impl->LockDevice = NULL;
impl->UnlockDevice = NULL;
impl->HasCaptureSupport = SDL_TRUE;
impl->ProvidesOwnCallbackThread = 0;
impl->SkipMixerLock = 0;
impl->HasCaptureSupport = 1;
impl->OnlyHasDefaultOutputDevice = 0;
impl->OnlyHasDefaultCaptureDevice = 0;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap QSAAUDIO_bootstrap = {
"qsa", "QNX QSA Audio", QSA_Init, SDL_FALSE
"qsa", "QNX QSA Audio", QSA_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_QSA */

View File

@@ -33,6 +33,9 @@
struct SDL_PrivateAudioData
{
/* SDL capture state */
SDL_bool iscapture;
/* The audio device handle */
int cardno;
int deviceno;

View File

@@ -237,11 +237,11 @@ SNDIO_CloseDevice(_THIS)
}
static int
SNDIO_OpenDevice(_THIS, const char *devname)
SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
SDL_AudioFormat test_format;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
struct sio_par par;
SDL_bool iscapture = this->iscapture;
int status;
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc(sizeof(*this->hidden));
@@ -273,7 +273,8 @@ SNDIO_OpenDevice(_THIS, const char *devname)
par.appbufsz = par.round * 2;
/* Try for a closest match on audio format */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
status = -1;
while (test_format && (status < 0)) {
if (!SDL_AUDIO_ISFLOAT(test_format)) {
par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0;
par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0;
@@ -289,13 +290,15 @@ SNDIO_OpenDevice(_THIS, const char *devname)
continue;
}
if ((par.bits == 8 * par.bps) || (par.msb)) {
status = 0;
break;
}
}
test_format = SDL_NextAudioFormat();
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "sndio");
if (status < 0) {
return SDL_SetError("sndio: Couldn't find any hardware audio formats");
}
if ((par.bps == 4) && (par.sig) && (par.le))
@@ -354,11 +357,11 @@ SNDIO_DetectDevices(void)
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *) 0x2);
}
static SDL_bool
static int
SNDIO_Init(SDL_AudioDriverImpl * impl)
{
if (LoadSNDIOLibrary() < 0) {
return SDL_FALSE;
return 0;
}
/* Set the function pointers */
@@ -372,14 +375,14 @@ SNDIO_Init(SDL_AudioDriverImpl * impl)
impl->Deinitialize = SNDIO_Deinitialize;
impl->DetectDevices = SNDIO_DetectDevices;
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
impl->AllowsArbitraryDeviceNames = 1;
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap SNDIO_bootstrap = {
"sndio", "OpenBSD sndio", SNDIO_Init, SDL_FALSE
"sndio", "OpenBSD sndio", SNDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_SNDIO */

View File

@@ -188,12 +188,11 @@ SUNAUDIO_CloseDevice(_THIS)
}
static int
SUNAUDIO_OpenDevice(_THIS, const char *devname)
SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
#ifdef AUDIO_SETINFO
int enc;
#endif
SDL_bool iscapture = this->iscapture;
int desired_freq = 0;
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
SDL_AudioFormat format = 0;
@@ -395,7 +394,7 @@ snd2au(int sample)
return (mask & sample);
}
static SDL_bool
static int
SUNAUDIO_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -406,13 +405,13 @@ SUNAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf;
impl->CloseDevice = SUNAUDIO_CloseDevice;
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
impl->AllowsArbitraryDeviceNames = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap SUNAUDIO_bootstrap = {
"audio", "UNIX /dev/audio interface", SUNAUDIO_Init, SDL_FALSE
"audio", "UNIX /dev/audio interface", SUNAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_SUNAUDIO */

View File

@@ -37,35 +37,18 @@
#include <psp2/kernel/threadmgr.h>
#include <psp2/audioout.h>
#include <psp2/audioin.h>
#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63)
#define SCE_AUDIO_MAX_VOLUME 0x8000
static int
VITAAUD_OpenCaptureDevice(_THIS)
{
this->spec.freq = 16000;
this->spec.samples = 512;
this->spec.channels = 1;
SDL_CalculateAudioSpec(&this->spec);
this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE , 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
if (this->hidden->port < 0) {
return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port);
}
return 0;
}
/* The tag name used by VITA audio */
#define VITAAUD_DRIVER_NAME "vita"
static int
VITAAUD_OpenDevice(_THIS, const char *devname)
VITAAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN;
int vols[2] = {SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME};
SDL_AudioFormat test_format;
this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc(sizeof(*this->hidden));
@@ -73,20 +56,13 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
return SDL_OutOfMemory();
}
SDL_memset(this->hidden, 0, sizeof(*this->hidden));
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
if (test_format == AUDIO_S16LSB) {
this->spec.format = test_format;
switch (this->spec.format & 0xff) {
case 8:
case 16:
this->spec.format = AUDIO_S16LSB;
break;
}
}
if(!test_format) {
return SDL_SetError("Unsupported audio format");
}
if (this->iscapture) {
return VITAAUD_OpenCaptureDevice(this);
default:
return SDL_SetError("Unsupported audio format");
}
/* The sample count must be a multiple of 64. */
@@ -115,14 +91,14 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
}
this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
if (this->hidden->port < 0) {
this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
if (this->hidden->channel < 0) {
free(this->hidden->rawbuf);
this->hidden->rawbuf = NULL;
return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port);
return SDL_SetError("Couldn't reserve hardware channel");
}
sceAudioOutSetVolume(this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
SDL_memset(this->hidden->rawbuf, 0, mixlen);
for (i = 0; i < NUM_BUFFERS; i++) {
@@ -137,7 +113,7 @@ static void VITAAUD_PlayDevice(_THIS)
{
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
sceAudioOutOutput(this->hidden->port, mixbuf);
sceAudioOutOutput(this->hidden->channel, mixbuf);
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
}
@@ -147,7 +123,6 @@ static void VITAAUD_WaitDevice(_THIS)
{
/* Because we block when sending audio, there's no need for this function to do anything. */
}
static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
{
return this->hidden->mixbufs[this->hidden->next_buffer];
@@ -155,32 +130,17 @@ static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
static void VITAAUD_CloseDevice(_THIS)
{
if (this->hidden->port >= 0) {
if (this->iscapture) {
sceAudioInReleasePort(this->hidden->port);
} else {
sceAudioOutReleasePort(this->hidden->port);
}
this->hidden->port = -1;
if (this->hidden->channel >= 0) {
sceAudioOutReleasePort(this->hidden->channel);
this->hidden->channel = -1;
}
if (!this->iscapture && this->hidden->rawbuf != NULL) {
if (this->hidden->rawbuf != NULL) {
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
this->hidden->rawbuf = NULL;
}
}
static int VITAAUD_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
int ret;
SDL_assert(buflen == this->spec.size);
ret = sceAudioInInput(this->hidden->port, buffer);
if (ret < 0) {
return SDL_SetError("Failed to capture from device: %x", ret);
}
return this->spec.size;
}
static void VITAAUD_ThreadInit(_THIS)
{
/* Increase the priority of this audio thread by 1 to put it
@@ -194,7 +154,7 @@ static void VITAAUD_ThreadInit(_THIS)
}
}
static SDL_bool
static int
VITAAUD_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -205,18 +165,17 @@ VITAAUD_Init(SDL_AudioDriverImpl * impl)
impl->CloseDevice = VITAAUD_CloseDevice;
impl->ThreadInit = VITAAUD_ThreadInit;
impl->CaptureFromDevice = VITAAUD_CaptureFromDevice;
/* and the capabilities */
impl->HasCaptureSupport = SDL_TRUE;
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
/* VITA audio device */
impl->OnlyHasDefaultOutputDevice = 1;
/*
impl->HasCaptureSupport = 1;
impl->OnlyHasDefaultInputDevice = 1;
*/
return 1; /* this audio target is available. */
}
AudioBootStrap VITAAUD_bootstrap = {
"vita", "VITA audio driver", VITAAUD_Init, SDL_FALSE
"vita", "VITA audio driver", VITAAUD_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_VITA */

View File

@@ -30,8 +30,8 @@
#define NUM_BUFFERS 2
struct SDL_PrivateAudioData {
/* The hardware input/output port. */
int port;
/* The hardware output channel. */
int channel;
/* The raw allocated mixing buffer. */
Uint8 *rawbuf;
/* Individual mixing buffers. */

View File

@@ -209,7 +209,7 @@ UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
}
if (!this->stream) {
return -1; /* SDL_NewAudioStream should have called SDL_SetError. */
return -1;
}
}
@@ -512,8 +512,9 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
IAudioRenderClient *render = NULL;
IAudioCaptureClient *capture = NULL;
WAVEFORMATEX *waveformat = NULL;
SDL_AudioFormat test_format;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
SDL_AudioFormat wasapi_format = 0;
SDL_bool valid_format = SDL_FALSE;
HRESULT ret = S_OK;
DWORD streamflags = 0;
@@ -542,15 +543,17 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
/* Make sure we have a valid format that we can convert to whatever WASAPI wants. */
wasapi_format = WaveFormatToSDLFormat(waveformat);
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
while ((!valid_format) && (test_format)) {
if (test_format == wasapi_format) {
this->spec.format = test_format;
valid_format = SDL_TRUE;
break;
}
test_format = SDL_NextAudioFormat();
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "wasapi");
if (!valid_format) {
return SDL_SetError("WASAPI: Unsupported audio format");
}
ret = IAudioClient_GetDevicePeriod(client, &default_period, NULL);
@@ -558,16 +561,12 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret);
}
#if 1 /* we're getting reports that WASAPI's resampler introduces distortions, so it's disabled for now. --ryan. */
this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in, if necessary. */
#else
/* favor WASAPI's resampler over our own */
if (this->spec.freq != waveformat->nSamplesPerSec) {
streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY);
waveformat->nSamplesPerSec = this->spec.freq;
waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8);
}
#endif
streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
ret = IAudioClient_Initialize(client, sharemode, streamflags, 0, 0, waveformat, NULL);
@@ -632,7 +631,9 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
}
if (updatestream) {
return UpdateAudioStream(this, &oldspec);
if (UpdateAudioStream(this, &oldspec) == -1) {
return -1;
}
}
return 0; /* good to go. */
@@ -640,9 +641,9 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
static int
WASAPI_OpenDevice(_THIS, const char *devname)
WASAPI_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
LPCWSTR devid = (LPCWSTR) this->handle;
LPCWSTR devid = (LPCWSTR) handle;
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
@@ -655,7 +656,7 @@ WASAPI_OpenDevice(_THIS, const char *devname)
WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */
if (!devid) { /* is default device? */
this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration);
this->hidden->default_device_generation = SDL_AtomicGet(iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration);
} else {
this->hidden->devid = SDL_wcsdup(devid);
if (!this->hidden->devid) {
@@ -690,6 +691,12 @@ WASAPI_ThreadDeinit(_THIS)
WASAPI_PlatformThreadDeinit(this);
}
void
WASAPI_BeginLoopIteration(_THIS)
{
/* no-op. */
}
static void
WASAPI_Deinitialize(void)
{
@@ -706,20 +713,21 @@ WASAPI_Deinitialize(void)
deviceid_list = NULL;
}
static SDL_bool
static int
WASAPI_Init(SDL_AudioDriverImpl * impl)
{
SDL_AtomicSet(&WASAPI_DefaultPlaybackGeneration, 1);
SDL_AtomicSet(&WASAPI_DefaultCaptureGeneration, 1);
if (WASAPI_PlatformInit() == -1) {
return SDL_FALSE;
return 0;
}
/* Set the function pointers */
impl->DetectDevices = WASAPI_DetectDevices;
impl->ThreadInit = WASAPI_ThreadInit;
impl->ThreadDeinit = WASAPI_ThreadDeinit;
impl->BeginLoopIteration = WASAPI_BeginLoopIteration;
impl->OpenDevice = WASAPI_OpenDevice;
impl->PlayDevice = WASAPI_PlayDevice;
impl->WaitDevice = WASAPI_WaitDevice;
@@ -728,13 +736,13 @@ WASAPI_Init(SDL_AudioDriverImpl * impl)
impl->FlushCapture = WASAPI_FlushCapture;
impl->CloseDevice = WASAPI_CloseDevice;
impl->Deinitialize = WASAPI_Deinitialize;
impl->HasCaptureSupport = SDL_TRUE;
impl->HasCaptureSupport = 1;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap WASAPI_bootstrap = {
"wasapi", "WASAPI", WASAPI_Init, SDL_FALSE
"wasapi", "WASAPI", WASAPI_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_WASAPI */

View File

@@ -74,6 +74,7 @@ int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery);
void WASAPI_PlatformThreadInit(_THIS);
void WASAPI_PlatformThreadDeinit(_THIS);
void WASAPI_PlatformDeleteActivationHandler(void *handler);
void WASAPI_BeginLoopIteration(_THIS);
#ifdef __cplusplus
}

View File

@@ -362,7 +362,7 @@ typedef struct
WAVEFORMATEXTENSIBLE fmt;
} EndpointItem;
static int SDLCALL sort_endpoints(const void *_a, const void *_b)
static int sort_endpoints(const void *_a, const void *_b)
{
LPWSTR a = ((const EndpointItem *) _a)->devid;
LPWSTR b = ((const EndpointItem *) _b)->devid;

View File

@@ -283,11 +283,10 @@ PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture)
}
static int
WINMM_OpenDevice(_THIS, const char *devname)
WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
SDL_AudioFormat test_format;
SDL_bool iscapture = this->iscapture;
void *handle = this->handle;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
int valid_datatype = 0;
MMRESULT result;
WAVEFORMATEX waveformat;
UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */
@@ -314,7 +313,7 @@ WINMM_OpenDevice(_THIS, const char *devname)
if (this->spec.channels > 2)
this->spec.channels = 2; /* !!! FIXME: is this right? */
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
while ((!valid_datatype) && (test_format)) {
switch (test_format) {
case AUDIO_U8:
case AUDIO_S16:
@@ -322,17 +321,20 @@ WINMM_OpenDevice(_THIS, const char *devname)
case AUDIO_F32:
this->spec.format = test_format;
if (PrepWaveFormat(this, devId, &waveformat, iscapture)) {
break;
valid_datatype = 1;
} else {
test_format = SDL_NextAudioFormat();
}
continue;
break;
default:
continue;
test_format = SDL_NextAudioFormat();
break;
}
break;
}
if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "winmm");
if (!valid_datatype) {
return SDL_SetError("Unsupported audio format");
}
/* Update the fragment size as size in bytes */
@@ -432,7 +434,7 @@ WINMM_OpenDevice(_THIS, const char *devname)
return 0; /* Ready to go! */
}
static SDL_bool
static int
WINMM_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -447,11 +449,11 @@ WINMM_Init(SDL_AudioDriverImpl * impl)
impl->HasCaptureSupport = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
return 1; /* this audio target is available. */
}
AudioBootStrap WINMM_bootstrap = {
"winmm", "Windows Waveform Audio", WINMM_Init, SDL_FALSE
"winmm", "Windows Waveform Audio", WINMM_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_WINMM */

View File

@@ -511,9 +511,8 @@ register_methods(JNIEnv *env, const char *classname, JNINativeMethod *methods, i
/* Library init */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env = NULL;
mJavaVM = vm;
JNIEnv *env = NULL;
if ((*mJavaVM)->GetEnv(mJavaVM, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {
__android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed to get JNI Env");
@@ -1010,7 +1009,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j
{
SDL_LockMutex(Android_ActivityMutex);
#if SDL_VIDEO_OPENGL_EGL
if (Android_Window)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
@@ -1023,7 +1021,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j
/* GL Context handling is done in the event loop because this function is run from the Java thread */
}
#endif
SDL_UnlockMutex(Android_ActivityMutex);
}
@@ -1054,12 +1051,10 @@ retry:
}
}
#if SDL_VIDEO_OPENGL_EGL
if (data->egl_surface != EGL_NO_SURFACE) {
SDL_EGL_DestroySurface(_this, data->egl_surface);
data->egl_surface = EGL_NO_SURFACE;
}
#endif
if (data->native_window) {
ANativeWindow_release(data->native_window);
@@ -2131,15 +2126,6 @@ void Android_JNI_HapticStop(int device_id)
/* See SDLActivity.java for constants. */
#define COMMAND_SET_KEEP_SCREEN_ON 5
int SDL_AndroidSendMessage(Uint32 command, int param)
{
if (command >= 0x8000) {
return Android_JNI_SendMessage(command, param);
}
return -1;
}
/* sends message to be handled on the UI event dispatch thread */
int Android_JNI_SendMessage(int command, int param)
{
@@ -2554,7 +2540,6 @@ SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled)
SDL_bool Android_JNI_RequestPermission(const char *permission)
{
JNIEnv *env = Android_JNI_GetEnv();
jstring jpermission;
const int requestCode = 1;
/* Wait for any pending request on another thread */
@@ -2563,7 +2548,7 @@ SDL_bool Android_JNI_RequestPermission(const char *permission)
}
SDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE);
jpermission = (*env)->NewStringUTF(env, permission);
jstring jpermission = (*env)->NewStringUTF(env, permission);
(*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode);
(*env)->DeleteLocalRef(env, jpermission);

View File

@@ -22,7 +22,6 @@
#include "SDL_hints.h"
#include "SDL_dbus.h"
#include "SDL_atomic.h"
#include "../../stdlib/SDL_vacopy.h"
#if SDL_USE_LIBDBUS
/* we never link directly to libdbus. */

View File

@@ -85,22 +85,14 @@ GetAppName()
}
static size_t
Fcitx_GetPreeditString(SDL_DBusContext *dbus,
DBusMessage *msg,
char **ret,
Sint32 *start_pos,
Sint32 *end_pos)
{
Fcitx_GetPreeditString(SDL_DBusContext *dbus, DBusMessage *msg, char **ret) {
char *text = NULL, *subtext;
size_t text_bytes = 0;
DBusMessageIter iter, array, sub;
Sint32 p_start_pos = -1;
Sint32 p_end_pos = -1;
dbus->message_iter_init(msg, &iter);
/* Message type is a(si)i, we only need string part */
if (dbus->message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
size_t pos = 0;
/* First pass: calculate string length */
dbus->message_iter_recurse(&iter, &array);
while (dbus->message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
@@ -111,29 +103,7 @@ Fcitx_GetPreeditString(SDL_DBusContext *dbus,
text_bytes += SDL_strlen(subtext);
}
}
dbus->message_iter_next(&sub);
if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_INT32 && p_end_pos == -1) {
/* Type is a bit field defined as follows: */
/* bit 3: Underline, bit 4: HighLight, bit 5: DontCommit, */
/* bit 6: Bold, bit 7: Strike, bit 8: Italic */
Sint32 type;
dbus->message_iter_get_basic(&sub, &type);
/* We only consider highlight */
if (type & (1 << 4)) {
if (p_start_pos == -1) {
p_start_pos = pos;
}
} else if (p_start_pos != -1 && p_end_pos == -1) {
p_end_pos = pos;
}
}
dbus->message_iter_next(&array);
if (subtext && *subtext) {
pos += SDL_utf8strlen(subtext);
}
}
if (p_start_pos != -1 && p_end_pos == -1) {
p_end_pos = pos;
}
if (text_bytes) {
text = SDL_malloc(text_bytes + 1);
@@ -159,32 +129,10 @@ Fcitx_GetPreeditString(SDL_DBusContext *dbus,
text_bytes = 0;
}
}
*ret = text;
*start_pos = p_start_pos;
*end_pos = p_end_pos;
*ret= text;
return text_bytes;
}
static Sint32
Fcitx_GetPreeditCursorByte(SDL_DBusContext *dbus, DBusMessage *msg)
{
Sint32 byte = -1;
DBusMessageIter iter;
dbus->message_iter_init(msg, &iter);
dbus->message_iter_next(&iter);
if (dbus->message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
return -1;
}
dbus->message_iter_get_basic(&iter, &byte);
return byte;
}
static DBusHandlerResult
DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
{
@@ -214,28 +162,20 @@ DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "UpdateFormattedPreedit")) {
char *text = NULL;
Sint32 start_pos, end_pos;
size_t text_bytes = Fcitx_GetPreeditString(dbus, msg, &text, &start_pos, &end_pos);
size_t text_bytes = Fcitx_GetPreeditString(dbus, msg, &text);
if (text_bytes) {
if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE)) {
if (start_pos == -1) {
Sint32 byte_pos = Fcitx_GetPreeditCursorByte(dbus, msg);
start_pos = byte_pos >= 0 ? SDL_utf8strnlen(text, byte_pos) : -1;
}
SDL_SendEditingText(text, start_pos, end_pos >= 0 ? end_pos - start_pos : -1);
} else {
char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
size_t i = 0;
size_t cursor = 0;
while (i < text_bytes) {
const size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf));
const size_t chars = SDL_utf8strlen(buf);
char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
size_t i = 0;
size_t cursor = 0;
SDL_SendEditingText(buf, cursor, chars);
while (i < text_bytes) {
const size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf));
const size_t chars = SDL_utf8strlen(buf);
i += sz;
cursor += chars;
}
SDL_SendEditingText(buf, cursor, chars);
i += sz;
cursor += chars;
}
SDL_free(text);
} else {
@@ -399,11 +339,11 @@ SDL_Fcitx_Reset(void)
}
SDL_bool
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
{
Uint32 mod_state = Fcitx_ModState();
Uint32 state = Fcitx_ModState();
Uint32 handled = SDL_FALSE;
Uint32 is_release = (state == SDL_RELEASED);
Uint32 is_release = SDL_FALSE;
Uint32 event_time = 0;
if (!fcitx_client.ic_path) {
@@ -411,7 +351,7 @@ SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
}
if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent",
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mod_state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) {
if (handled) {
SDL_Fcitx_UpdateTextRect(NULL);

View File

@@ -31,7 +31,7 @@ extern SDL_bool SDL_Fcitx_Init(void);
extern void SDL_Fcitx_Quit(void);
extern void SDL_Fcitx_SetFocus(SDL_bool focused);
extern void SDL_Fcitx_Reset(void);
extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect);
extern void SDL_Fcitx_PumpEvents(void);

View File

@@ -22,7 +22,6 @@
#ifdef HAVE_IBUS_IBUS_H
#include "SDL.h"
#include "SDL_hints.h"
#include "SDL_syswm.h"
#include "SDL_ibus.h"
#include "SDL_dbus.h"
@@ -67,217 +66,107 @@ IBus_ModState(void)
return ibus_mods;
}
static SDL_bool
IBus_EnterVariant(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus,
DBusMessageIter *inside, const char * struct_id, size_t id_size)
{
DBusMessageIter sub;
if (dbus->message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT) {
return SDL_FALSE;
}
dbus->message_iter_recurse(iter, &sub);
if (dbus->message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) {
return SDL_FALSE;
}
dbus->message_iter_recurse(&sub, inside);
if (dbus->message_iter_get_arg_type(inside) != DBUS_TYPE_STRING) {
return SDL_FALSE;
}
dbus->message_iter_get_basic(inside, &struct_id);
if (!struct_id || SDL_strncmp(struct_id, struct_id, id_size) != 0) {
return SDL_FALSE;
}
return SDL_TRUE;
}
static SDL_bool
IBus_GetDecorationPosition(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus,
Uint32 *start_pos, Uint32 *end_pos)
{
DBusMessageIter sub1, sub2, array;
if (!IBus_EnterVariant(conn, iter, dbus, &sub1, "IBusText", sizeof("IBusText"))) {
return SDL_FALSE;
}
dbus->message_iter_next(&sub1);
dbus->message_iter_next(&sub1);
dbus->message_iter_next(&sub1);
if (!IBus_EnterVariant(conn, &sub1, dbus, &sub2, "IBusAttrList", sizeof("IBusAttrList"))) {
return SDL_FALSE;
}
dbus->message_iter_next(&sub2);
dbus->message_iter_next(&sub2);
if (dbus->message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY) {
return SDL_FALSE;
}
dbus->message_iter_recurse(&sub2, &array);
while (dbus->message_iter_get_arg_type(&array) == DBUS_TYPE_VARIANT) {
DBusMessageIter sub;
if (IBus_EnterVariant(conn, &array, dbus, &sub, "IBusAttribute", sizeof("IBusAttribute"))) {
Uint32 type;
dbus->message_iter_next(&sub);
dbus->message_iter_next(&sub);
/* From here on, the structure looks like this: */
/* Uint32 type: 1=underline, 2=foreground, 3=background */
/* Uint32 value: for underline it's 0=NONE, 1=SINGLE, 2=DOUBLE, */
/* 3=LOW, 4=ERROR */
/* for foreground and background it's a color */
/* Uint32 start_index: starting position for the style (utf8-char) */
/* Uint32 end_index: end position for the style (utf8-char) */
dbus->message_iter_get_basic(&sub, &type);
/* We only use the background type to determine the selection */
if (type == 3) {
Uint32 start = -1;
dbus->message_iter_next(&sub);
dbus->message_iter_next(&sub);
if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32) {
dbus->message_iter_get_basic(&sub, &start);
dbus->message_iter_next(&sub);
if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32) {
dbus->message_iter_get_basic(&sub, end_pos);
*start_pos = start;
return SDL_TRUE;
}
}
}
}
dbus->message_iter_next(&array);
}
return SDL_FALSE;
}
static const char *
IBus_GetVariantText(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus)
{
/* The text we need is nested weirdly, use dbus-monitor to see the structure better */
const char *text = NULL;
DBusMessageIter sub;
const char *struct_id = NULL;
DBusMessageIter sub1, sub2;
if (!IBus_EnterVariant(conn, iter, dbus, &sub, "IBusText", sizeof("IBusText"))) {
if (dbus->message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT) {
return NULL;
}
dbus->message_iter_next(&sub);
dbus->message_iter_next(&sub);
if (dbus->message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
dbus->message_iter_recurse(iter, &sub1);
if (dbus->message_iter_get_arg_type(&sub1) != DBUS_TYPE_STRUCT) {
return NULL;
}
dbus->message_iter_get_basic(&sub, &text);
dbus->message_iter_recurse(&sub1, &sub2);
if (dbus->message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) {
return NULL;
}
dbus->message_iter_get_basic(&sub2, &struct_id);
if (!struct_id || SDL_strncmp(struct_id, "IBusText", sizeof("IBusText")) != 0) {
return NULL;
}
dbus->message_iter_next(&sub2);
dbus->message_iter_next(&sub2);
if (dbus->message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) {
return NULL;
}
dbus->message_iter_get_basic(&sub2, &text);
return text;
}
static SDL_bool
IBus_GetVariantCursorPos(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus,
Uint32 *pos)
{
dbus->message_iter_next(iter);
if (dbus->message_iter_get_arg_type(iter) != DBUS_TYPE_UINT32) {
return SDL_FALSE;
}
dbus->message_iter_get_basic(iter, pos);
return SDL_TRUE;
}
static DBusHandlerResult
IBus_MessageHandler(DBusConnection *conn, DBusMessage *msg, void *user_data)
{
SDL_DBusContext *dbus = (SDL_DBusContext *)user_data;
if (dbus->message_is_signal(msg, IBUS_INPUT_INTERFACE, "CommitText")) {
DBusMessageIter iter;
const char *text;
dbus->message_iter_init(msg, &iter);
text = IBus_GetVariantText(conn, &iter, dbus);
if (text && *text) {
char buf[SDL_TEXTINPUTEVENT_TEXT_SIZE];
size_t text_bytes = SDL_strlen(text), i = 0;
while (i < text_bytes) {
size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf));
SDL_SendKeyboardText(buf);
i += sz;
}
}
return DBUS_HANDLER_RESULT_HANDLED;
}
if (dbus->message_is_signal(msg, IBUS_INPUT_INTERFACE, "UpdatePreeditText")) {
DBusMessageIter iter;
const char *text;
dbus->message_iter_init(msg, &iter);
text = IBus_GetVariantText(conn, &iter, dbus);
if (text) {
if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE)) {
Uint32 pos, start_pos, end_pos;
SDL_bool has_pos = SDL_FALSE;
SDL_bool has_dec_pos = SDL_FALSE;
char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
size_t text_bytes = SDL_strlen(text), i = 0;
size_t cursor = 0;
do {
const size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf));
const size_t chars = SDL_utf8strlen(buf);
SDL_SendEditingText(buf, cursor, chars);
dbus->message_iter_init(msg, &iter);
has_dec_pos = IBus_GetDecorationPosition(conn, &iter, dbus, &start_pos, &end_pos);
if (!has_dec_pos)
{
dbus->message_iter_init(msg, &iter);
has_pos = IBus_GetVariantCursorPos(conn, &iter, dbus, &pos);
}
if(has_dec_pos) {
SDL_SendEditingText(text, start_pos, end_pos - start_pos);
} else if (has_pos) {
SDL_SendEditingText(text, pos, -1);
} else {
SDL_SendEditingText(text, -1, -1);
}
} else {
char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
size_t text_bytes = SDL_strlen(text), i = 0;
size_t cursor = 0;
do {
const size_t sz = SDL_utf8strlcpy(buf, text+i, sizeof(buf));
const size_t chars = SDL_utf8strlen(buf);
SDL_SendEditingText(buf, cursor, chars);
i += sz;
cursor += chars;
} while (i < text_bytes);
}
i += sz;
cursor += chars;
} while (i < text_bytes);
}
SDL_IBus_UpdateTextRect(NULL);
return DBUS_HANDLER_RESULT_HANDLED;
}
if (dbus->message_is_signal(msg, IBUS_INPUT_INTERFACE, "HidePreeditText")) {
SDL_SendEditingText("", 0, 0);
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
@@ -614,20 +503,15 @@ SDL_IBus_Reset(void)
}
SDL_bool
SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
{
Uint32 result = 0;
SDL_DBusContext *dbus = SDL_DBus_GetContext();
if (IBus_CheckConnection(dbus)) {
Uint32 mods = IBus_ModState();
Uint32 ibus_keycode = keycode - 8;
if (state == SDL_RELEASED) {
mods |= (1 << 30); // IBUS_RELEASE_MASK
}
if (!SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &ibus_keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) {
result = 0;
}

View File

@@ -41,7 +41,7 @@ extern void SDL_IBus_Reset(void);
/* Sends a keypress event to IBus, returns SDL_TRUE if IBus used this event to
update its candidate list or change input methods. PumpEvents should be
called some time after this, to recieve the TextInput / TextEditing event back. */
extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
/* Update the position of IBus' candidate list. If rect is NULL then this will
just reposition it relative to the focused window's new position. */

View File

@@ -27,7 +27,7 @@ typedef SDL_bool (*_SDL_IME_Init)(void);
typedef void (*_SDL_IME_Quit)(void);
typedef void (*_SDL_IME_SetFocus)(SDL_bool);
typedef void (*_SDL_IME_Reset)(void);
typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32, Uint8 state);
typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32);
typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *);
typedef void (*_SDL_IME_PumpEvents)(void);
@@ -127,10 +127,10 @@ SDL_IME_Reset(void)
}
SDL_bool
SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
{
if (SDL_IME_ProcessKeyEvent_Real)
return SDL_IME_ProcessKeyEvent_Real(keysym, keycode, state);
return SDL_IME_ProcessKeyEvent_Real(keysym, keycode);
return SDL_FALSE;
}

View File

@@ -31,7 +31,7 @@ extern SDL_bool SDL_IME_Init(void);
extern void SDL_IME_Quit(void);
extern void SDL_IME_SetFocus(SDL_bool focused);
extern void SDL_IME_Reset(void);
extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
extern void SDL_IME_UpdateTextRect(SDL_Rect *rect);
extern void SDL_IME_PumpEvents(void);

View File

@@ -394,7 +394,6 @@ typedef struct {
unsigned int text_len;
keysym_t composebuffer[2];
unsigned char composelen;
int type;
} SDL_WSCONS_input_data;
static SDL_WSCONS_input_data* inputs[4] = {NULL, NULL, NULL, NULL};
@@ -433,7 +432,6 @@ static SDL_WSCONS_input_data* SDL_WSCONS_Init_Keyboard(const char* dev)
RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETLEDS, &input->ledstate));
input->origledstate = input->ledstate;
RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETENCODING, &input->encoding));
RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GTYPE, &input->type));
#ifdef WSKBDIO_SETVERSION
RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_SETVERSION, &version));
#endif
@@ -727,12 +725,7 @@ static void updateKeyboard(SDL_WSCONS_input_data* input)
}
break;
}
if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7)
SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value);
else
Translate_to_keycode(input, type, events[i].value);
Translate_to_keycode(input, type, events[i].value);
if (type == WSCONS_EVENT_KEY_UP) continue;
if (IS_ALTGR_MODE && !IS_CONTROL_HELD)

View File

@@ -46,17 +46,17 @@ extern size_t _System os2_iconv (iconv_t cd,
char **outbuf, size_t *outbytesleft);
extern int _System os2_iconv_close (iconv_t cd);
/* Functions pointers */
/* Functions pointers types */
typedef iconv_t (_System *FNICONV_OPEN)(const char*, const char*);
typedef size_t (_System *FNICONV) (iconv_t, char **, size_t *, char **, size_t *);
typedef int (_System *FNICONV_CLOSE)(iconv_t);
/* Used DLL module handle */
static HMODULE hmIconv = NULLHANDLE;
static FNICONV_OPEN fn_iconv_open = os2_iconv_open;
static FNICONV fn_iconv = os2_iconv;
static FNICONV_CLOSE fn_iconv_close = os2_iconv_close;
static int geniconv_init = 0;
/* Functions pointers */
static FNICONV_OPEN fn_iconv_open = NULL;
static FNICONV fn_iconv = NULL;
static FNICONV_CLOSE fn_iconv_close = NULL;
static BOOL _loadDLL(const char *dllname,
@@ -102,12 +102,10 @@ static BOOL _loadDLL(const char *dllname,
static void _init(void)
{
if (geniconv_init) {
if (fn_iconv_open != NULL) {
return; /* Already initialized */
}
geniconv_init = 1;
/* Try to load kiconv.dll, iconv2.dll or iconv.dll */
if (!_loadDLL("KICONV", "_libiconv_open", "_libiconv", "_libiconv_close") &&
!_loadDLL("ICONV2", "_libiconv_open", "_libiconv", "_libiconv_close") &&
@@ -125,19 +123,16 @@ static void _init(void)
* ----------------
*/
/* function to unload the used iconv dynamic library */
/* Non-standard function for iconv to unload the used dynamic library */
void libiconv_clean(void)
{
geniconv_init = 0;
/* reset the function pointers. */
fn_iconv_open = os2_iconv_open;
fn_iconv = os2_iconv;
fn_iconv_close = os2_iconv_close;
if (hmIconv != NULLHANDLE) {
DosFreeModule(hmIconv);
hmIconv = NULLHANDLE;
fn_iconv_open = NULL;
fn_iconv = NULL;
fn_iconv_close = NULL;
}
}

View File

@@ -27,6 +27,8 @@
HidD_GetString_t SDL_HidD_GetManufacturerString;
HidD_GetString_t SDL_HidD_GetProductString;
HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData;
HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData;
HidP_GetCaps_t SDL_HidP_GetCaps;
HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps;
HidP_GetValueCaps_t SDL_HidP_GetValueCaps;
@@ -56,13 +58,15 @@ WIN_LoadHIDDLL(void)
SDL_HidD_GetManufacturerString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetManufacturerString");
SDL_HidD_GetProductString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetProductString");
SDL_HidD_GetPreparsedData = (HidD_GetPreparsedData_t)GetProcAddress(s_pHIDDLL, "HidD_GetPreparsedData");
SDL_HidD_FreePreparsedData = (HidD_FreePreparsedData_t)GetProcAddress(s_pHIDDLL, "HidD_FreePreparsedData");
SDL_HidP_GetCaps = (HidP_GetCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetCaps");
SDL_HidP_GetButtonCaps = (HidP_GetButtonCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetButtonCaps");
SDL_HidP_GetValueCaps = (HidP_GetValueCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetValueCaps");
SDL_HidP_MaxDataListLength = (HidP_MaxDataListLength_t)GetProcAddress(s_pHIDDLL, "HidP_MaxDataListLength");
SDL_HidP_GetData = (HidP_GetData_t)GetProcAddress(s_pHIDDLL, "HidP_GetData");
if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString ||
!SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps ||
if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString || !SDL_HidD_GetPreparsedData ||
!SDL_HidD_FreePreparsedData || !SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps ||
!SDL_HidP_GetValueCaps || !SDL_HidP_MaxDataListLength || !SDL_HidP_GetData) {
WIN_UnloadHIDDLL();
return -1;

View File

@@ -183,6 +183,8 @@ extern int WIN_LoadHIDDLL(void);
extern void WIN_UnloadHIDDLL(void);
typedef BOOLEAN (WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
typedef BOOLEAN (WINAPI *HidD_GetPreparsedData_t)(HANDLE HidDeviceObject, PHIDP_PREPARSED_DATA *PreparsedData);
typedef BOOLEAN (WINAPI *HidD_FreePreparsedData_t)(PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS (WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities);
typedef NTSTATUS (WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS (WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
@@ -191,6 +193,8 @@ typedef NTSTATUS (WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DAT
extern HidD_GetString_t SDL_HidD_GetManufacturerString;
extern HidD_GetString_t SDL_HidD_GetProductString;
extern HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData;
extern HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData;
extern HidP_GetCaps_t SDL_HidP_GetCaps;
extern HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps;
extern HidP_GetValueCaps_t SDL_HidP_GetValueCaps;

View File

@@ -25,15 +25,7 @@
#include "SDL_windows.h"
#include "SDL_error.h"
#include <objbase.h> /* for CoInitialize/CoUninitialize (Win32 only) */
#if defined(HAVE_ROAPI_H)
#include <roapi.h> /* For RoInitialize/RoUninitialize (Win32 only) */
#else
typedef enum RO_INIT_TYPE {
RO_INIT_SINGLETHREADED = 0,
RO_INIT_MULTITHREADED = 1
} RO_INIT_TYPE;
#endif
#include <objbase.h> /* for CoInitialize/CoUninitialize (Win32 only) */
#ifndef _WIN32_WINNT_VISTA
#define _WIN32_WINNT_VISTA 0x0600
@@ -45,10 +37,6 @@ typedef enum RO_INIT_TYPE {
#define _WIN32_WINNT_WIN8 0x0602
#endif
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
/* Sets an error message based on an HRESULT */
int
@@ -120,65 +108,6 @@ WIN_CoUninitialize(void)
#endif
}
#ifndef __WINRT__
void *
WIN_LoadComBaseFunction(const char *name)
{
static SDL_bool s_bLoaded;
static HMODULE s_hComBase;
if (!s_bLoaded) {
s_hComBase = LoadLibraryEx(TEXT("combase.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
s_bLoaded = SDL_TRUE;
}
if (s_hComBase) {
return GetProcAddress(s_hComBase, name);
} else {
return NULL;
}
}
#endif
HRESULT
WIN_RoInitialize(void)
{
#ifdef __WINRT__
return S_OK;
#else
typedef HRESULT (WINAPI *RoInitialize_t)(RO_INIT_TYPE initType);
RoInitialize_t RoInitializeFunc = (RoInitialize_t)WIN_LoadComBaseFunction("RoInitialize");
if (RoInitializeFunc) {
/* RO_INIT_SINGLETHREADED is equivalent to COINIT_APARTMENTTHREADED */
HRESULT hr = RoInitializeFunc(RO_INIT_SINGLETHREADED);
if (hr == RPC_E_CHANGED_MODE) {
hr = RoInitializeFunc(RO_INIT_MULTITHREADED);
}
/* S_FALSE means success, but someone else already initialized. */
/* You still need to call RoUninitialize in this case! */
if (hr == S_FALSE) {
return S_OK;
}
return hr;
} else {
return E_NOINTERFACE;
}
#endif
}
void
WIN_RoUninitialize(void)
{
#ifndef __WINRT__
typedef void (WINAPI *RoUninitialize_t)(void);
RoUninitialize_t RoUninitializeFunc = (RoUninitialize_t)WIN_LoadComBaseFunction("RoUninitialize");
if (RoUninitializeFunc) {
RoUninitializeFunc();
}
#endif
}
#ifndef __WINRT__
static BOOL
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)

View File

@@ -30,14 +30,8 @@
#ifndef UNICODE
#define UNICODE 1
#endif
#undef WINVER
#define WINVER 0x0501
#undef _WIN32_WINNT
#if !defined(SDL_VIDEO_RENDER_D3D12)
#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */
#else
#define _WIN32_WINNT 0xA00 /* For D3D12, 0xA00 is required */
#endif
#endif
#include <windows.h>
@@ -69,19 +63,10 @@ extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
/* Sets an error message based on GetLastError(). Always return -1. */
extern int WIN_SetError(const char *prefix);
#if !defined(__WINRT__)
/* Load a function from combase.dll */
void *WIN_LoadComBaseFunction(const char *name);
#endif
/* Wrap up the oddities of CoInitialize() into a common function. */
extern HRESULT WIN_CoInitialize(void);
extern void WIN_CoUninitialize(void);
/* Wrap up the oddities of RoInitialize() into a common function. */
extern HRESULT WIN_RoInitialize(void);
extern void WIN_RoUninitialize(void);
/* Returns SDL_TRUE if we're running on Windows Vista and newer */
extern BOOL WIN_IsWindowsVistaOrGreater(void);

View File

@@ -23,6 +23,8 @@
#include "SDL_xinput.h"
#ifdef HAVE_XINPUT_H
XInputGetState_t SDL_XInputGetState = NULL;
XInputSetState_t SDL_XInputSetState = NULL;
XInputGetCapabilities_t SDL_XInputGetCapabilities = NULL;
@@ -135,5 +137,6 @@ WIN_UnloadXInputDLL(void)
}
#endif /* __WINRT__ */
#endif /* HAVE_XINPUT_H */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -23,11 +23,10 @@
#ifndef SDL_xinput_h_
#define SDL_xinput_h_
#include "SDL_windows.h"
#ifdef HAVE_XINPUT_H
#include "SDL_windows.h"
#include <xinput.h>
#endif /* HAVE_XINPUT_H */
#ifndef XUSER_MAX_COUNT
#define XUSER_MAX_COUNT 4
@@ -73,53 +72,6 @@
#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
#endif
#ifndef XINPUT_FLAG_GAMEPAD
#define XINPUT_FLAG_GAMEPAD 0x01
#endif
#ifndef XINPUT_GAMEPAD_DPAD_UP
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
#endif
#ifndef XINPUT_GAMEPAD_DPAD_DOWN
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
#endif
#ifndef XINPUT_GAMEPAD_DPAD_LEFT
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
#endif
#ifndef XINPUT_GAMEPAD_DPAD_RIGHT
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
#endif
#ifndef XINPUT_GAMEPAD_START
#define XINPUT_GAMEPAD_START 0x0010
#endif
#ifndef XINPUT_GAMEPAD_BACK
#define XINPUT_GAMEPAD_BACK 0x0020
#endif
#ifndef XINPUT_GAMEPAD_LEFT_THUMB
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
#endif
#ifndef XINPUT_GAMEPAD_RIGHT_THUMB
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
#endif
#ifndef XINPUT_GAMEPAD_LEFT_SHOULDER
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
#endif
#ifndef XINPUT_GAMEPAD_RIGHT_SHOULDER
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
#endif
#ifndef XINPUT_GAMEPAD_A
#define XINPUT_GAMEPAD_A 0x1000
#endif
#ifndef XINPUT_GAMEPAD_B
#define XINPUT_GAMEPAD_B 0x2000
#endif
#ifndef XINPUT_GAMEPAD_X
#define XINPUT_GAMEPAD_X 0x4000
#endif
#ifndef XINPUT_GAMEPAD_Y
#define XINPUT_GAMEPAD_Y 0x8000
#endif
#ifndef XINPUT_GAMEPAD_GUIDE
#define XINPUT_GAMEPAD_GUIDE 0x0400
#endif
@@ -177,36 +129,6 @@ typedef struct
BYTE BatteryLevel;
} XINPUT_BATTERY_INFORMATION_EX;
#ifndef HAVE_XINPUT_H
typedef struct
{
WORD wButtons;
BYTE bLeftTrigger;
BYTE bRightTrigger;
SHORT sThumbLX;
SHORT sThumbLY;
SHORT sThumbRX;
SHORT sThumbRY;
} XINPUT_GAMEPAD;
typedef struct
{
WORD wLeftMotorSpeed;
WORD wRightMotorSpeed;
} XINPUT_VIBRATION;
typedef struct
{
BYTE Type;
BYTE SubType;
WORD Flags;
XINPUT_GAMEPAD Gamepad;
XINPUT_VIBRATION Vibration;
} XINPUT_CAPABILITIES;
#endif /* HAVE_XINPUT_H */
/* Forward decl's for XInput API's we load dynamically and use if available */
typedef DWORD (WINAPI *XInputGetState_t)
(
@@ -248,6 +170,8 @@ extern DWORD SDL_XInputVersion; /* ((major << 16) & 0xFF00) | (minor & 0xFF) */
#define XINPUTGETCAPABILITIES SDL_XInputGetCapabilities
#define XINPUTGETBATTERYINFORMATION SDL_XInputGetBatteryInformation
#endif /* HAVE_XINPUT_H */
#endif /* SDL_xinput_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -115,7 +115,7 @@ SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAs
// Make sure we have a valid XAML element (to draw onto):
if ( ! backgroundPanelAsIInspectable) {
return SDL_InvalidParamError("backgroundPanelAsIInspectable");
return SDL_SetError("'backgroundPanelAsIInspectable' can't be NULL");
}
Platform::Object ^ backgroundPanel = reinterpret_cast<Object ^>((IInspectable *) backgroundPanelAsIInspectable);

View File

@@ -98,10 +98,6 @@
#include <swis.h>
#endif
#ifdef __PS2__
#include <kernel.h>
#endif
#define CPU_HAS_RDTSC (1 << 0)
#define CPU_HAS_ALTIVEC (1 << 1)
#define CPU_HAS_MMX (1 << 2)
@@ -116,12 +112,6 @@
#define CPU_HAS_NEON (1 << 11)
#define CPU_HAS_AVX512F (1 << 12)
#define CPU_HAS_ARM_SIMD (1 << 13)
#define CPU_HAS_LSX (1 << 14)
#define CPU_HAS_LASX (1 << 15)
#define CPU_CFG2 0x2
#define CPU_CFG2_LSX (1 << 6)
#define CPU_CFG2_LASX (1 << 7)
#if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__ && !__FreeBSD__
/* This is the brute force way of detecting instruction sets...
@@ -140,7 +130,7 @@ CPU_haveCPUID(void)
{
int has_CPUID = 0;
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */
#ifndef SDL_CPUINFO_DISABLED
#if (defined(__GNUC__) || defined(__llvm__)) && defined(__i386__)
__asm__ (
@@ -229,7 +219,7 @@ done:
);
#endif
#endif
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */
return has_CPUID;
}
@@ -518,23 +508,6 @@ CPU_haveNEON(void)
#endif
}
static int
CPU_readCPUCFG(void)
{
uint32_t cfg2 = 0;
#if defined __loongarch__
__asm__ volatile(
"cpucfg %0, %1 \n\t"
: "+&r"(cfg2)
: "r"(CPU_CFG2)
);
#endif
return cfg2;
}
#define CPU_haveLSX() (CPU_readCPUCFG() & CPU_CFG2_LSX)
#define CPU_haveLASX() (CPU_readCPUCFG() & CPU_CFG2_LASX)
#if defined(__e2k__)
inline int
CPU_have3DNow(void)
@@ -912,14 +885,6 @@ SDL_GetCPUFeatures(void)
SDL_CPUFeatures |= CPU_HAS_NEON;
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
}
if (CPU_haveLSX()) {
SDL_CPUFeatures |= CPU_HAS_LSX;
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
}
if (CPU_haveLASX()) {
SDL_CPUFeatures |= CPU_HAS_LASX;
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
}
}
return SDL_CPUFeatures;
}
@@ -1009,18 +974,6 @@ SDL_HasNEON(void)
return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON);
}
SDL_bool
SDL_HasLSX(void)
{
return CPU_FEATURE_AVAILABLE(CPU_HAS_LSX);
}
SDL_bool
SDL_HasLASX(void)
{
return CPU_FEATURE_AVAILABLE(CPU_HAS_LASX);
}
static int SDL_SystemRAM = 0;
int
@@ -1085,12 +1038,6 @@ SDL_GetSystemRAM(void)
SDL_SystemRAM = 536870912;
}
#endif
#ifdef __PS2__
if (SDL_SystemRAM <= 0) {
/* PlayStation 2 has 32MiB however there are some special models with 64 and 128 */
SDL_SystemRAM = GetMemorySize();
}
#endif
#endif
}
return SDL_SystemRAM;
@@ -1111,18 +1058,10 @@ void *
SDL_SIMDAlloc(const size_t len)
{
const size_t alignment = SDL_SIMDGetAlignment();
const size_t padding = (alignment - (len % alignment)) % alignment;
const size_t padding = alignment - (len % alignment);
const size_t padded = (padding != alignment) ? (len + padding) : len;
Uint8 *retval = NULL;
Uint8 *ptr;
size_t to_allocate;
/* alignment + padding + sizeof (void *) is bounded (a few hundred
* bytes max), so no need to check for overflow within that argument */
if (SDL_size_add_overflow(len, alignment + padding + sizeof (void *), &to_allocate)) {
return NULL;
}
ptr = (Uint8 *) SDL_malloc(to_allocate);
Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *));
if (ptr) {
/* store the actual allocated pointer right before our aligned pointer. */
retval = ptr + sizeof (void *);
@@ -1136,18 +1075,12 @@ void *
SDL_SIMDRealloc(void *mem, const size_t len)
{
const size_t alignment = SDL_SIMDGetAlignment();
const size_t padding = (alignment - (len % alignment)) % alignment;
const size_t padding = alignment - (len % alignment);
const size_t padded = (padding != alignment) ? (len + padding) : len;
Uint8 *retval = (Uint8*) mem;
void *oldmem = mem;
size_t memdiff = 0, ptrdiff;
Uint8 *ptr;
size_t to_allocate;
/* alignment + padding + sizeof (void *) is bounded (a few hundred
* bytes max), so no need to check for overflow within that argument */
if (SDL_size_add_overflow(len, alignment + padding + sizeof (void *), &to_allocate)) {
return NULL;
}
if (mem) {
void **realptr = (void **) mem;
@@ -1158,7 +1091,7 @@ SDL_SIMDRealloc(void *mem, const size_t len)
memdiff = ((size_t) oldmem) - ((size_t) mem);
}
ptr = (Uint8 *) SDL_realloc(mem, to_allocate);
ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *));
if (ptr == NULL) {
return NULL; /* Out of memory, bail! */
@@ -1223,8 +1156,6 @@ main()
printf("AVX-512F: %d\n", SDL_HasAVX512F());
printf("ARM SIMD: %d\n", SDL_HasARMSIMD());
printf("NEON: %d\n", SDL_HasNEON());
printf("LSX: %d\n", SDL_HasLSX());
printf("LASX: %d\n", SDL_HasLASX());
printf("RAM: %d MB\n", SDL_GetSystemRAM());
return 0;
}

View File

@@ -51,8 +51,6 @@
#define SDL_DYNAMIC_API 0
#elif defined(SDL_BUILDING_WINRT) && SDL_BUILDING_WINRT /* probably not useful on WinRT, given current .dll loading restrictions */
#define SDL_DYNAMIC_API 0
#elif defined(__PS2__) && __PS2__
#define SDL_DYNAMIC_API 0
#elif defined(__PSP__) && __PSP__
#define SDL_DYNAMIC_API 0
#elif defined(__riscos__) && __riscos__ /* probably not useful on RISC OS, since dlopen() can't be used when using static linking. */
@@ -61,8 +59,6 @@
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
#elif defined(__VITA__)
#define SDL_DYNAMIC_API 0 /* vitasdk doesn't support dynamic linking */
#elif defined(__NGAGE__)
#define SDL_DYNAMIC_API 0 /* The N-Gage doesn't support dynamic linking either */
#elif defined(DYNAPI_NEEDS_DLOPEN) && !defined(HAVE_DLOPEN)
#define SDL_DYNAMIC_API 0 /* we need dlopen(), but don't have it.... */
#endif

View File

@@ -439,6 +439,8 @@
#define SDL_iconv_close SDL_iconv_close_REAL
#define SDL_iconv SDL_iconv_REAL
#define SDL_iconv_string SDL_iconv_string_REAL
#define SDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat_REAL
#define SDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom_REAL
#define SDL_CreateRGBSurface SDL_CreateRGBSurface_REAL
#define SDL_CreateRGBSurfaceFrom SDL_CreateRGBSurfaceFrom_REAL
#define SDL_FreeSurface SDL_FreeSurface_REAL
@@ -575,6 +577,7 @@
#define SDL_WarpMouseGlobal SDL_WarpMouseGlobal_REAL
#define SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE_REAL
#define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL
#define SDL_WinRTRunApp SDL_WinRTRunApp_REAL
#define SDL_sqrtf SDL_sqrtf_REAL
#define SDL_tan SDL_tan_REAL
#define SDL_tanf SDL_tanf_REAL
@@ -750,6 +753,7 @@
#define SDL_JoystickDetachVirtual SDL_JoystickDetachVirtual_REAL
#define SDL_JoystickIsVirtual SDL_JoystickIsVirtual_REAL
#define SDL_JoystickSetVirtualAxis SDL_JoystickSetVirtualAxis_REAL
#define SDL_JoystickSetVirtualBall SDL_JoystickSetVirtualBall_REAL
#define SDL_JoystickSetVirtualButton SDL_JoystickSetVirtualButton_REAL
#define SDL_JoystickSetVirtualHat SDL_JoystickSetVirtualHat_REAL
#define SDL_GetErrorMsg SDL_GetErrorMsg_REAL
@@ -851,27 +855,3 @@
#define SDL_GameControllerHasRumbleTriggers SDL_GameControllerHasRumbleTriggers_REAL
#define SDL_hid_ble_scan SDL_hid_ble_scan_REAL
#define SDL_PremultiplyAlpha SDL_PremultiplyAlpha_REAL
#define SDL_AndroidSendMessage SDL_AndroidSendMessage_REAL
#define SDL_GetTouchName SDL_GetTouchName_REAL
#define SDL_ClearComposition SDL_ClearComposition_REAL
#define SDL_IsTextInputShown SDL_IsTextInputShown_REAL
#define SDL_HasIntersectionF SDL_HasIntersectionF_REAL
#define SDL_IntersectFRect SDL_IntersectFRect_REAL
#define SDL_UnionFRect SDL_UnionFRect_REAL
#define SDL_EncloseFPoints SDL_EncloseFPoints_REAL
#define SDL_IntersectFRectAndLine SDL_IntersectFRectAndLine_REAL
#define SDL_RenderGetWindow SDL_RenderGetWindow_REAL
#define SDL_bsearch SDL_bsearch_REAL
#define SDL_GameControllerPathForIndex SDL_GameControllerPathForIndex_REAL
#define SDL_GameControllerPath SDL_GameControllerPath_REAL
#define SDL_JoystickPathForIndex SDL_JoystickPathForIndex_REAL
#define SDL_JoystickPath SDL_JoystickPath_REAL
#define SDL_JoystickAttachVirtualEx SDL_JoystickAttachVirtualEx_REAL
#define SDL_GameControllerGetFirmwareVersion SDL_GameControllerGetFirmwareVersion_REAL
#define SDL_JoystickGetFirmwareVersion SDL_JoystickGetFirmwareVersion_REAL
#define SDL_GUIDToString SDL_GUIDToString_REAL
#define SDL_GUIDFromString SDL_GUIDFromString_REAL
#define SDL_HasLSX SDL_HasLSX_REAL
#define SDL_HasLASX SDL_HasLASX_REAL
#define SDL_RenderGetD3D12Device SDL_RenderGetD3D12Device_REAL
#define SDL_utf8strnlen SDL_utf8strnlen_REAL

View File

@@ -70,7 +70,7 @@ SDL_DYNAPI_PROC(IDirect3DDevice9*,SDL_RenderGetD3D9Device,(SDL_Renderer *a),(a),
#endif
#ifdef __IPHONEOS__
SDL_DYNAPI_PROC(int,SDL_iPhoneSetAnimationCallback,(SDL_Window *a, int b, void (SDLCALL *c)(void *), void *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_iPhoneSetAnimationCallback,(SDL_Window *a, int b, void c, void *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(void,SDL_iPhoneSetEventPump,(SDL_bool a),(a),)
#endif
@@ -408,7 +408,7 @@ SDL_DYNAPI_PROC(void*,SDL_realloc,(void *a, size_t b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_free,(void *a),(a),)
SDL_DYNAPI_PROC(char*,SDL_getenv,(const char *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_setenv,(const char *a, const char *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, int (SDLCALL *d)(const void *, const void *)),(a,b,c,d),)
SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, int (*d)(const void *, const void *)),(a,b,c,d),)
SDL_DYNAPI_PROC(int,SDL_abs,(int a),(a),return)
SDL_DYNAPI_PROC(int,SDL_isdigit,(int a),(a),return)
SDL_DYNAPI_PROC(int,SDL_isspace,(int a),(a),return)
@@ -508,7 +508,7 @@ SDL_DYNAPI_PROC(void,SDL_WaitThread,(SDL_Thread *a, int *b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_DetachThread,(SDL_Thread *a),(a),)
SDL_DYNAPI_PROC(SDL_TLSID,SDL_TLSCreate,(void),(),return)
SDL_DYNAPI_PROC(void*,SDL_TLSGet,(SDL_TLSID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_TLSSet,(SDL_TLSID a, const void *b, void (SDLCALL *c)(void*)),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_TLSSet,(SDL_TLSID a, const void *b, void (*c)(void*)),(a,b,c),return)
SDL_DYNAPI_PROC(Uint32,SDL_GetTicks,(void),(),return)
SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceCounter,(void),(),return)
SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceFrequency,(void),(),return)
@@ -924,31 +924,3 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasRumble,(SDL_GameController *a),(a)
SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasRumbleTriggers,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_hid_ble_scan,(SDL_bool a),(a),)
SDL_DYNAPI_PROC(int,SDL_PremultiplyAlpha,(int a, int b, Uint32 c, const void *d, int e, Uint32 f, void *g, int h),(a,b,c,d,e,f,g,h),return)
#ifdef __ANDROID__
SDL_DYNAPI_PROC(int,SDL_AndroidSendMessage,(Uint32 a, int b),(a,b),return)
#endif
SDL_DYNAPI_PROC(const char*,SDL_GetTouchName,(int a),(a),return)
SDL_DYNAPI_PROC(void,SDL_ClearComposition,(void),(),)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsTextInputShown,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasIntersectionF,(const SDL_FRect *a, const SDL_FRect *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_UnionFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),)
SDL_DYNAPI_PROC(SDL_bool,SDL_EncloseFPoints,(const SDL_FPoint *a, int b, const SDL_FRect *c, SDL_FRect *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRectAndLine,(const SDL_FRect *a, float *b, float *c, float *d, float *e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(SDL_Window*,SDL_RenderGetWindow,(SDL_Renderer *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_bsearch,(const void *a, const void *b, size_t c, size_t d, int (SDLCALL *e)(const void *, const void *)),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(const char*,SDL_GameControllerPathForIndex,(int a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GameControllerPath,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_JoystickPathForIndex,(int a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_JoystickPath,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_JoystickAttachVirtualEx,(const SDL_VirtualJoystickDesc *a),(a),return)
SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetFirmwareVersion,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(Uint16,SDL_JoystickGetFirmwareVersion,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_GUIDToString,(SDL_GUID a, char *b, int c),(a,b,c),)
SDL_DYNAPI_PROC(SDL_GUID,SDL_GUIDFromString,(const char *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasLSX,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasLASX,(void),(),return)
#ifdef __WIN32__
SDL_DYNAPI_PROC(ID3D12Device*,SDL_RenderGetD3D12Device,(SDL_Renderer *a),(a),return)
#endif
SDL_DYNAPI_PROC(size_t,SDL_utf8strnlen,(const char *a, size_t b),(a,b),return)

View File

@@ -33,7 +33,6 @@ use File::Basename;
chdir(dirname(__FILE__) . '/../..');
my $sdl_dynapi_procs_h = "src/dynapi/SDL_dynapi_procs.h";
my $sdl_dynapi_overrides_h = "src/dynapi/SDL_dynapi_overrides.h";
my $sdl2_exports = "src/dynapi/SDL2.exports";
my %existing = ();
if (-f $sdl_dynapi_procs_h) {
@@ -48,7 +47,6 @@ if (-f $sdl_dynapi_procs_h) {
open(SDL_DYNAPI_PROCS_H, '>>', $sdl_dynapi_procs_h) or die("Can't open $sdl_dynapi_procs_h: $!\n");
open(SDL_DYNAPI_OVERRIDES_H, '>>', $sdl_dynapi_overrides_h) or die("Can't open $sdl_dynapi_overrides_h: $!\n");
open(SDL2_EXPORTS, '>>', $sdl2_exports) or die("Can't open $sdl2_exports: $!\n");
opendir(HEADERS, 'include') or die("Can't open include dir: $!\n");
while (my $d = readdir(HEADERS)) {
@@ -135,7 +133,6 @@ while (my $d = readdir(HEADERS)) {
print("NEW: $decl\n");
print SDL_DYNAPI_PROCS_H "SDL_DYNAPI_PROC($rc,$fn,$paramstr,$argstr,$retstr)\n";
print SDL_DYNAPI_OVERRIDES_H "#define $fn ${fn}_REAL\n";
print SDL2_EXPORTS "++'_${fn}'.'SDL2.dll'.'${fn}'\n";
} else {
print("Failed to parse decl [$decl]!\n");
}
@@ -146,6 +143,5 @@ closedir(HEADERS);
close(SDL_DYNAPI_PROCS_H);
close(SDL_DYNAPI_OVERRIDES_H);
close(SDL2_EXPORTS);
# vi: set ts=4 sw=4 expandtab:

View File

@@ -35,7 +35,7 @@
#include "SDL_syswm.h"
#undef SDL_PRIs64
#if defined(__WIN32__) && !defined(__CYGWIN__)
#ifdef __WIN32__
#define SDL_PRIs64 "I64d"
#else
#define SDL_PRIs64 "lld"
@@ -150,19 +150,13 @@ SDL_PollSentinelChanged(void *userdata, const char *name, const char *oldValue,
SDL_EventState(SDL_POLLSENTINEL, SDL_GetStringBoolean(hint, SDL_TRUE) ? SDL_ENABLE : SDL_DISABLE);
}
/**
* Verbosity of logged events as defined in SDL_HINT_EVENT_LOGGING:
* - 0: (default) no logging
* - 1: logging of most events
* - 2: as above, plus mouse and finger motion
* - 3: as above, plus SDL_SysWMEvents
*/
static int SDL_EventLoggingVerbosity = 0;
/* 0 (default) means no logging, 1 means logging, 2 means logging with mouse and finger motion */
static int SDL_DoEventLogging = 0;
static void SDLCALL
SDL_EventLoggingChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_EventLoggingVerbosity = (hint && *hint) ? SDL_clamp(SDL_atoi(hint), 0, 3) : 0;
SDL_DoEventLogging = (hint && *hint) ? SDL_clamp(SDL_atoi(hint), 0, 2) : 0;
}
static void
@@ -172,7 +166,7 @@ SDL_LogEvent(const SDL_Event *event)
char details[128];
/* sensor/mouse/finger motion are spammy, ignore these if they aren't demanded. */
if ( (SDL_EventLoggingVerbosity < 2) &&
if ( (SDL_DoEventLogging < 2) &&
( (event->type == SDL_MOUSEMOTION) ||
(event->type == SDL_FINGERMOTION) ||
(event->type == SDL_CONTROLLERTOUCHPADMOTION) ||
@@ -181,11 +175,6 @@ SDL_LogEvent(const SDL_Event *event)
return;
}
/* window manager events are even more spammy, and don't provide much useful info. */
if ((SDL_EventLoggingVerbosity < 3) && (event->type == SDL_SYSWMEVENT)) {
return;
}
/* this is to make SDL_snprintf() calls cleaner. */
#define uint unsigned int
@@ -217,28 +206,11 @@ SDL_LogEvent(const SDL_Event *event)
SDL_EVENT_CASE(SDL_APP_DIDENTERBACKGROUND) break;
SDL_EVENT_CASE(SDL_APP_WILLENTERFOREGROUND) break;
SDL_EVENT_CASE(SDL_APP_DIDENTERFOREGROUND) break;
SDL_EVENT_CASE(SDL_LOCALECHANGED) break;
SDL_EVENT_CASE(SDL_KEYMAPCHANGED) break;
SDL_EVENT_CASE(SDL_CLIPBOARDUPDATE) break;
SDL_EVENT_CASE(SDL_RENDER_TARGETS_RESET) break;
SDL_EVENT_CASE(SDL_RENDER_DEVICE_RESET) break;
SDL_EVENT_CASE(SDL_DISPLAYEVENT) {
char name2[64];
switch (event->display.event) {
case SDL_DISPLAYEVENT_NONE: SDL_strlcpy(name2, "SDL_DISPLAYEVENT_NONE (THIS IS PROBABLY A BUG!)", sizeof(name2)); break;
#define SDL_DISPLAYEVENT_CASE(x) case x: SDL_strlcpy(name2, #x, sizeof (name2)); break
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_ORIENTATION);
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_CONNECTED);
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_DISCONNECTED);
#undef SDL_DISPLAYEVENT_CASE
default: SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof(name2)); break;
}
SDL_snprintf(details, sizeof (details), " (timestamp=%u display=%u event=%s data1=%d)",
(uint) event->display.timestamp, (uint) event->display.display, name2, (int) event->display.data1);
break;
}
SDL_EVENT_CASE(SDL_WINDOWEVENT) {
char name2[64];
switch(event->window.event) {
@@ -260,8 +232,6 @@ SDL_LogEvent(const SDL_Event *event)
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_CLOSE);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_TAKE_FOCUS);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIT_TEST);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ICCPROF_CHANGED);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_DISPLAY_CHANGED);
#undef SDL_WINDOWEVENT_CASE
default: SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof (name2)); break;
}
@@ -601,7 +571,7 @@ SDL_AddEvent(SDL_Event * event)
SDL_EventQ.free = entry->next;
}
if (SDL_EventLoggingVerbosity > 0) {
if (SDL_DoEventLogging) {
SDL_LogEvent(event);
}
@@ -690,12 +660,12 @@ static int
SDL_PeepEventsInternal(SDL_Event * events, int numevents, SDL_eventaction action,
Uint32 minType, Uint32 maxType, SDL_bool include_sentinel)
{
int i, used, sentinels_expected = 0;
int i, used;
/* Don't look after we've quit */
if (!SDL_AtomicGet(&SDL_EventQ.active)) {
/* We get a few spurious events at shutdown, so don't warn then */
if (action == SDL_GETEVENT) {
if (action != SDL_ADDEVENT) {
SDL_SetError("The event system has been shut down");
}
return (-1);
@@ -753,15 +723,8 @@ SDL_PeepEventsInternal(SDL_Event * events, int numevents, SDL_eventaction action
}
if (type == SDL_POLLSENTINEL) {
/* Special handling for the sentinel event */
if (!include_sentinel) {
/* Skip it, we don't want to include it */
continue;
}
if (!events || action != SDL_GETEVENT) {
++sentinels_expected;
}
if (SDL_AtomicGet(&SDL_sentinel_pending) > sentinels_expected) {
/* Skip it, there's another one pending */
if (!include_sentinel || SDL_AtomicGet(&SDL_sentinel_pending) > 0) {
/* Skip it, we don't want to include it or there's another one pending */
continue;
}
}
@@ -928,11 +891,7 @@ SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event,
c) Periodic processing that takes place in some platform PumpEvents() functions happens
d) Signals received in WaitEventTimeout() are turned into SDL events
*/
/* We only want a single sentinel in the queue. We could get more than one if event is NULL,
* since the SDL_PeepEvents() call below won't remove it in that case.
*/
SDL_bool add_sentinel = (SDL_AtomicGet(&SDL_sentinel_pending) == 0) ? SDL_TRUE : SDL_FALSE;
SDL_PumpEventsInternal(add_sentinel);
SDL_PumpEventsInternal(SDL_TRUE);
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
int status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
@@ -973,10 +932,7 @@ SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event,
status = _this->WaitEventTimeout(_this, loop_timeout);
/* Set wakeup_window to NULL without holding the lock. */
_this->wakeup_window = NULL;
if (status == 0 && need_periodic_poll && loop_timeout == PERIODIC_POLL_INTERVAL_MS) {
/* We may have woken up to poll. Try again */
continue;
} else if (status <= 0) {
if (status <= 0) {
/* There is either an error or the timeout is elapsed: return */
return status;
}
@@ -1031,7 +987,6 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
SDL_Window *wakeup_window;
Uint32 start, expiration;
SDL_bool include_sentinel = (timeout == 0) ? SDL_TRUE : SDL_FALSE;
int result;
/* If there isn't a poll sentinel event pending, pump events and add one */
if (SDL_AtomicGet(&SDL_sentinel_pending) == 0) {
@@ -1039,34 +994,33 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
}
/* First check for existing events */
result = SDL_PeepEventsInternal(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, include_sentinel);
if (result < 0) {
switch (SDL_PeepEventsInternal(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, include_sentinel)) {
case -1:
return 0;
}
if (include_sentinel) {
if (event) {
if (event->type == SDL_POLLSENTINEL) {
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
} else {
/* Need to peek the next event to check for sentinel */
SDL_Event dummy;
if (SDL_PeepEventsInternal(&dummy, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, SDL_TRUE) &&
dummy.type == SDL_POLLSENTINEL) {
SDL_PeepEventsInternal(&dummy, 1, SDL_GETEVENT, SDL_POLLSENTINEL, SDL_POLLSENTINEL, SDL_TRUE);
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
}
}
if (result == 0) {
case 0:
if (timeout == 0) {
/* No events available, and not willing to wait */
return 0;
}
} else {
break;
default:
if (include_sentinel) {
if (event) {
if (event->type == SDL_POLLSENTINEL) {
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
} else {
/* Need to peek the next event to check for sentinel */
SDL_Event dummy;
if (SDL_PeepEventsInternal(&dummy, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, SDL_TRUE) &&
dummy.type == SDL_POLLSENTINEL) {
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
}
}
/* Has existing events */
return 1;
}
@@ -1278,7 +1232,8 @@ SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
Uint8
SDL_EventState(Uint32 type, int state)
{
const SDL_bool isde = (state == SDL_DISABLE) || (state == SDL_ENABLE);
const SDL_bool isdnd = ((state == SDL_DISABLE) || (state == SDL_ENABLE)) &&
((type == SDL_DROPFILE) || (type == SDL_DROPTEXT));
Uint8 current_state;
Uint8 hi = ((type >> 8) & 0xff);
Uint8 lo = (type & 0xff);
@@ -1290,32 +1245,44 @@ SDL_EventState(Uint32 type, int state)
current_state = SDL_ENABLE;
}
if (isde && state != current_state) {
if (state == SDL_DISABLE) {
if (state != current_state)
{
switch (state) {
case SDL_DISABLE:
/* Disable this event type and discard pending events */
if (!SDL_disabled_events[hi]) {
SDL_disabled_events[hi] = (SDL_DisabledEventBlock*) SDL_calloc(1, sizeof(SDL_DisabledEventBlock));
if (!SDL_disabled_events[hi]) {
/* Out of memory, nothing we can do... */
break;
}
}
/* Out of memory, nothing we can do... */
if (SDL_disabled_events[hi]) {
SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
SDL_FlushEvent(type);
}
} else { // state == SDL_ENABLE
SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
SDL_FlushEvent(type);
break;
case SDL_ENABLE:
SDL_disabled_events[hi]->bits[lo/32] &= ~(1 << (lo&31));
break;
default:
/* Querying state... */
break;
}
#if !SDL_JOYSTICK_DISABLED
SDL_CalculateShouldUpdateJoysticks();
if (state == SDL_DISABLE || state == SDL_ENABLE) {
SDL_CalculateShouldUpdateJoysticks();
}
#endif
#if !SDL_SENSOR_DISABLED
SDL_CalculateShouldUpdateSensors();
if (state == SDL_DISABLE || state == SDL_ENABLE) {
SDL_CalculateShouldUpdateSensors();
}
#endif
}
/* turn off drag'n'drop support if we've disabled the events.
This might change some UI details at the OS level. */
if (isde && ((type == SDL_DROPFILE) || (type == SDL_DROPTEXT))) {
if (isdnd) {
SDL_ToggleDragAndDropSupport();
}

View File

@@ -282,10 +282,6 @@ static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
SDLK_APP2,
SDLK_AUDIOREWIND,
SDLK_AUDIOFASTFORWARD,
SDLK_SOFTLEFT,
SDLK_SOFTRIGHT,
SDLK_CALL,
SDLK_ENDCALL,
};
static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = {
@@ -522,10 +518,6 @@ static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = {
"App2",
"AudioRewind",
"AudioFastForward",
"SoftLeft",
"SoftRight",
"Call",
"EndCall",
};
/* Taken from SDL_iconv() */
@@ -646,7 +638,6 @@ SDL_SetKeyboardFocus(SDL_Window * window)
/* old window must lose an existing mouse capture. */
if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) {
SDL_CaptureMouse(SDL_FALSE); /* drop the capture. */
SDL_UpdateMouseCapture(SDL_TRUE);
SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE));
}
@@ -876,14 +867,10 @@ SDL_SendKeyboardText(const char *text)
posted = 0;
if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) {
SDL_Event event;
size_t i = 0, length = SDL_strlen(text);
event.text.type = SDL_TEXTINPUT;
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
while (i < length) {
i += SDL_utf8strlcpy(event.text.text, text + i, SDL_arraysize(event.text.text));
posted |= (SDL_PushEvent(&event) > 0);
}
SDL_utf8strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
posted = (SDL_PushEvent(&event) > 0);
}
return (posted);
}
@@ -903,22 +890,6 @@ SDL_SendEditingText(const char *text, int start, int length)
event.edit.start = start;
event.edit.length = length;
SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE) &&
SDL_strlen(text) > SDL_arraysize(event.text.text)) {
event.editExt.type = SDL_TEXTEDITING_EXT;
event.editExt.windowID = keyboard->focus ? keyboard->focus->id : 0;
event.editExt.text = text ? SDL_strdup(text) : NULL;
event.editExt.start = start;
event.editExt.length = length;
} else {
event.edit.type = SDL_TEXTEDITING;
event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
event.edit.start = start;
event.edit.length = length;
SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
}
posted = (SDL_PushEvent(&event) > 0);
}
return (posted);

View File

@@ -109,28 +109,6 @@ SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldVal
mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE);
}
#if defined(__vita__)
static void SDLCALL
SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
if (hint) {
switch(*hint) {
default:
case '0':
mouse->vita_touch_mouse_device = 0;
break;
case '1':
mouse->vita_touch_mouse_device = 1;
break;
case '2':
mouse->vita_touch_mouse_device = 2;
break;
}
}
}
#endif
static void SDLCALL
SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
@@ -149,18 +127,6 @@ SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldVal
}
}
static void SDLCALL
SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
SDL_bool auto_capture = SDL_GetStringBoolean(hint, SDL_TRUE);
if (auto_capture != mouse->auto_capture) {
mouse->auto_capture = auto_capture;
SDL_UpdateMouseCapture(SDL_FALSE);
}
}
/* Public functions */
int
SDL_MouseInit(void)
@@ -184,17 +150,9 @@ SDL_MouseInit(void)
SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
SDL_TouchMouseEventsChanged, mouse);
#if defined(__vita__)
SDL_AddHintCallback(SDL_HINT_VITA_TOUCH_MOUSE_DEVICE,
SDL_VitaTouchMouseDeviceChanged, mouse);
#endif
SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
SDL_MouseTouchEventsChanged, mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE,
SDL_MouseAutoCaptureChanged, mouse);
mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */
mouse->cursor_shown = SDL_TRUE;
@@ -290,10 +248,23 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_
}
}
/* Linux doesn't give you mouse events outside your window unless you grab
the pointer.
Windows doesn't give you mouse events outside your window unless you call
SetCapture().
Both of these are slightly scary changes, so for now we'll punt and if the
mouse leaves the window you'll lose mouse focus and reset button state.
*/
#ifdef SUPPORT_DRAG_OUTSIDE_WINDOW
if (!inWindow && !buttonstate) {
#else
if (!inWindow) {
#endif
if (window == mouse->focus) {
#ifdef DEBUG_MOUSE
SDL_Log("Mouse left window, synthesizing move & focus lost event\n");
printf("Mouse left window, synthesizing move & focus lost event\n");
#endif
if (send_mouse_motion) {
SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
@@ -305,7 +276,7 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_
if (window != mouse->focus) {
#ifdef DEBUG_MOUSE
SDL_Log("Mouse entered window, synthesizing focus gain & move event\n");
printf("Mouse entered window, synthesizing focus gain & move event\n");
#endif
SDL_SetMouseFocus(window);
if (send_mouse_motion) {
@@ -407,12 +378,14 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
/* Ignore relative motion when first positioning the mouse */
if (!mouse->has_position) {
xrel = 0;
yrel = 0;
mouse->x = x;
mouse->y = y;
mouse->has_position = SDL_TRUE;
} else if (!xrel && !yrel) { /* Drop events that don't change state */
#ifdef DEBUG_MOUSE
SDL_Log("Mouse event didn't change state - dropped!\n");
printf("Mouse event didn't change state - dropped!\n");
#endif
return 0;
}
@@ -560,7 +533,7 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
Uint32 type;
Uint32 buttonstate;
SDL_MouseInputSource *source;
source = GetMouseInputSource(mouse, mouseID);
if (!source) {
return 0;
@@ -660,11 +633,6 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, SDL_TRUE);
}
/* Automatically capture the mouse while buttons are pressed */
if (mouse->auto_capture) {
SDL_UpdateMouseCapture(SDL_FALSE);
}
return posted;
}
@@ -759,7 +727,6 @@ SDL_MouseQuit(void)
if (mouse->CaptureMouse) {
SDL_CaptureMouse(SDL_FALSE);
SDL_UpdateMouseCapture(SDL_TRUE);
}
SDL_SetRelativeMouseMode(SDL_FALSE);
SDL_ShowCursor(1);
@@ -790,26 +757,11 @@ SDL_MouseQuit(void)
}
mouse->num_clickstates = 0;
SDL_DelHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME,
SDL_MouseDoubleClickTimeChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS,
SDL_MouseDoubleClickRadiusChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
SDL_MouseRelativeSpeedScaleChanged, mouse);
SDL_DelHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
SDL_TouchMouseEventsChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
SDL_MouseTouchEventsChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE,
SDL_MouseAutoCaptureChanged, mouse);
}
Uint32
@@ -867,7 +819,7 @@ SDL_GetGlobalMouseState(int *x, int *y)
}
void
SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode)
SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
{
SDL_Mouse *mouse = SDL_GetMouse();
@@ -883,20 +835,6 @@ SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_r
return;
}
if (mouse->relative_mode && !ignore_relative_mode) {
/* 2.0.22 made warping in relative mode actually functional, which
* surprised many applications that weren't expecting the additional
* mouse motion.
*
* So for now, warping in relative mode adjusts the absolution position
* but doesn't generate motion events.
*/
mouse->x = x;
mouse->y = y;
mouse->has_position = SDL_TRUE;
return;
}
/* Ignore the previous position when we warp */
mouse->has_position = SDL_FALSE;
@@ -908,12 +846,6 @@ SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_r
}
}
void
SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
{
SDL_PerformWarpMouseInWindow(window, x, y, SDL_FALSE);
}
int
SDL_WarpMouseGlobal(int x, int y)
{
@@ -973,9 +905,8 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
if (enabled && focusWindow) {
SDL_SetMouseFocus(focusWindow);
if (mouse->relative_mode_warp) {
SDL_PerformWarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2, SDL_TRUE);
}
if (mouse->relative_mode_warp)
SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
}
if (focusWindow) {
@@ -983,10 +914,8 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
/* Put the cursor back to where the application expects it */
if (!enabled) {
SDL_PerformWarpMouseInWindow(focusWindow, mouse->x, mouse->y, SDL_TRUE);
SDL_WarpMouseInWindow(focusWindow, mouse->x, mouse->y);
}
SDL_UpdateMouseCapture(SDL_FALSE);
}
if (!enabled) {
@@ -1008,84 +937,39 @@ SDL_GetRelativeMouseMode()
return mouse->relative_mode;
}
int
SDL_UpdateMouseCapture(SDL_bool force_release)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Window *capture_window = NULL;
if (!mouse->CaptureMouse) {
return 0;
}
if (!force_release) {
if (SDL_GetMessageBoxCount() == 0 &&
(mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseState(NULL, NULL) != 0))) {
if (!mouse->relative_mode) {
capture_window = SDL_GetKeyboardFocus();
}
}
}
if (capture_window != mouse->capture_window) {
/* We can get here recursively on Windows, so make sure we complete
* all of the window state operations before we change the capture state
* (e.g. https://github.com/libsdl-org/SDL/pull/5608)
*/
SDL_Window *previous_capture = mouse->capture_window;
if (previous_capture) {
previous_capture->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
}
if (capture_window) {
capture_window->flags |= SDL_WINDOW_MOUSE_CAPTURE;
}
mouse->capture_window = capture_window;
if (mouse->CaptureMouse(capture_window) < 0) {
/* CaptureMouse() will have set an error, just restore the state */
if (previous_capture) {
previous_capture->flags |= SDL_WINDOW_MOUSE_CAPTURE;
}
if (capture_window) {
capture_window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
}
mouse->capture_window = previous_capture;
return -1;
}
}
return 0;
}
int
SDL_CaptureMouse(SDL_bool enabled)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Window *focusWindow;
SDL_bool isCaptured;
if (!mouse->CaptureMouse) {
return SDL_Unsupported();
}
#ifdef __WIN32__
/* Windows mouse capture is tied to the current thread, and must be called
* from the thread that created the window being captured. Since we update
* the mouse capture state from the event processing, any application state
* changes must be processed on that thread as well.
*/
if (!SDL_OnVideoThread()) {
return SDL_SetError("SDL_CaptureMouse() must be called on the main thread");
}
#endif /* __WIN32__ */
focusWindow = SDL_GetKeyboardFocus();
if (enabled && SDL_GetKeyboardFocus() == NULL) {
return SDL_SetError("No window has focus");
isCaptured = focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE);
if (isCaptured == enabled) {
return 0; /* already done! */
}
mouse->capture_desired = enabled;
return SDL_UpdateMouseCapture(SDL_FALSE);
if (enabled) {
if (!focusWindow) {
return SDL_SetError("No window has focus");
} else if (mouse->CaptureMouse(focusWindow) == -1) {
return -1; /* CaptureMouse() should call SetError */
}
focusWindow->flags |= SDL_WINDOW_MOUSE_CAPTURE;
} else {
if (mouse->CaptureMouse(NULL) == -1) {
return -1; /* CaptureMouse() should call SetError */
}
focusWindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
}
return 0;
}
SDL_Cursor *
@@ -1145,7 +1029,7 @@ SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
SDL_Cursor *cursor;
if (!surface) {
SDL_InvalidParamError("surface");
SDL_SetError("Passed NULL cursor surface");
return NULL;
}

View File

@@ -100,12 +100,6 @@ typedef struct
SDL_bool touch_mouse_events;
SDL_bool mouse_touch_events;
SDL_bool was_touch_mouse_events; /* Was a touch-mouse event pending? */
#if defined(__vita__)
Uint8 vita_touch_mouse_device;
#endif
SDL_bool auto_capture;
SDL_bool capture_desired;
SDL_Window *capture_window;
/* Data for input source state */
int num_sources;
@@ -137,9 +131,6 @@ extern void SDL_SetDefaultCursor(SDL_Cursor * cursor);
/* Set the mouse focus window */
extern void SDL_SetMouseFocus(SDL_Window * window);
/* Update the mouse capture window */
extern int SDL_UpdateMouseCapture(SDL_bool force_release);
/* Send a mouse motion event */
extern int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
@@ -152,9 +143,6 @@ extern int SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, U
/* Send a mouse wheel event */
extern int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction);
/* Warp the mouse within the window, potentially overriding relative mode */
extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode);
/* Shutdown the mouse subsystem */
extern void SDL_MouseQuit(void);

View File

@@ -63,16 +63,6 @@ SDL_GetTouchDevice(int index)
return SDL_touchDevices[index]->id;
}
const char*
SDL_GetTouchName(int index)
{
if (index < 0 || index >= SDL_num_touch) {
SDL_SetError("Unknown touch device");
return NULL;
}
return SDL_touchDevices[index]->name;
}
static int
SDL_GetTouchIndex(SDL_TouchID id)
{
@@ -195,7 +185,6 @@ SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
SDL_touchDevices[index]->num_fingers = 0;
SDL_touchDevices[index]->max_fingers = 0;
SDL_touchDevices[index]->fingers = NULL;
SDL_touchDevices[index]->name = SDL_strdup(name ? name : "");
/* Record this touch device for gestures */
/* We could do this on the fly in the gesture code if we wanted */
@@ -265,13 +254,8 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window,
#if SYNTHESIZE_TOUCH_TO_MOUSE
/* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
/* SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only */
{
#if defined(__vita__)
if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 2)) ) {
#else
if (mouse->touch_mouse_events) {
#endif
/* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */
if (id != SDL_MOUSE_TOUCHID) {
if (window) {
@@ -318,9 +302,8 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window,
finger = SDL_GetFinger(touch, fingerid);
if (down) {
if (finger) {
/* This finger is already down.
Assume the finger-up for the previous touch was lost, and send it. */
SDL_SendTouch(id, fingerid, window, SDL_FALSE, x, y, pressure);
/* This finger is already down */
return 0;
}
if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) {
@@ -468,7 +451,6 @@ SDL_DelTouch(SDL_TouchID id)
SDL_free(touch->fingers[i]);
}
SDL_free(touch->fingers);
SDL_free(touch->name);
SDL_free(touch);
SDL_num_touch--;

View File

@@ -31,7 +31,6 @@ typedef struct SDL_Touch
int num_fingers;
int max_fingers;
SDL_Finger** fingers;
char *name;
} SDL_Touch;

View File

@@ -25,7 +25,7 @@
#include "SDL_events.h"
#include "SDL_events_c.h"
#include "SDL_mouse_c.h"
#include "SDL_hints.h"
static int SDLCALL
RemovePendingSizeChangedAndResizedEvents(void * userdata, SDL_Event *event)
@@ -201,9 +201,8 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
if (windowevent == SDL_WINDOWEVENT_CLOSE) {
if ( !window->prev && !window->next ) {
if (SDL_GetHintBoolean(SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE, SDL_TRUE)) {
SDL_SendQuit(); /* This is the last window in the list so send the SDL_QUIT event */
}
/* This is the last window in the list so send the SDL_QUIT event */
SDL_SendQuit();
}
}

View File

@@ -25,7 +25,7 @@
- Apple USB keyboard driver source <http://darwinsource.opendarwin.org/10.4.6.ppc/IOHIDFamily-172.8/IOHIDFamily/Cosmo_USB2ADB.c>
- experimentation on various ADB and USB ISO keyboards and one ADB ANSI keyboard
*/
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */
static const SDL_Scancode darwin_scancode_table[] = {
/* 0 */ SDL_SCANCODE_A,
/* 1 */ SDL_SCANCODE_S,
@@ -156,4 +156,4 @@ static const SDL_Scancode darwin_scancode_table[] = {
/* 126 */ SDL_SCANCODE_UP,
/* 127 */ SDL_SCANCODE_POWER
};
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */

View File

@@ -24,7 +24,7 @@
Sources:
- Linux kernel source input.h
*/
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */
static SDL_Scancode const linux_scancode_table[] = {
/* 0 */ SDL_SCANCODE_UNKNOWN,
/* 1 */ SDL_SCANCODE_ESCAPE,
@@ -260,4 +260,4 @@ static SDL_Scancode const linux_scancode_table[] = {
/* 235 */ SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS */
/* 236 */ SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY */
};
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */

View File

@@ -23,7 +23,7 @@
/* Windows scancode to SDL scancode mapping table */
/* derived from Microsoft scan code document, http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc */
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */
static const SDL_Scancode windows_scancode_table[] =
{
/* 0 1 2 3 4 5 6 7 */
@@ -52,4 +52,4 @@ static const SDL_Scancode windows_scancode_table[] =
SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL3, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN /* 7 */
};
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */

View File

@@ -28,7 +28,7 @@
Sources:
- atKeyNames.h from XFree86 source code
*/
/* *INDENT-OFF* */ /* clang-format off */
/* *INDENT-OFF* */
static const SDL_Scancode xfree86_scancode_table[] = {
/* 0 */ SDL_SCANCODE_UNKNOWN,
/* 1 */ SDL_SCANCODE_ESCAPE,
@@ -509,4 +509,4 @@ static const SDL_Scancode xvnc_scancode_table[] = {
#endif /* scancodes_xfree86_h_ */
/* *INDENT-ON* */ /* clang-format on */
/* *INDENT-ON* */

View File

@@ -62,6 +62,235 @@
#include "nacl_io/nacl_io.h"
#endif
#ifdef __VITA__
#include <psp2/io/fcntl.h>
#include <psp2/io/stat.h>
#define READAHEAD_BUFFER_SIZE 1024
static int SDLCALL
vita_file_open(SDL_RWops * context, const char *filename, const char *mode)
{
int h;
int open_flags;
SDL_bool has_r;
SDL_bool has_w;
SDL_bool has_a;
SDL_bool has_plus;
if (!context)
return -1; /* failed (invalid call) */
context->hidden.vitaio.h = -1; /* mark this as unusable */
context->hidden.vitaio.buffer.data = NULL;
context->hidden.vitaio.buffer.size = 0;
context->hidden.vitaio.buffer.left = 0;
open_flags = 0;
/* "r" = reading, file must exist */
/* "w" = writing, truncate existing, file may not exist */
/* "r+"= reading or writing, file must exist */
/* "a" = writing, append file may not exist */
/* "a+"= append + read, file may not exist */
/* "w+" = read, write, truncate. file may not exist */
has_r = SDL_strchr(mode, 'r') != NULL;
has_w = SDL_strchr(mode, 'w') != NULL;
has_a = SDL_strchr(mode, 'a') != NULL;
has_plus = SDL_strchr(mode, '+') != NULL;
if (has_plus)
{
if (has_r || has_w || has_a)
{
open_flags |= SCE_O_RDWR;
}
}
else
{
if (has_r)
{
open_flags |= SCE_O_RDONLY;
}
if (has_w || has_a)
{
open_flags |= SCE_O_WRONLY;
}
}
if (has_w || has_a)
{
open_flags |= SCE_O_CREAT;
}
if (has_w)
{
open_flags |= SCE_O_TRUNC;
}
if (has_a)
{
open_flags |= SCE_O_APPEND;
}
context->hidden.vitaio.buffer.data =
(char *) SDL_malloc(READAHEAD_BUFFER_SIZE);
if (!context->hidden.vitaio.buffer.data) {
return SDL_OutOfMemory();
}
/* Try to open the file on the filesystem first */
h = sceIoOpen(filename, open_flags, 0777);
if (h < 0) {
/* Try opening it from app0:/ container if it's a relative path */
char path[4096];
SDL_snprintf(path, 4096, "app0:/%s", filename);
h = sceIoOpen(path, open_flags, 0777);
}
if (h < 0) {
SDL_free(context->hidden.vitaio.buffer.data);
context->hidden.vitaio.buffer.data = NULL;
SDL_SetError("Couldn't open %s", filename);
return -2; /* failed (sceIoOpen) */
}
context->hidden.vitaio.h = h;
return 0; /* ok */
}
static Sint64 SDLCALL
vita_file_size(SDL_RWops * context)
{
SceIoStat st;
if (!context || context->hidden.vitaio.h < 0) {
return SDL_SetError("vita_file_size: invalid context/file not opened");
}
if (sceIoGetstatByFd(context->hidden.vitaio.h, &st) < 0) {
return SDL_SetError("vita_file_size: could not get file size");
}
return st.st_size;
}
static Sint64 SDLCALL
vita_file_seek(SDL_RWops * context, Sint64 offset, int whence)
{
int vitawhence;
if (!context || context->hidden.vitaio.h < 0) {
return SDL_SetError("vita_file_seek: invalid context/file not opened");
}
/* FIXME: We may be able to satisfy the seek within buffered data */
if (whence == RW_SEEK_CUR && context->hidden.vitaio.buffer.left) {
offset -= (long)context->hidden.vitaio.buffer.left;
}
context->hidden.vitaio.buffer.left = 0;
switch (whence) {
case RW_SEEK_SET:
vitawhence = SCE_SEEK_SET;
break;
case RW_SEEK_CUR:
vitawhence = SCE_SEEK_CUR;
break;
case RW_SEEK_END:
vitawhence = SCE_SEEK_END;
break;
default:
return SDL_SetError("vita_file_seek: Unknown value for 'whence'");
}
return sceIoLseek(context->hidden.vitaio.h, offset, vitawhence);
}
static size_t SDLCALL
vita_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
{
size_t total_need;
size_t total_read = 0;
size_t read_ahead;
size_t byte_read;
total_need = size * maxnum;
if (!context || context->hidden.vitaio.h < 0 || !total_need) {
return 0;
}
if (context->hidden.vitaio.buffer.left > 0) {
void *data = (char *) context->hidden.vitaio.buffer.data +
context->hidden.vitaio.buffer.size -
context->hidden.vitaio.buffer.left;
read_ahead =
SDL_min(total_need, context->hidden.vitaio.buffer.left);
SDL_memcpy(ptr, data, read_ahead);
context->hidden.vitaio.buffer.left -= read_ahead;
if (read_ahead == total_need) {
return maxnum;
}
ptr = (char *) ptr + read_ahead;
total_need -= read_ahead;
total_read += read_ahead;
}
if (total_need < READAHEAD_BUFFER_SIZE) {
byte_read = sceIoRead(context->hidden.vitaio.h, context->hidden.vitaio.buffer.data, READAHEAD_BUFFER_SIZE);
read_ahead = SDL_min(total_need, (int) byte_read);
SDL_memcpy(ptr, context->hidden.vitaio.buffer.data, read_ahead);
context->hidden.vitaio.buffer.size = byte_read;
context->hidden.vitaio.buffer.left = byte_read - read_ahead;
total_read += read_ahead;
} else {
byte_read = sceIoRead(context->hidden.vitaio.h, ptr, total_need);
total_read += byte_read;
}
return (total_read / size);
}
static size_t SDLCALL
vita_file_write(SDL_RWops * context, const void *ptr, size_t size,
size_t num)
{
size_t total_bytes;
size_t byte_written;
size_t nwritten;
total_bytes = size * num;
if (!context || context->hidden.vitaio.h < 0 || !size || !total_bytes) {
return 0;
}
if (context->hidden.vitaio.buffer.left) {
sceIoLseek(context->hidden.vitaio.h, -(SceOff)context->hidden.vitaio.buffer.left, SCE_SEEK_CUR);
context->hidden.vitaio.buffer.left = 0;
}
byte_written = sceIoWrite(context->hidden.vitaio.h, ptr, total_bytes);
nwritten = byte_written / size;
return nwritten;
}
static int SDLCALL
vita_file_close(SDL_RWops * context)
{
if (context) {
if (context->hidden.vitaio.h >= 0) {
sceIoClose(context->hidden.vitaio.h);
context->hidden.vitaio.h = -1; /* to be sure */
}
SDL_free(context->hidden.vitaio.buffer.data);
context->hidden.vitaio.buffer.data = NULL;
SDL_FreeRW(context);
}
return 0;
}
#endif
#ifdef __WIN32__
/* Functions to read/write Win32 API file pointers */
@@ -588,9 +817,23 @@ SDL_RWFromFile(const char *file, const char *mode)
rwops->write = windows_file_write;
rwops->close = windows_file_close;
rwops->type = SDL_RWOPS_WINFILE;
#elif defined(__VITA__)
rwops = SDL_AllocRW();
if (!rwops)
return NULL; /* SDL_SetError already setup by SDL_AllocRW() */
if (vita_file_open(rwops, file, mode) < 0) {
SDL_FreeRW(rwops);
return NULL;
}
rwops->size = vita_file_size;
rwops->seek = vita_file_seek;
rwops->read = vita_file_read;
rwops->write = vita_file_write;
rwops->close = vita_file_close;
rwops->type = SDL_RWOPS_VITAFILE;
#elif HAVE_STDIO_H
{
#if __APPLE__ && !SDL_FILE_DISABLED // TODO: add dummy?
#ifdef __APPLE__
FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode);
#elif __WINRT__
FILE *fp = NULL;

View File

@@ -31,7 +31,6 @@
#define INCL_DOSFILEMGR
#define INCL_DOSPROCESS
#define INCL_DOSMODULEMGR
#define INCL_DOSERRORS
#include <os2.h>
@@ -43,31 +42,30 @@ SDL_GetBasePath(void)
PPIB pib;
ULONG ulRC = DosGetInfoBlocks(&tib, &pib);
PCHAR pcEnd;
ULONG cbResult;
CHAR acBuf[CCHMAXPATH];
if (ulRC != NO_ERROR) {
SDL_SetError("Can't get process information block (E%lu)", ulRC);
debug_os2("DosGetInfoBlocks() failed, rc = %u", ulRC);
return NULL;
}
ulRC = DosQueryModuleName(pib->pib_hmte, sizeof(acBuf), acBuf);
if (ulRC != NO_ERROR) {
SDL_SetError("Can't query the module name (E%lu)", ulRC);
return NULL;
}
pcEnd = SDL_strrchr(acBuf, '\\');
pcEnd = SDL_strrchr(pib->pib_pchcmd, '\\');
if (pcEnd != NULL)
pcEnd[1] = '\0';
pcEnd++;
else {
if (acBuf[1] == ':') /* e.g. "C:FOO" */
acBuf[2] = '\0';
if (pib->pib_pchcmd[1] == ':')
pcEnd = &pib->pib_pchcmd[2];
else {
SDL_SetError("No path in module name");
SDL_SetError("No path in pib->pib_pchcmd");
return NULL;
}
}
cbResult = pcEnd - pib->pib_pchcmd;
SDL_memcpy(acBuf, pib->pib_pchcmd, cbResult);
acBuf[cbResult] = '\0';
return OS2_SysToUTF8(acBuf);
}

View File

@@ -34,44 +34,44 @@
char *
SDL_GetBasePath(void)
{
char *retval = NULL;
size_t len;
char cwd[FILENAME_MAX];
char *retval = NULL;
size_t len;
char cwd[FILENAME_MAX];
getcwd(cwd, sizeof(cwd));
len = SDL_strlen(cwd) + 2;
retval = (char *) SDL_malloc(len);
SDL_snprintf(retval, len, "%s/", cwd);
getcwd(cwd, sizeof(cwd));
len = SDL_strlen(cwd) + 2;
retval = (char *) SDL_malloc(len);
SDL_snprintf(retval, len, "%s/", cwd);
return retval;
return retval;
}
char *
SDL_GetPrefPath(const char *org, const char *app)
{
char *retval = NULL;
size_t len;
char *base = SDL_GetBasePath();
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if(!org) {
org = "";
}
char *retval = NULL;
size_t len;
char *base = SDL_GetBasePath();
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if(!org) {
org = "";
}
len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
retval = (char *) SDL_malloc(len);
len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
retval = (char *) SDL_malloc(len);
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", base, app);
}
free(base);
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", base, app);
}
free(base);
mkdir(retval, 0755);
return retval;
mkdir(retval, 0755);
return retval;
}
#endif /* SDL_FILESYSTEM_PSP */

View File

@@ -35,23 +35,39 @@
char *
SDL_GetBasePath(void)
{
typedef DWORD (WINAPI *GetModuleFileNameExW_t)(HANDLE, HMODULE, LPWSTR, DWORD);
GetModuleFileNameExW_t pGetModuleFileNameExW;
DWORD buflen = 128;
WCHAR *path = NULL;
HANDLE psapi = LoadLibrary(TEXT("psapi.dll"));
char *retval = NULL;
DWORD len = 0;
int i;
if (!psapi) {
WIN_SetError("Couldn't load psapi.dll");
return NULL;
}
pGetModuleFileNameExW = (GetModuleFileNameExW_t)GetProcAddress(psapi, "GetModuleFileNameExW");
if (!pGetModuleFileNameExW) {
WIN_SetError("Couldn't find GetModuleFileNameExW");
FreeLibrary(psapi);
return NULL;
}
while (SDL_TRUE) {
void *ptr = SDL_realloc(path, buflen * sizeof (WCHAR));
if (!ptr) {
SDL_free(path);
FreeLibrary(psapi);
SDL_OutOfMemory();
return NULL;
}
path = (WCHAR *) ptr;
len = GetModuleFileNameW(NULL, path, buflen);
len = pGetModuleFileNameExW(GetCurrentProcess(), NULL, path, buflen);
/* if it truncated, then len >= buflen - 1 */
/* if there was enough room (or failure), len < buflen - 1 */
if (len < buflen - 1) {
@@ -62,6 +78,8 @@ SDL_GetBasePath(void)
buflen *= 2;
}
FreeLibrary(psapi);
if (len == 0) {
SDL_free(path);
WIN_SetError("Couldn't locate our .exe");

View File

@@ -492,7 +492,8 @@ SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
++index;
}
return SDL_SetError("Couldn't find joystick in haptic device list");
SDL_SetError("Couldn't find joystick in haptic device list");
return -1;
}
void
@@ -958,7 +959,8 @@ SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SD
REFGUID type = SDL_SYS_HapticEffectType(base);
if (type == NULL) {
return SDL_SetError("Haptic: Unknown effect type.");
SDL_SetError("Haptic: Unknown effect type.");
return -1;
}
/* Get the effect. */

View File

@@ -246,7 +246,8 @@ SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
++index;
}
return SDL_SetError("Couldn't find joystick in haptic device list");
SDL_SetError("Couldn't find joystick in haptic device list");
return -1;
}
void

View File

@@ -951,7 +951,6 @@ DeleteHIDDeviceWrapper(SDL_hid_device *device)
}
#if !SDL_HIDAPI_DISABLED
#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC)
#define COPY_IF_EXISTS(var) \
if (pSrc->var != NULL) { \
@@ -988,7 +987,6 @@ CopyHIDDeviceInfo(struct SDL_hid_device_info *pSrc, struct SDL_hid_device_info *
#undef COPY_IF_EXISTS
#undef WCOPY_IF_EXISTS
#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */
#endif /* !SDL_HIDAPI_DISABLED */
static int SDL_hidapi_refcount = 0;
@@ -1034,60 +1032,54 @@ int SDL_hid_init(void)
#endif
#ifdef SDL_LIBUSB_DYNAMIC
if (SDL_getenv("SDL_HIDAPI_DISABLE_LIBUSB") != NULL) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"libusb disabled by SDL_HIDAPI_DISABLE_LIBUSB");
libusb_ctx.libhandle = NULL;
} else {
++attempts;
libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC);
if (libusb_ctx.libhandle != NULL) {
SDL_bool loaded = SDL_TRUE;
#ifdef __OS2__
#define LOAD_LIBUSB_SYMBOL(func) \
if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle,"_libusb_" #func))) {loaded = SDL_FALSE;}
#else
#define LOAD_LIBUSB_SYMBOL(func) \
if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func))) {loaded = SDL_FALSE;}
#endif
LOAD_LIBUSB_SYMBOL(init)
LOAD_LIBUSB_SYMBOL(exit)
LOAD_LIBUSB_SYMBOL(get_device_list)
LOAD_LIBUSB_SYMBOL(free_device_list)
LOAD_LIBUSB_SYMBOL(get_device_descriptor)
LOAD_LIBUSB_SYMBOL(get_active_config_descriptor)
LOAD_LIBUSB_SYMBOL(get_config_descriptor)
LOAD_LIBUSB_SYMBOL(free_config_descriptor)
LOAD_LIBUSB_SYMBOL(get_bus_number)
LOAD_LIBUSB_SYMBOL(get_device_address)
LOAD_LIBUSB_SYMBOL(open)
LOAD_LIBUSB_SYMBOL(close)
LOAD_LIBUSB_SYMBOL(claim_interface)
LOAD_LIBUSB_SYMBOL(release_interface)
LOAD_LIBUSB_SYMBOL(kernel_driver_active)
LOAD_LIBUSB_SYMBOL(detach_kernel_driver)
LOAD_LIBUSB_SYMBOL(attach_kernel_driver)
LOAD_LIBUSB_SYMBOL(set_interface_alt_setting)
LOAD_LIBUSB_SYMBOL(alloc_transfer)
LOAD_LIBUSB_SYMBOL(submit_transfer)
LOAD_LIBUSB_SYMBOL(cancel_transfer)
LOAD_LIBUSB_SYMBOL(free_transfer)
LOAD_LIBUSB_SYMBOL(control_transfer)
LOAD_LIBUSB_SYMBOL(interrupt_transfer)
LOAD_LIBUSB_SYMBOL(handle_events)
LOAD_LIBUSB_SYMBOL(handle_events_completed)
#undef LOAD_LIBUSB_SYMBOL
++attempts;
libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC);
if (libusb_ctx.libhandle != NULL) {
SDL_bool loaded = SDL_TRUE;
#ifdef __OS2__
#define LOAD_LIBUSB_SYMBOL(func) \
if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle,"_libusb_" #func))) {loaded = SDL_FALSE;}
#else
#define LOAD_LIBUSB_SYMBOL(func) \
if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func))) {loaded = SDL_FALSE;}
#endif
LOAD_LIBUSB_SYMBOL(init)
LOAD_LIBUSB_SYMBOL(exit)
LOAD_LIBUSB_SYMBOL(get_device_list)
LOAD_LIBUSB_SYMBOL(free_device_list)
LOAD_LIBUSB_SYMBOL(get_device_descriptor)
LOAD_LIBUSB_SYMBOL(get_active_config_descriptor)
LOAD_LIBUSB_SYMBOL(get_config_descriptor)
LOAD_LIBUSB_SYMBOL(free_config_descriptor)
LOAD_LIBUSB_SYMBOL(get_bus_number)
LOAD_LIBUSB_SYMBOL(get_device_address)
LOAD_LIBUSB_SYMBOL(open)
LOAD_LIBUSB_SYMBOL(close)
LOAD_LIBUSB_SYMBOL(claim_interface)
LOAD_LIBUSB_SYMBOL(release_interface)
LOAD_LIBUSB_SYMBOL(kernel_driver_active)
LOAD_LIBUSB_SYMBOL(detach_kernel_driver)
LOAD_LIBUSB_SYMBOL(attach_kernel_driver)
LOAD_LIBUSB_SYMBOL(set_interface_alt_setting)
LOAD_LIBUSB_SYMBOL(alloc_transfer)
LOAD_LIBUSB_SYMBOL(submit_transfer)
LOAD_LIBUSB_SYMBOL(cancel_transfer)
LOAD_LIBUSB_SYMBOL(free_transfer)
LOAD_LIBUSB_SYMBOL(control_transfer)
LOAD_LIBUSB_SYMBOL(interrupt_transfer)
LOAD_LIBUSB_SYMBOL(handle_events)
LOAD_LIBUSB_SYMBOL(handle_events_completed)
#undef LOAD_LIBUSB_SYMBOL
if (!loaded) {
SDL_UnloadObject(libusb_ctx.libhandle);
libusb_ctx.libhandle = NULL;
/* SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function"); */
} else if (LIBUSB_hid_init() < 0) {
SDL_UnloadObject(libusb_ctx.libhandle);
libusb_ctx.libhandle = NULL;
} else {
++success;
}
if (!loaded) {
SDL_UnloadObject(libusb_ctx.libhandle);
libusb_ctx.libhandle = NULL;
/* SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function"); */
} else if (LIBUSB_hid_init() < 0) {
SDL_UnloadObject(libusb_ctx.libhandle);
libusb_ctx.libhandle = NULL;
} else {
++success;
}
}
#endif /* SDL_LIBUSB_DYNAMIC */
@@ -1193,9 +1185,9 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
#ifdef SDL_LIBUSB_DYNAMIC
if (libusb_ctx.libhandle) {
usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
#ifdef DEBUG_HIDAPI
#ifdef DEBUG_HIDAPI
SDL_Log("libusb devices found:");
#endif
#endif
for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
new_dev = (struct SDL_hid_device_info*) SDL_malloc(sizeof(struct SDL_hid_device_info));
if (!new_dev) {
@@ -1205,11 +1197,11 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
return NULL;
}
CopyHIDDeviceInfo(usb_dev, new_dev);
#ifdef DEBUG_HIDAPI
#ifdef DEBUG_HIDAPI
SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx",
usb_dev->manufacturer_string, usb_dev->product_string,
usb_dev->vendor_id, usb_dev->product_id);
#endif
#endif
if (last != NULL) {
last->next = new_dev;
@@ -1530,7 +1522,7 @@ int SDL_hid_get_indexed_string(SDL_hid_device *device, int string_index, wchar_t
void SDL_hid_ble_scan(SDL_bool active)
{
#if !SDL_HIDAPI_DISABLED && (__IPHONEOS__ || __TVOS__)
#if __IPHONEOS__ || __TVOS__
hid_ble_scan(active);
#endif
}

View File

@@ -24,30 +24,6 @@
//
// This layer glues the hidapi API to Android's USB and BLE stack.
// Common to stub version and non-stub version of functions
#include <jni.h>
#include <android/log.h>
#define TAG "hidapi"
// Have error log always available
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#ifdef DEBUG
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#else
#define LOGV(...)
#define LOGD(...)
#endif
#define SDL_JAVA_PREFIX org_libsdl_app
#define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function)
#define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function
#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)
#if !SDL_HIDAPI_DISABLED
#include "SDL_hints.h"
@@ -72,10 +48,30 @@
#define hid_get_indexed_string PLATFORM_hid_get_indexed_string
#define hid_error PLATFORM_hid_error
#include <jni.h>
#include <android/log.h>
#include <pthread.h>
#include <errno.h> // For ETIMEDOUT and ECONNRESET
#include <stdlib.h> // For malloc() and free()
#define TAG "hidapi"
// Have error log always available
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#ifdef DEBUG
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#else
#define LOGV(...)
#define LOGD(...)
#endif
#define SDL_JAVA_PREFIX org_libsdl_app
#define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function)
#define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function
#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)
#include "../hidapi/hidapi.h"
typedef uint32_t uint32;
@@ -1340,79 +1336,4 @@ int hid_exit(void)
}
#else
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol );
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz )
{
LOGV("Stub HIDDeviceRegisterCallback()");
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz)
{
LOGV("Stub HIDDeviceReleaseCallback()");
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol )
{
LOGV("Stub HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface);
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID)
{
LOGV("Stub HIDDeviceOpenPending() id=%d\n", nDeviceID);
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened)
{
LOGV("Stub HIDDeviceOpenResult() id=%d, result=%s\n", nDeviceID, bOpened ? "true" : "false");
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID)
{
LOGV("Stub HIDDeviceDisconnected() id=%d\n", nDeviceID);
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
{
LOGV("Stub HIDDeviceInput() id=%d len=%u\n", nDeviceID, nBufSize);
}
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
{
LOGV("Stub HIDDeviceFeatureReport() id=%d len=%u\n", nDeviceID, nBufSize);
}
#endif /* SDL_HIDAPI_DISABLED */

View File

@@ -31,24 +31,9 @@
#include "SDL_thread.h"
#include "SDL_mutex.h"
#ifndef HAVE_WCSDUP
#ifdef HAVE__WCSDUP
#if defined(HAVE__WCSDUP) && !defined(HAVE_WCSDUP)
#define wcsdup _wcsdup
#else
#define wcsdup _dupwcs
static wchar_t *_dupwcs(const wchar_t *src)
{
wchar_t *dst = NULL;
if (src) {
size_t len = SDL_wcslen(src) + 1;
len *= sizeof(wchar_t);
dst = (wchar_t *) malloc(len);
if (dst) memcpy(dst, src, len);
}
return dst;
}
#endif
#endif /* HAVE_WCSDUP */
#include <libusb.h>
#include <locale.h> /* setlocale */
@@ -74,8 +59,12 @@ typedef struct _SDL_ThreadBarrier
static int SDL_CreateThreadBarrier(SDL_ThreadBarrier *barrier, Uint32 count)
{
SDL_assert(barrier != NULL);
SDL_assert(count != 0);
if (barrier == NULL) {
return SDL_SetError("barrier must be non-NULL");
}
if (count == 0) {
return SDL_SetError("count must be > 0");
}
barrier->mutex = SDL_CreateMutex();
if (barrier->mutex == NULL) {
@@ -384,16 +373,12 @@ static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
/* This function returns a newly allocated wide string containing the USB
device string numbered by the index. The returned string must be freed
by using free(). */
#if defined(__OS2__) /* don't use iconv on OS/2: no support for wchar_t. */
#define NO_ICONV
#endif
static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
{
char buf[512];
int len;
wchar_t *str = NULL;
#if !defined(NO_ICONV)
wchar_t wbuf[256];
SDL_iconv_t ic;
size_t inbytes;
@@ -401,9 +386,6 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
size_t res;
const char *inptr;
char *outptr;
#else
int i;
#endif
/* Determine which language to use. */
uint16_t lang;
@@ -420,23 +402,6 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
if (len < 0)
return NULL;
#if defined(NO_ICONV) /* original hidapi code for NO_ICONV : */
/* Bionic does not have wchar_t iconv support, so it
has to be done manually. The following code will only work for
code points that can be represented as a single UTF-16 character,
and will incorrectly convert any code points which require more
than one UTF-16 character.
Skip over the first character (2-bytes). */
len -= 2;
str = (wchar_t*) malloc((len / 2 + 1) * sizeof(wchar_t));
for (i = 0; i < len / 2; i++) {
str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8);
}
str[len / 2] = 0x00000000;
#else
/* buf does not need to be explicitly NULL-terminated because
it is only passed into iconv() which does not need it. */
@@ -469,7 +434,6 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
err:
SDL_iconv_close(ic);
#endif
return str;
}
@@ -635,7 +599,6 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de
0x1bad, /* Harmonix */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
0x2c22, /* Qanba */
};
if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
@@ -995,7 +958,7 @@ static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
}
static int SDLCALL read_thread(void *param)
static int read_thread(void *param)
{
hid_device *dev = (hid_device *)param;
uint8_t *buf;
@@ -1498,7 +1461,6 @@ void HID_API_EXPORT hid_close(hid_device *dev)
/* Clean up the Transfer objects allocated in read_thread(). */
free(dev->transfer->buffer);
dev->transfer->buffer = NULL;
libusb_free_transfer(dev->transfer);
/* release the interface */

View File

@@ -259,7 +259,7 @@ static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t
buf[0] = 0;
if (str && CFGetTypeID(str) == CFStringGetTypeID()) {
if (str) {
len --;
CFIndex str_len = CFStringGetLength(str);
@@ -298,7 +298,7 @@ static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, cha
buf[0] = 0;
if (str && CFGetTypeID(str) == CFStringGetTypeID()) {
if (str) {
len--;
CFIndex str_len = CFStringGetLength(str);
@@ -326,7 +326,10 @@ static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, cha
static int get_serial_number(IOHIDDeviceRef device, wchar_t *buf, size_t len)
{
return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len);
// This crashes on M1 Macs, tracked by radar bug 79667729
//return get_string_property(device, CFSTR(kIOHIDSerialNumberKey), buf, len);
buf[0] = 0;
return 0;
}
static int get_manufacturer_string(IOHIDDeviceRef device, wchar_t *buf, size_t len)
@@ -554,7 +557,6 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
continue;
}
#if 0 // Prefer direct HID support as that has extended functionality
#if defined(SDL_JOYSTICK_MFI)
// We want to prefer Game Controller support where available,
// as Apple will likely be requiring that for supported devices.
@@ -562,7 +564,6 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
if (IOS_SupportedHIDDevice(dev)) {
continue;
}
#endif
#endif
dev_vid = get_vendor_id(dev);
@@ -572,7 +573,8 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
if ((vendor_id == 0x0 && product_id == 0x0) ||
(vendor_id == dev_vid && product_id == dev_pid)) {
struct hid_device_info *tmp;
size_t len;
/* VID/PID match. Create the record. */
tmp = (struct hid_device_info *)calloc(1, sizeof(struct hid_device_info));
if (cur_dev) {
@@ -589,7 +591,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
/* Fill out the record */
cur_dev->next = NULL;
make_path(dev, cbuf, sizeof(cbuf));
len = make_path(dev, cbuf, sizeof(cbuf));
cur_dev->path = strdup(cbuf);
/* Serial Number */
@@ -816,9 +818,10 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
CFSetGetValues(device_set, (const void **) device_array);
for (i = 0; i < num_devices; i++) {
char cbuf[BUF_LEN];
size_t len;
IOHIDDeviceRef os_dev = device_array[i];
make_path(os_dev, cbuf, sizeof(cbuf));
len = make_path(os_dev, cbuf, sizeof(cbuf));
if (!strcmp(cbuf, path)) {
// Matched Paths. Open this Device.
IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone);
@@ -831,7 +834,6 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
/* Create the buffers for receiving data */
dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev);
SDL_assert(dev->max_input_report_len > 0);
dev->input_report_buf = (uint8_t *)calloc(dev->max_input_report_len, sizeof(uint8_t));
/* Create the Run Loop Mode for this device.
@@ -935,14 +937,11 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length)
/* Copy the data out of the linked list item (rpt) into the
return buffer (data), and delete the liked list item. */
struct input_report *rpt = dev->input_reports;
size_t len = 0;
if (rpt != NULL) {
len = (length < rpt->len)? length: rpt->len;
memcpy(data, rpt->data, len);
dev->input_reports = rpt->next;
free(rpt->data);
free(rpt);
}
size_t len = (length < rpt->len)? length: rpt->len;
memcpy(data, rpt->data, len);
dev->input_reports = rpt->next;
free(rpt->data);
free(rpt);
return (int)len;
}

View File

@@ -43,6 +43,21 @@
typedef LONG NTSTATUS;
#endif
/* SDL C runtime functions */
#include "SDL_stdinc.h"
#define calloc SDL_calloc
#define free SDL_free
#define malloc SDL_malloc
#define memcpy SDL_memcpy
#define memset SDL_memset
#define strcmp SDL_strcmp
#define strlen SDL_strlen
#define strstr SDL_strstr
#define strtol SDL_strtol
#define wcscmp SDL_wcscmp
#define _wcsdup SDL_wcsdup
/* The maximum number of characters that can be passed into the
HidD_Get*String() functions without it failing.*/
#define MAX_STRING_WCHARS 0xFFF
@@ -79,26 +94,11 @@ extern "C" {
} /* extern "C" */
#endif
#include "../hidapi/hidapi.h"
/*#include <stdio.h>*/
/*#include <stdlib.h>*/
/* SDL C runtime functions */
#include "SDL_stdinc.h"
#define calloc SDL_calloc
#define free SDL_free
#define malloc SDL_malloc
#define memcpy SDL_memcpy
#define memset SDL_memset
#define strcmp SDL_strcmp
#define strlen SDL_strlen
#define strstr SDL_strstr
#define strtol SDL_strtol
#define wcscmp SDL_wcscmp
#define _wcsdup SDL_wcsdup
#include "../hidapi/hidapi.h"
#undef MIN
#define MIN(x,y) ((x) < (y)? (x): (y))

View File

@@ -28,7 +28,6 @@
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "SDL_gamecontrollerdb.h"
#include "controller_type.h"
#include "usb_ids.h"
#if !SDL_EVENTS_DISABLED
@@ -587,12 +586,6 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
(vendor == USB_VENDOR_SHENZHEN && product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER)) {
/* GameCube driver has 12 buttons and 6 axes */
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", sizeof(mapping_string));
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_N64_CONTROLLER) {
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b15,", sizeof(mapping_string));
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER) {
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,rightshoulder:b10,righttrigger:a5,start:b6,misc1:b15,", sizeof(mapping_string));
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) {
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,", sizeof(mapping_string));
} else {
/* All other controllers have the standard set of 19 buttons and 6 axes */
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string));
@@ -653,20 +646,12 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
*/
static ControllerMapping_t *SDL_CreateMappingForRAWINPUTController(SDL_JoystickGUID guid)
{
Uint16 vendor;
Uint16 product;
SDL_bool existing;
char mapping_string[1024];
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string));
if (GuessControllerType(vendor, product) == k_eControllerType_XInputSwitchController &&
SDL_GetHintBoolean(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, SDL_TRUE)) {
SDL_strlcat(mapping_string, "a:b1,b:b0,x:b3,y:b2,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
} else {
SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
}
SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
return SDL_PrivateAddMappingForGUID(guid, mapping_string,
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
@@ -711,20 +696,19 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
return s_pXInputMapping;
}
#endif
if (!mapping) {
if (SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForHIDAPIController(guid);
} else if (SDL_IsJoystickRAWINPUT(guid)) {
mapping = SDL_CreateMappingForRAWINPUTController(guid);
} else if (SDL_IsJoystickWGI(guid)) {
mapping = SDL_CreateMappingForWGIController(guid);
} else if (SDL_IsJoystickVirtual(guid)) {
/* We'll pick up a robust mapping in VIRTUAL_JoystickGetGamepadMapping */
#ifdef __ANDROID__
} else {
mapping = SDL_CreateMappingForAndroidController(guid);
if (!mapping && !SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForAndroidController(guid);
}
#endif
}
if (!mapping && SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForHIDAPIController(guid);
}
if (!mapping && SDL_IsJoystickRAWINPUT(guid)) {
mapping = SDL_CreateMappingForRAWINPUTController(guid);
}
if (!mapping && SDL_IsJoystickWGI(guid)) {
mapping = SDL_CreateMappingForWGIController(guid);
}
}
return mapping;
@@ -1274,11 +1258,6 @@ static ControllerMapping_t *SDL_PrivateGenerateAutomaticControllerMapping(const
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpdown", &raw_map->dpdown);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpleft", &raw_map->dpleft);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpright", &raw_map->dpright);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "misc1", &raw_map->misc1);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle1", &raw_map->paddle1);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle2", &raw_map->paddle2);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle3", &raw_map->paddle3);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle4", &raw_map->paddle4);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "leftx", &raw_map->leftx);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "lefty", &raw_map->lefty);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "rightx", &raw_map->rightx);
@@ -1753,20 +1732,6 @@ SDL_GameControllerNameForIndex(int device_index)
}
/*
* Get the implementation dependent path of a controller
*/
const char *
SDL_GameControllerPathForIndex(int device_index)
{
ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
if (pSupportedController) {
return SDL_JoystickPathForIndex(device_index);
}
return NULL;
}
/**
* Get the type of a game controller.
*/
@@ -1855,10 +1820,12 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
}
#endif
#if defined(__ANDROID__)
if (name && SDL_strcmp(name, "uinput-fpc") == 0) {
/* The Google Pixel fingerprint sensor reports itself as a joystick */
return SDL_TRUE;
}
#endif
if (SDL_allowed_controllers.num_entries == 0 &&
SDL_ignored_controllers.num_entries == 0) {
@@ -2327,15 +2294,6 @@ SDL_GameControllerName(SDL_GameController *gamecontroller)
}
}
const char *
SDL_GameControllerPath(SDL_GameController *gamecontroller)
{
if (!gamecontroller)
return NULL;
return SDL_JoystickPath(SDL_GameControllerGetJoystick(gamecontroller));
}
SDL_GameControllerType
SDL_GameControllerGetType(SDL_GameController *gamecontroller)
{
@@ -2375,12 +2333,6 @@ SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller)
return SDL_JoystickGetProductVersion(SDL_GameControllerGetJoystick(gamecontroller));
}
Uint16
SDL_GameControllerGetFirmwareVersion(SDL_GameController *gamecontroller)
{
return SDL_JoystickGetFirmwareVersion(SDL_GameControllerGetJoystick(gamecontroller));
}
const char *
SDL_GameControllerGetSerial(SDL_GameController *gamecontroller)
{

View File

@@ -187,7 +187,6 @@ static const char *s_ControllerMappings [] =
"030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
"030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
"03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000380700006382000000000000,MLG Gamepad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
@@ -262,18 +261,11 @@ static const char *s_ControllerMappings [] =
"03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,",
"03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,",
"03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,",
"03000000222c00000025000000000000,Qanba Dragon Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,",
"030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,",
"030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@@ -449,7 +441,6 @@ static const char *s_ControllerMappings [] =
"030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
"03000000222c00000225000000010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
"03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@@ -503,7 +494,7 @@ static const char *s_ControllerMappings [] =
"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,",
#endif
#ifdef SDL_JOYSTICK_LINUX
#if defined(__LINUX__)
"xinput,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -714,10 +705,6 @@ static const char *s_ControllerMappings [] =
"03000000c62400003a54000001010000,PowerA XBox One Controller,a:b0,b:b1,back:b6,dpdown:h0.7,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,",
"03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
@@ -754,11 +741,8 @@ static const char *s_ControllerMappings [] =
"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,",
"03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,",
"03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,",
"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
@@ -771,7 +755,6 @@ static const char *s_ControllerMappings [] =
"0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,",
"030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,",
@@ -803,7 +786,6 @@ static const char *s_ControllerMappings [] =
"030000005e040000ea02000001030000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,",
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@@ -905,6 +887,9 @@ static const char *s_ControllerMappings [] =
"050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
"050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
#endif
#if defined(SDL_JOYSTICK_VIRTUAL)
"00000000000000000000000000007601,Virtual Joystick,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
#endif
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
"default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
#endif
@@ -912,7 +897,7 @@ static const char *s_ControllerMappings [] =
"50535669746120436f6e74726f6c6c65,PSVita Controller,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
#endif
#if defined(SDL_JOYSTICK_PSP)
"505350206275696c74696e206a6f7970,PSP builtin joypad,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
"505350206275696c74696e206a6f7970,PSP builtin joypad,y:b0,b:b1,a:b2,x:b3,leftshoulder:b4,rightshoulder:b5,dpdown:b6,dpleft:b7,dpup:b8,dpright:b9,back:b10,start:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
#endif
"hidapi,*,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
NULL

View File

@@ -320,28 +320,6 @@ SDL_JoystickNameForIndex(int device_index)
return name;
}
/*
* Get the implementation dependent path of a joystick
*/
const char *
SDL_JoystickPathForIndex(int device_index)
{
SDL_JoystickDriver *driver;
const char *path = NULL;
SDL_LockJoysticks();
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
path = driver->GetDevicePath(device_index);
}
SDL_UnlockJoysticks();
/* FIXME: Really we should reference count this path so it doesn't go away after unlock */
if (!path) {
SDL_Unsupported();
}
return path;
}
/*
* Get the player index of a joystick, or -1 if it's not available
*/
@@ -408,8 +386,6 @@ SDL_JoystickOpen(int device_index)
SDL_Joystick *joystick;
SDL_Joystick *joysticklist;
const char *joystickname = NULL;
const char *joystickpath = NULL;
SDL_JoystickPowerLevel initial_power_level;
SDL_LockJoysticks();
@@ -459,13 +435,6 @@ SDL_JoystickOpen(int device_index)
joystick->name = NULL;
}
joystickpath = driver->GetDevicePath(device_index);
if (joystickpath) {
joystick->path = SDL_strdup(joystickpath);
} else {
joystick->path = NULL;
}
joystick->guid = driver->GetDeviceGUID(device_index);
if (joystick->naxes > 0) {
@@ -509,11 +478,6 @@ SDL_JoystickOpen(int device_index)
SDL_UnlockJoysticks();
/* send initial battery event */
initial_power_level = joystick->epowerlevel;
joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
SDL_PrivateJoystickBatteryLevel(joystick, initial_power_level);
driver->Update(joystick);
return joystick;
@@ -522,23 +486,9 @@ SDL_JoystickOpen(int device_index)
int
SDL_JoystickAttachVirtual(SDL_JoystickType type,
int naxes, int nbuttons, int nhats)
{
SDL_VirtualJoystickDesc desc;
SDL_zero(desc);
desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION;
desc.type = (Uint16)type;
desc.naxes = (Uint16)naxes;
desc.nbuttons = (Uint16)nbuttons;
desc.nhats = (Uint16)nhats;
return SDL_JoystickAttachVirtualEx(&desc);
}
int
SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc)
{
#if SDL_JOYSTICK_VIRTUAL
return SDL_JoystickAttachVirtualInner(desc);
return SDL_JoystickAttachVirtualInner(type, naxes, nbuttons, nhats);
#else
return SDL_SetError("SDL not built with virtual-joystick support");
#endif
@@ -884,23 +834,6 @@ SDL_JoystickName(SDL_Joystick *joystick)
return joystick->name;
}
/*
* Get the implementation dependent path of this joystick
*/
const char *
SDL_JoystickPath(SDL_Joystick *joystick)
{
if (!SDL_PrivateJoystickValid(joystick)) {
return NULL;
}
if (!joystick->path) {
SDL_Unsupported();
return NULL;
}
return joystick->path;
}
/**
* Get the player index of an opened joystick, or -1 if it's not available
*/
@@ -953,18 +886,17 @@ SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h
result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble);
}
if (result == 0) {
joystick->low_frequency_rumble = low_frequency_rumble;
joystick->high_frequency_rumble = high_frequency_rumble;
/* Save the rumble value regardless of success, so we don't spam the driver */
joystick->low_frequency_rumble = low_frequency_rumble;
joystick->high_frequency_rumble = high_frequency_rumble;
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->rumble_expiration) {
joystick->rumble_expiration = 1;
}
} else {
joystick->rumble_expiration = 0;
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->rumble_expiration) {
joystick->rumble_expiration = 1;
}
} else {
joystick->rumble_expiration = 0;
}
SDL_UnlockJoysticks();
@@ -988,18 +920,17 @@ SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
result = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble);
}
if (result == 0) {
joystick->left_trigger_rumble = left_rumble;
joystick->right_trigger_rumble = right_rumble;
/* Save the rumble value regardless of success, so we don't spam the driver */
joystick->left_trigger_rumble = left_rumble;
joystick->right_trigger_rumble = right_rumble;
if ((left_rumble || right_rumble) && duration_ms) {
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->trigger_rumble_expiration) {
joystick->trigger_rumble_expiration = 1;
}
} else {
joystick->trigger_rumble_expiration = 0;
if ((left_rumble || right_rumble) && duration_ms) {
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->trigger_rumble_expiration) {
joystick->trigger_rumble_expiration = 1;
}
} else {
joystick->trigger_rumble_expiration = 0;
}
SDL_UnlockJoysticks();
@@ -1073,13 +1004,14 @@ SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
SDL_LockJoysticks();
isfreshvalue = red != joystick->led_red ||
green != joystick->led_green ||
blue != joystick->led_blue;
green != joystick->led_green ||
blue != joystick->led_blue;
if (isfreshvalue || SDL_TICKS_PASSED(SDL_GetTicks(), joystick->led_expiration)) {
if ( isfreshvalue || SDL_TICKS_PASSED( SDL_GetTicks(), joystick->led_expiration ) ) {
result = joystick->driver->SetLED(joystick, red, green, blue);
joystick->led_expiration = SDL_GetTicks() + SDL_LED_MIN_REPEAT_MS;
} else {
}
else {
/* Avoid spamming the driver */
result = 0;
}
@@ -1166,7 +1098,6 @@ SDL_JoystickClose(SDL_Joystick *joystick)
}
SDL_free(joystick->name);
SDL_free(joystick->path);
SDL_free(joystick->serial);
/* Free the data associated with this joystick */
@@ -1657,13 +1588,11 @@ SDL_JoystickUpdate(void)
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
if (joystick->attached) {
/* This driver should always be != NULL, but seeing a crash in the wild...? */
if (!joystick->driver) {
continue; /* nothing we can do, and other things use joystick->driver below here. */
/* This should always be true, but seeing a crash in the wild...? */
if (joystick->driver) {
joystick->driver->Update(joystick);
}
joystick->driver->Update(joystick);
if (joystick->delayed_guide_button) {
SDL_GameControllerHandleDelayedGuideButton(joystick);
}
@@ -1810,11 +1739,6 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
char *name;
size_t i, len;
/* Use the given name for the Nintendo Online NES Controllers */
if (SDL_strncmp(product_name, "NES Controller", 14) == 0) {
return SDL_strdup(product_name);
}
custom_name = GuessControllerName(vendor, product);
if (custom_name) {
return SDL_strdup(custom_name);
@@ -1837,48 +1761,23 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
if (*vendor_name && *product_name) {
len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1);
name = (char *)SDL_malloc(len);
if (name) {
SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
if (!name) {
return NULL;
}
SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
} else if (*product_name) {
name = SDL_strdup(product_name);
} else if (vendor || product) {
/* Couldn't find a controller name, try to give it one based on device type */
switch (SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, NULL, SDL_TRUE)) {
case SDL_CONTROLLER_TYPE_XBOX360:
name = SDL_strdup("Xbox 360 Controller");
break;
case SDL_CONTROLLER_TYPE_XBOXONE:
name = SDL_strdup("Xbox One Controller");
break;
case SDL_CONTROLLER_TYPE_PS3:
name = SDL_strdup("PS3 Controller");
break;
case SDL_CONTROLLER_TYPE_PS4:
name = SDL_strdup("PS4 Controller");
break;
case SDL_CONTROLLER_TYPE_PS5:
name = SDL_strdup("PS5 Controller");
break;
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
name = SDL_strdup("Nintendo Switch Pro Controller");
break;
default:
len = (6 + 1 + 6 + 1);
name = (char *)SDL_malloc(len);
if (name) {
SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
}
break;
len = (6 + 1 + 6 + 1);
name = (char *)SDL_malloc(len);
if (!name) {
return NULL;
}
SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
} else {
name = SDL_strdup("Controller");
}
if (!name) {
return NULL;
}
/* Trim trailing whitespace */
for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
/* continue */
@@ -1927,85 +1826,9 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
}
SDL_GameControllerType
SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI)
SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product)
{
SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN;
if (vendor == 0x0000 && product == 0x0000) {
/* Some devices are only identifiable by their name */
if (name &&
(SDL_strcmp(name, "Lic Pro Controller") == 0 ||
SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
SDL_strcmp(name, "Wireless Gamepad") == 0)) {
/* HORI or PowerA Switch Pro Controller clone */
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
}
} else if (vendor == 0x0001 && product == 0x0001) {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
} else if (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER) {
type = SDL_CONTROLLER_TYPE_XBOXONE;
} else if ((vendor == USB_VENDOR_AMAZON && product == USB_PRODUCT_AMAZON_LUNA_CONTROLLER) ||
(vendor == BLUETOOTH_VENDOR_AMAZON && product == BLUETOOTH_PRODUCT_LUNA_CONTROLLER)) {
type = SDL_CONTROLLER_TYPE_AMAZON_LUNA;
} else if (vendor == USB_VENDOR_GOOGLE && product == USB_PRODUCT_GOOGLE_STADIA_CONTROLLER) {
type = SDL_CONTROLLER_TYPE_GOOGLE_STADIA;
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
} else {
switch (GuessControllerType(vendor, product)) {
case k_eControllerType_XBox360Controller:
type = SDL_CONTROLLER_TYPE_XBOX360;
break;
case k_eControllerType_XBoxOneController:
type = SDL_CONTROLLER_TYPE_XBOXONE;
break;
case k_eControllerType_PS3Controller:
type = SDL_CONTROLLER_TYPE_PS3;
break;
case k_eControllerType_PS4Controller:
type = SDL_CONTROLLER_TYPE_PS4;
break;
case k_eControllerType_PS5Controller:
type = SDL_CONTROLLER_TYPE_PS5;
break;
case k_eControllerType_XInputPS4Controller:
if (forUI) {
type = SDL_CONTROLLER_TYPE_PS4;
} else {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
}
break;
case k_eControllerType_SwitchProController:
case k_eControllerType_SwitchInputOnlyController:
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
break;
case k_eControllerType_XInputSwitchController:
if (forUI) {
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
} else {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
}
break;
case k_eControllerType_SwitchJoyConLeft:
case k_eControllerType_SwitchJoyConRight:
/* We always support the Nintendo Online NES Controllers */
if (name && SDL_strncmp(name, "NES Controller", 14) == 0) {
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
} else {
type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
}
break;
default:
break;
}
}
return type;
return SDL_GetJoystickGameControllerType(NULL, vendor, product, -1, 0, 0, 0);
}
SDL_GameControllerType
@@ -2015,24 +1838,154 @@ SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *nam
Uint16 vendor, product;
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_TRUE);
type = SDL_GetJoystickGameControllerType(name, vendor, product, -1, 0, 0, 0);
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
if (SDL_IsJoystickXInput(guid)) {
/* This is probably an Xbox One controller */
return SDL_CONTROLLER_TYPE_XBOXONE;
}
if (SDL_IsJoystickVirtual(guid)) {
return SDL_CONTROLLER_TYPE_VIRTUAL;
}
}
return type;
}
SDL_bool
SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id)
SDL_GameControllerType
SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
EControllerType eType = GuessControllerType(vendor_id, product_id);
return (eType == k_eControllerType_XBoxOneController);
static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF;
static const int XB360_IFACE_SUBCLASS = 93;
static const int XB360_IFACE_PROTOCOL = 1; /* Wired */
static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */
static const int XBONE_IFACE_SUBCLASS = 71;
static const int XBONE_IFACE_PROTOCOL = 208;
SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN;
/* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */
if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
interface_subclass == XB360_IFACE_SUBCLASS &&
(interface_protocol == XB360_IFACE_PROTOCOL ||
interface_protocol == XB360W_IFACE_PROTOCOL)) {
static const int SUPPORTED_VENDORS[] = {
0x0079, /* GPD Win 2 */
0x044f, /* Thrustmaster */
0x045e, /* Microsoft */
0x046d, /* Logitech */
0x056e, /* Elecom */
0x06a3, /* Saitek */
0x0738, /* Mad Catz */
0x07ff, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1038, /* SteelSeries */
0x11c9, /* Nacon */
0x12ab, /* Unknown */
0x1430, /* RedOctane */
0x146b, /* BigBen */
0x1532, /* Razer Sabertooth */
0x15e4, /* Numark */
0x162e, /* Joytech */
0x1689, /* Razer Onza */
0x1949, /* Lab126, Inc. */
0x1bad, /* Harmonix */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
};
int i;
for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
if (vendor == SUPPORTED_VENDORS[i]) {
type = SDL_CONTROLLER_TYPE_XBOX360;
break;
}
}
}
if (interface_number == 0 &&
interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
interface_subclass == XBONE_IFACE_SUBCLASS &&
interface_protocol == XBONE_IFACE_PROTOCOL) {
static const int SUPPORTED_VENDORS[] = {
0x045e, /* Microsoft */
0x0738, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1532, /* Razer Wildcat */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
0x2e24, /* Hyperkin */
};
int i;
for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
if (vendor == SUPPORTED_VENDORS[i]) {
type = SDL_CONTROLLER_TYPE_XBOXONE;
break;
}
}
}
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
if (vendor == 0x0000 && product == 0x0000) {
/* Some devices are only identifiable by their name */
if (name &&
(SDL_strcmp(name, "Lic Pro Controller") == 0 ||
SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
SDL_strcmp(name, "Wireless Gamepad") == 0)) {
/* HORI or PowerA Switch Pro Controller clone */
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
} else if (name && SDL_strcmp(name, "Virtual Joystick") == 0) {
type = SDL_CONTROLLER_TYPE_VIRTUAL;
} else {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
}
} else if (vendor == 0x0001 && product == 0x0001) {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
} else if ((vendor == USB_VENDOR_AMAZON && product == USB_PRODUCT_AMAZON_LUNA_CONTROLLER) ||
(vendor == BLUETOOTH_VENDOR_AMAZON && product == BLUETOOTH_PRODUCT_LUNA_CONTROLLER)) {
type = SDL_CONTROLLER_TYPE_AMAZON_LUNA;
} else if (vendor == USB_VENDOR_GOOGLE && product == USB_PRODUCT_GOOGLE_STADIA_CONTROLLER) {
type = SDL_CONTROLLER_TYPE_GOOGLE_STADIA;
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
} else {
switch (GuessControllerType(vendor, product)) {
case k_eControllerType_XBox360Controller:
type = SDL_CONTROLLER_TYPE_XBOX360;
break;
case k_eControllerType_XBoxOneController:
type = SDL_CONTROLLER_TYPE_XBOXONE;
break;
case k_eControllerType_PS3Controller:
type = SDL_CONTROLLER_TYPE_PS3;
break;
case k_eControllerType_PS4Controller:
type = SDL_CONTROLLER_TYPE_PS4;
break;
case k_eControllerType_PS5Controller:
type = SDL_CONTROLLER_TYPE_PS5;
break;
case k_eControllerType_SwitchProController:
case k_eControllerType_SwitchInputOnlyController:
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
break;
case k_eControllerType_SwitchJoyConLeft:
case k_eControllerType_SwitchJoyConRight:
type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
break;
default:
type = SDL_CONTROLLER_TYPE_UNKNOWN;
break;
}
}
}
return type;
}
SDL_bool
@@ -2196,14 +2149,10 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
MAKE_VIDPID(0x046d, 0xc261), /* Logitech G920 (initial mode) */
MAKE_VIDPID(0x046d, 0xc262), /* Logitech G920 (active mode) */
MAKE_VIDPID(0x046d, 0xc26e), /* Logitech G923 */
MAKE_VIDPID(0x046d, 0xca03), /* Logitech Momo Racing */
MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */
MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */
MAKE_VIDPID(0x044f, 0xb696), /* Thrustmaster T248 */
MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS (normal mode) */
MAKE_VIDPID(0x044f, 0xb66f), /* Thrustmaster T300RS (advanced mode) */
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster T300RS (PS4 mode) */
MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS */
MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */
MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */
MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */
@@ -2241,12 +2190,6 @@ static SDL_bool SDL_IsJoystickProductArcadeStick(Uint32 vidpid)
MAKE_VIDPID(0x1532, 0x0a00), /* Razer Atrox Arcade Stick */
MAKE_VIDPID(0x0f0d, 0x00aa), /* HORI Real Arcade Pro V Hayabusa in Switch Mode */
MAKE_VIDPID(0x20d6, 0xa715), /* PowerA Nintendo Switch Fusion Arcade Stick */
MAKE_VIDPID(0x2c22, 0x2300), /* Qanba Obsidian Arcade Joystick in PS4 Mode */
MAKE_VIDPID(0x2c22, 0x2302), /* Qanba Obsidian Arcade Joystick in PS3 Mode */
MAKE_VIDPID(0x2c22, 0x2303), /* Qanba Obsidian Arcade Joystick in PC Mode */
MAKE_VIDPID(0x2c22, 0x2500), /* Qanba Dragon Arcade Joystick in PS4 Mode */
MAKE_VIDPID(0x2c22, 0x2502), /* Qanba Dragon Arcade Joystick in PS3 Mode */
MAKE_VIDPID(0x2c22, 0x2503), /* Qanba Dragon Arcade Joystick in PC Mode */
};
int i;
@@ -2495,24 +2438,11 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
/* Additional entries */
/*****************************************************************/
MAKE_VIDPID(0x04d9, 0x8008), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x04d9, 0xa292), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x04d9, 0xa293), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x1532, 0x0266), /* Razer Huntman V2 Analog, non-functional DInput device */
MAKE_VIDPID(0x1532, 0x0282), /* Razer Huntman Mini Analog, non-functional DInput device */
MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard */
MAKE_VIDPID(0x0b05, 0x1958), /* ROG Chakram Mouse */
MAKE_VIDPID(0x26ce, 0x01a2), /* ASRock LED Controller */
};
static Uint32 rog_chakram_list[] = {
MAKE_VIDPID(0x0b05, 0x1958), /* ROG Chakram Core Mouse */
MAKE_VIDPID(0x0b05, 0x18e3), /* ROG Chakram (wired) Mouse */
MAKE_VIDPID(0x0b05, 0x18e5), /* ROG Chakram (wireless) Mouse */
MAKE_VIDPID(0x0b05, 0x1a18), /* ROG Chakram X (wired) Mouse */
MAKE_VIDPID(0x0b05, 0x1a1a), /* ROG Chakram X (wireless) Mouse */
MAKE_VIDPID(0x0b05, 0x1a1c), /* ROG Chakram X (Bluetooth) Mouse */
};
unsigned int i;
Uint32 id;
Uint16 vendor;
@@ -2528,20 +2458,14 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
return SDL_TRUE;
}
}
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_ROG_CHAKRAM, SDL_FALSE)) {
for (i = 0; i < SDL_arraysize(rog_chakram_list); ++i) {
if (id == rog_chakram_list[i]) {
return SDL_TRUE;
}
}
}
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_FALSE);
type = SDL_GetJoystickGameControllerType(name, vendor, product, -1, 0, 0, 0);
if ((type == SDL_CONTROLLER_TYPE_PS4 || type == SDL_CONTROLLER_TYPE_PS5) && SDL_IsPS4RemapperRunning()) {
return SDL_TRUE;
}
if (SDL_ShouldIgnoreGameController(name, guid)) {
if (SDL_IsGameControllerNameAndGUID(name, guid) &&
SDL_ShouldIgnoreGameController(name, guid)) {
return SDL_TRUE;
}
@@ -2674,14 +2598,6 @@ Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick)
return version;
}
Uint16 SDL_JoystickGetFirmwareVersion(SDL_Joystick *joystick)
{
if (!SDL_PrivateJoystickValid(joystick)) {
return 0;
}
return joystick->firmware_version;
}
const char *SDL_JoystickGetSerial(SDL_Joystick *joystick)
{
if (!SDL_PrivateJoystickValid(joystick)) {
@@ -2707,31 +2623,74 @@ SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick)
/* convert the guid to a printable string */
void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
{
SDL_GUIDToString(guid, pszGUID, cbGUID);
static const char k_rgchHexToASCII[] = "0123456789abcdef";
int i;
if ((pszGUID == NULL) || (cbGUID <= 0)) {
return;
}
for (i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++) {
/* each input byte writes 2 ascii chars, and might write a null byte. */
/* If we don't have room for next input byte, stop */
unsigned char c = guid.data[i];
*pszGUID++ = k_rgchHexToASCII[c >> 4];
*pszGUID++ = k_rgchHexToASCII[c & 0x0F];
}
*pszGUID = '\0';
}
/*-----------------------------------------------------------------------------
* Purpose: Returns the 4 bit nibble for a hex character
* Input : c -
* Output : unsigned char
*-----------------------------------------------------------------------------*/
static unsigned char nibble(unsigned char c)
{
if ((c >= '0') && (c <= '9')) {
return (c - '0');
}
if ((c >= 'A') && (c <= 'F')) {
return (c - 'A' + 0x0a);
}
if ((c >= 'a') && (c <= 'f')) {
return (c - 'a' + 0x0a);
}
/* received an invalid character, and no real way to return an error */
/* AssertMsg1(false, "Q_nibble invalid hex character '%c' ", c); */
return 0;
}
/* convert the string version of a joystick guid to the struct */
SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
{
return SDL_GUIDFromString(pchGUID);
SDL_JoystickGUID guid;
int maxoutputbytes= sizeof(guid);
size_t len = SDL_strlen(pchGUID);
Uint8 *p;
size_t i;
/* Make sure it's even */
len = (len) & ~0x1;
SDL_memset(&guid, 0x00, sizeof(guid));
p = (Uint8 *)&guid;
for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i+=2, p++) {
*p = (nibble((unsigned char)pchGUID[i]) << 4) | nibble((unsigned char)pchGUID[i+1]);
}
return guid;
}
/* update the power level for this joystick */
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
{
SDL_assert(joystick->ref_count); /* make sure we are calling this only for update, not for initialisation */
if (ePowerLevel != joystick->epowerlevel) {
#if !SDL_EVENTS_DISABLED
if (SDL_GetEventState(SDL_JOYBATTERYUPDATED) == SDL_ENABLE) {
SDL_Event event;
event.type = SDL_JOYBATTERYUPDATED;
event.jbattery.which = joystick->instance_id;
event.jbattery.level = ePowerLevel;
SDL_PushEvent(&event);
}
#endif /* !SDL_EVENTS_DISABLED */
joystick->epowerlevel = ePowerLevel;
}
joystick->epowerlevel = ePowerLevel;
}
/* return its power level */
@@ -2748,7 +2707,9 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
SDL_JoystickTouchpadInfo *touchpad_info;
SDL_JoystickTouchpadFingerInfo *finger_info;
int posted;
#if !SDL_EVENTS_DISABLED
Uint32 event_type;
#endif
if (touchpad < 0 || touchpad >= joystick->ntouchpads) {
return 0;
@@ -2792,6 +2753,7 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
}
}
#if !SDL_EVENTS_DISABLED
if (state == finger_info->state) {
event_type = SDL_CONTROLLERTOUCHPADMOTION;
} else if (state) {
@@ -2799,6 +2761,7 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
} else {
event_type = SDL_CONTROLLERTOUCHPADUP;
}
#endif
/* We ignore events if we don't have keyboard focus, except for touch release */
if (SDL_PrivateJoystickShouldIgnoreEvent()) {

View File

@@ -58,11 +58,9 @@ extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint1
extern char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name);
/* Function to return the type of a controller */
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI);
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product);
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name);
/* Function to return whether a joystick is an Xbox One controller */
extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id);
extern SDL_GameControllerType SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol);
/* Function to return whether a joystick is an Xbox One Elite controller */
extern SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id);
@@ -170,11 +168,6 @@ typedef struct _SDL_GamepadMapping
SDL_InputMapping dpdown;
SDL_InputMapping dpleft;
SDL_InputMapping dpright;
SDL_InputMapping misc1;
SDL_InputMapping paddle1;
SDL_InputMapping paddle2;
SDL_InputMapping paddle3;
SDL_InputMapping paddle4;
SDL_InputMapping leftx;
SDL_InputMapping lefty;
SDL_InputMapping rightx;

View File

@@ -65,10 +65,8 @@ struct _SDL_Joystick
{
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
char *name; /* Joystick name - system dependent */
char *path; /* Joystick path - system dependent */
char *serial; /* Joystick serial */
SDL_JoystickGUID guid; /* Joystick guid */
Uint16 firmware_version; /* Firmware version, if available */
int naxes; /* Number of axis controls on the joystick */
SDL_JoystickAxisInfo *axes;
@@ -120,7 +118,6 @@ struct _SDL_Joystick
};
/* Device bus definitions */
#define SDL_HARDWARE_BUS_VIRTUAL 0x00
#define SDL_HARDWARE_BUS_USB 0x03
#define SDL_HARDWARE_BUS_BLUETOOTH 0x05
@@ -149,9 +146,6 @@ typedef struct _SDL_JoystickDriver
/* Function to get the device-dependent name of a joystick */
const char *(*GetDeviceName)(int device_index);
/* Function to get the device-dependent path of a joystick */
const char *(*GetDevicePath)(int device_index);
/* Function to get the player index of a joystick */
int (*GetDevicePlayerIndex)(int device_index);

View File

@@ -103,7 +103,6 @@ keycode_to_SDL(int keycode)
case AKEYCODE_BUTTON_THUMBR:
button = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
break;
case AKEYCODE_MENU:
case AKEYCODE_BUTTON_START:
button = SDL_CONTROLLER_BUTTON_START;
break;
@@ -558,12 +557,6 @@ ANDROID_JoystickGetDeviceName(int device_index)
return JoystickByDevIndex(device_index)->name;
}
static const char *
ANDROID_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int
ANDROID_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -719,7 +712,6 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickGetCount,
ANDROID_JoystickDetect,
ANDROID_JoystickGetDeviceName,
ANDROID_JoystickGetDevicePath,
ANDROID_JoystickGetDevicePlayerIndex,
ANDROID_JoystickSetDevicePlayerIndex,
ANDROID_JoystickGetDeviceGUID,

View File

@@ -268,15 +268,9 @@ static const char *
BSD_JoystickGetDeviceName(int device_index)
{
if (joydevnames[device_index] != NULL) {
return joydevnames[device_index];
return (joydevnames[device_index]);
}
return joynames[device_index];
}
static const char *
BSD_JoystickGetDevicePath(int device_index)
{
return joynames[device_index];
return (joynames[device_index]);
}
static int
@@ -813,7 +807,6 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
BSD_JoystickGetCount,
BSD_JoystickDetect,
BSD_JoystickGetDeviceName,
BSD_JoystickGetDevicePath,
BSD_JoystickGetDevicePlayerIndex,
BSD_JoystickSetDevicePlayerIndex,
BSD_JoystickGetDeviceGUID,

Some files were not shown because too many files have changed in this diff Show More