early-access version 1988

This commit is contained in:
pineappleEA
2021-08-12 01:07:27 +02:00
parent e37f82ce96
commit 24ddfcbb39
265 changed files with 68343 additions and 5348 deletions
+3 -3
View File
@@ -327,7 +327,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
BOOL attachResult;
DWORD attachError;
unsigned long charsWritten;
DWORD charsWritten;
DWORD consoleMode;
/* Maybe attach console and get stderr handle */
@@ -376,7 +376,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
/* Screen output to stderr, if console was attached. */
if (consoleAttached == 1) {
if (!WriteConsole(stderrHandle, tstr, SDL_tcslen(tstr), &charsWritten, NULL)) {
if (!WriteConsole(stderrHandle, tstr, (DWORD) SDL_tcslen(tstr), &charsWritten, NULL)) {
OutputDebugString(TEXT("Error calling WriteConsole\r\n"));
if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
OutputDebugString(TEXT("Insufficient heap memory to write message\r\n"));
@@ -384,7 +384,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
}
} else if (consoleAttached == 2) {
if (!WriteFile(stderrHandle, output, SDL_strlen(output), &charsWritten, NULL)) {
if (!WriteFile(stderrHandle, output, (DWORD) SDL_strlen(output), &charsWritten, NULL)) {
OutputDebugString(TEXT("Error calling WriteFile\r\n"));
}
}
+8 -7
View File
@@ -72,6 +72,9 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
return SDL_FALSE;
}
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
return (__sync_lock_test_and_set(lock, 1) == 0);
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
return (_InterlockedExchange_acq(lock, 1) == 0);
@@ -82,9 +85,6 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
#elif defined(__WATCOMC__) && defined(__386__)
return _SDL_xchg_watcom(lock, 1) == 0;
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
return (__sync_lock_test_and_set(lock, 1) == 0);
#elif defined(__GNUC__) && defined(__arm__) && \
(defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \
defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
@@ -176,8 +176,12 @@ SDL_AtomicLock(SDL_SpinLock *lock)
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
{
#if defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
#if HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
__sync_lock_release(lock);
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
_InterlockedExchange_rel(lock, 0);
#elif defined(_MSC_VER)
_ReadWriteBarrier();
*lock = 0;
@@ -186,9 +190,6 @@ SDL_AtomicUnlock(SDL_SpinLock *lock)
SDL_CompilerBarrier ();
*lock = 0;
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
__sync_lock_release(lock);
#elif defined(__SOLARIS__)
/* Used for Solaris when not using gcc. */
*lock = 0;
+32 -12
View File
@@ -972,19 +972,39 @@ SDL_AudioInit(const char *driver_name)
driver_name = SDL_getenv("SDL_AUDIODRIVER");
}
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
/* make sure we should even try this driver before doing so... */
const AudioBootStrap *backend = bootstrap[i];
if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) ||
(!driver_name && backend->demand_only)) {
continue;
}
if (driver_name != NULL) {
const char *driver_attempt = driver_name;
while (driver_attempt != NULL && *driver_attempt != 0 && !initialized) {
const char *driver_attempt_end = SDL_strchr(driver_attempt, ',');
size_t driver_attempt_len = (driver_attempt_end != NULL) ? (driver_attempt_end - driver_attempt)
: SDL_strlen(driver_attempt);
tried_to_init = 1;
SDL_zero(current_audio);
current_audio.name = backend->name;
current_audio.desc = backend->desc;
initialized = backend->init(&current_audio.impl);
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 = 1;
SDL_zero(current_audio);
current_audio.name = bootstrap[i]->name;
current_audio.desc = bootstrap[i]->desc;
initialized = bootstrap[i]->init(&current_audio.impl);
break;
}
}
driver_attempt = (driver_attempt_end != NULL) ? (driver_attempt_end + 1) : NULL;
}
} else {
for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
if(bootstrap[i]->demand_only) {
continue;
}
tried_to_init = 1;
SDL_zero(current_audio);
current_audio.name = bootstrap[i]->name;
current_audio.desc = bootstrap[i]->desc;
initialized = bootstrap[i]->init(&current_audio.impl);
}
}
if (!initialized) {
+197 -28
View File
@@ -35,15 +35,33 @@
#define DEBUG_AUDIOSTREAM 0
#ifdef __SSE__
#define HAVE_SSE_INTRINSICS 1
#endif
#ifdef __SSE3__
#define HAVE_SSE3_INTRINSICS 1
#endif
#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
#define HAVE_AVX_INTRINSICS 1
#endif
#if defined __clang__
# if (__clang_major__ < 5) || defined(_MSC_VER) || defined(__SCE__)
# undef HAVE_AVX_INTRINSICS
# endif
#elif defined __GNUC__
# if (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
# undef HAVE_AVX_INTRINSICS
# endif
#endif
#if HAVE_SSE3_INTRINSICS
/* Convert from stereo to mono. Average left and right. */
static void SDLCALL
SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
const __m128 divby2 = _mm_set1_ps(0.5f);
float *dst = (float *) cvt->buf;
const float *src = dst;
int i = cvt->len_cvt / 8;
@@ -51,15 +69,12 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
LOG_DEBUG_CONVERT("stereo", "mono (using SSE3)");
SDL_assert(format == AUDIO_F32SYS);
/* We can only do this if dst is aligned to 16 bytes; since src is the
same pointer and it moves by 2, it can't be forcibly aligned. */
if ((((size_t) dst) & 15) == 0) {
/* Aligned! Do SSE blocks as long as we have 16 bytes available. */
const __m128 divby2 = _mm_set1_ps(0.5f);
while (i >= 4) { /* 4 * float32 */
_mm_store_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_load_ps(src+4)), divby2));
i -= 4; src += 8; dst += 4;
}
/* Do SSE blocks as long as we have 16 bytes available.
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_load_ps(src), _mm_loadu_ps(src+4)), divby2));
i -= 4; src += 8; dst += 4;
}
/* Finish off any leftovers with scalar operations. */
@@ -96,6 +111,139 @@ SDL_ConvertStereoToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
}
}
#if HAVE_AVX_INTRINSICS
/* MSVC will always accept AVX intrinsics when compiling for x64 */
#if defined(__clang__)
#pragma clang attribute push (__attribute__((target("avx"))), apply_to=function)
#elif defined(__GNUC__)
#pragma GCC push_options
#pragma GCC target("avx")
#endif
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
static void SDLCALL
SDL_Convert51ToStereo_AVX(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
float *dst = (float *) cvt->buf;
const float *src = dst;
int i = cvt->len_cvt / (sizeof (float) * 6);
const float two_fifths_f = 1.0f / 2.5f;
const __m256 two_fifths_v = _mm256_set1_ps(two_fifths_f);
const __m256 half = _mm256_set1_ps(0.5f);
LOG_DEBUG_CONVERT("5.1", "stereo (using AVX)");
SDL_assert(format == AUDIO_F32SYS);
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
while (i >= 4) {
__m256 in0 = _mm256_loadu_ps(src + 0); /* 0FL 0FR 0FC 0LF 0BL 0BR 1FL 1FR */
__m256 in1 = _mm256_loadu_ps(src + 8); /* 1FC 1LF 1BL 1BR 2FL 2FR 2FC 2LF */
__m256 in2 = _mm256_loadu_ps(src + 16); /* 2BL 2BR 3FL 3FR 3FC 3LF 3BL 3BR */
/* 0FL 0FR 0FC 0LF 2FL 2FR 2FC 2LF */
__m256 temp0 = _mm256_blend_ps(in0, in1, 0xF0);
/* 1FC 1LF 1BL 1BR 3FC 3LF 3BL 3BR */
__m256 temp1 = _mm256_blend_ps(in1, in2, 0xF0);
/* 0FC 0FC 1FC 1FC 2FC 2FC 3FC 3FC */
__m256 fc_distributed = _mm256_mul_ps(half, _mm256_shuffle_ps(temp0, temp1, _MM_SHUFFLE(0, 0, 2, 2)));
/* 0FL 0FR 1BL 1BR 2FL 2FR 3BL 3BR */
__m256 permuted0 = _mm256_blend_ps(temp0, temp1, 0xCC);
/* 0BL 0BR 1FL 1FR 2BL 2BR 3FL 3FR */
__m256 permuted1 = _mm256_permute2f128_ps(in0, in2, 0x21);
/* 0FL 0FR 1BL 1BR 2FL 2FR 3BL 3BR */
/* + 0BL 0BR 1FL 1FR 2BL 2BR 3FL 3FR */
/* = 0L 0R 1L 1R 2L 2R 3L 3R */
__m256 out = _mm256_add_ps(permuted0, permuted1);
out = _mm256_add_ps(out, fc_distributed);
out = _mm256_mul_ps(out, two_fifths_v);
_mm256_storeu_ps(dst, out);
i -= 4; src += 24; dst += 8;
}
/* Finish off any leftovers with scalar operations. */
while (i) {
const float front_center_distributed = src[2] * 0.5f;
dst[0] = (src[0] + front_center_distributed + src[4]) * two_fifths_f; /* left */
dst[1] = (src[1] + front_center_distributed + src[5]) * two_fifths_f; /* right */
i--; src += 6; dst+=2;
}
cvt->len_cvt /= 3;
if (cvt->filters[++cvt->filter_index]) {
cvt->filters[cvt->filter_index] (cvt, format);
}
}
#if defined(__clang__)
#pragma clang attribute pop
#elif defined(__GNUC__)
#pragma GCC pop_options
#endif
#endif
#if HAVE_SSE_INTRINSICS
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
static void SDLCALL
SDL_Convert51ToStereo_SSE(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
float *dst = (float *) cvt->buf;
const float *src = dst;
int i = cvt->len_cvt / (sizeof (float) * 6);
const float two_fifths_f = 1.0f / 2.5f;
const __m128 two_fifths_v = _mm_set1_ps(two_fifths_f);
const __m128 half = _mm_set1_ps(0.5f);
LOG_DEBUG_CONVERT("5.1", "stereo (using SSE)");
SDL_assert(format == AUDIO_F32SYS);
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
/* Just use unaligned load/stores, if the memory at runtime is */
/* aligned it'll be just as fast on modern processors */
while (i >= 2) {
/* Two 5.1 samples (12 floats) fit nicely in three 128bit */
/* registers. Using shuffles they can be rearranged so that */
/* the conversion math can be vectorized. */
__m128 in0 = _mm_loadu_ps(src); /* 0FL 0FR 0FC 0LF */
__m128 in1 = _mm_loadu_ps(src + 4); /* 0BL 0BR 1FL 1FR */
__m128 in2 = _mm_loadu_ps(src + 8); /* 1FC 1LF 1BL 1BR */
/* 0FC 0FC 1FC 1FC */
__m128 fc_distributed = _mm_mul_ps(half, _mm_shuffle_ps(in0, in2, _MM_SHUFFLE(0, 0, 2, 2)));
/* 0FL 0FR 1BL 1BR */
__m128 blended = _mm_shuffle_ps(in0, in2, _MM_SHUFFLE(3, 2, 1, 0));
/* 0FL 0FR 1BL 1BR */
/* + 0BL 0BR 1FL 1FR */
/* = 0L 0R 1L 1R */
__m128 out = _mm_add_ps(blended, in1);
out = _mm_add_ps(out, fc_distributed);
out = _mm_mul_ps(out, two_fifths_v);
_mm_storeu_ps(dst, out);
i -= 2; src += 12; dst += 4;
}
/* Finish off any leftovers with scalar operations. */
while (i) {
const float front_center_distributed = src[2] * 0.5f;
dst[0] = (src[0] + front_center_distributed + src[4]) * two_fifths_f; /* left */
dst[1] = (src[1] + front_center_distributed + src[5]) * two_fifths_f; /* right */
i--; src += 6; dst+=2;
}
cvt->len_cvt /= 3;
if (cvt->filters[++cvt->filter_index]) {
cvt->filters[cvt->filter_index] (cvt, format);
}
}
#endif
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
static void SDLCALL
@@ -104,6 +252,7 @@ SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
float *dst = (float *) cvt->buf;
const float *src = dst;
int i;
const float two_fifths = 1.0f / 2.5f;
LOG_DEBUG_CONVERT("5.1", "stereo");
SDL_assert(format == AUDIO_F32SYS);
@@ -111,8 +260,8 @@ SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 2) {
const float front_center_distributed = src[2] * 0.5f;
dst[0] = (src[0] + front_center_distributed + src[4]) / 2.5f; /* left */
dst[1] = (src[1] + front_center_distributed + src[5]) / 2.5f; /* right */
dst[0] = (src[0] + front_center_distributed + src[4]) * two_fifths; /* left */
dst[1] = (src[1] + front_center_distributed + src[5]) * two_fifths; /* right */
}
cvt->len_cvt /= 3;
@@ -152,6 +301,7 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
float *dst = (float *) cvt->buf;
const float *src = dst;
int i;
const float two_thirds = 1.0f / 1.5f;
LOG_DEBUG_CONVERT("7.1", "5.1");
SDL_assert(format == AUDIO_F32SYS);
@@ -159,12 +309,12 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8, dst += 6) {
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) / 1.5f; /* FL */
dst[1] = (src[1] + surround_right_distributed) / 1.5f; /* FR */
dst[2] = src[2] / 1.5f; /* CC */
dst[3] = src[3] / 1.5f; /* LFE */
dst[4] = (src[4] + surround_left_distributed) / 1.5f; /* BL */
dst[5] = (src[5] + surround_right_distributed) / 1.5f; /* BR */
dst[0] = (src[0] + surround_left_distributed) * two_thirds; /* FL */
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 */
}
cvt->len_cvt /= 8;
@@ -182,6 +332,7 @@ SDL_Convert51ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format)
float *dst = (float *) cvt->buf;
const float *src = dst;
int i;
const float two_thirds = 1.0f / 1.5f;
LOG_DEBUG_CONVERT("5.1", "quad");
SDL_assert(format == AUDIO_F32SYS);
@@ -190,10 +341,10 @@ SDL_Convert51ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format)
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 4) {
const float front_center_distributed = src[2] * 0.5f;
dst[0] = (src[0] + front_center_distributed) / 1.5f; /* FL */
dst[1] = (src[1] + front_center_distributed) / 1.5f; /* FR */
dst[2] = src[4] / 1.5f; /* BL */
dst[3] = src[5] / 1.5f; /* BR */
dst[0] = (src[0] + front_center_distributed) * two_thirds; /* FL */
dst[1] = (src[1] + front_center_distributed) * two_thirds; /* FR */
dst[2] = src[4] * two_thirds; /* BL */
dst[3] = src[5] * two_thirds; /* BR */
}
cvt->len_cvt /= 6;
@@ -246,8 +397,8 @@ SDL_ConvertStereoTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
lf = src[0];
rf = src[1];
ce = (lf + rf) * 0.5f;
dst[0] = 0.5f * (lf + (lf - ce)); /* FL */
dst[1] = 0.5f * (rf + (rf - ce)); /* FR */
dst[0] = 0.571f * (lf + (lf - 0.5f * ce)); /* FL */
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] = lf; /* BL */
@@ -282,8 +433,8 @@ SDL_ConvertQuadTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
lb = src[2];
rb = src[3];
ce = (lf + rf) * 0.5f;
dst[0] = 0.5f * (lf + (lf - ce)); /* FL */
dst[1] = 0.5f * (rf + (rf - ce)); /* FR */
dst[0] = 0.571f * (lf + (lf - 0.5f * ce)); /* FL */
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 */
@@ -804,8 +955,8 @@ SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, const int dst_channels,
if (cvt->filter_index >= (SDL_AUDIOCVT_MAX_FILTERS-2)) {
return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS-2);
}
cvt->filters[SDL_AUDIOCVT_MAX_FILTERS-1] = (SDL_AudioFilter) (size_t) src_rate;
cvt->filters[SDL_AUDIOCVT_MAX_FILTERS] = (SDL_AudioFilter) (size_t) dst_rate;
cvt->filters[SDL_AUDIOCVT_MAX_FILTERS-1] = (SDL_AudioFilter) (uintptr_t) src_rate;
cvt->filters[SDL_AUDIOCVT_MAX_FILTERS] = (SDL_AudioFilter) (uintptr_t) dst_rate;
if (src_rate < dst_rate) {
const double mult = ((double) dst_rate) / ((double) src_rate);
@@ -1017,7 +1168,25 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
}
/* [7.1 ->] 5.1 -> Stereo [-> Mono] */
if ((src_channels == 6) && (dst_channels <= 2)) {
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51ToStereo) < 0) {
SDL_AudioFilter filter = NULL;
#if HAVE_AVX_INTRINSICS
if (SDL_HasAVX()) {
filter = SDL_Convert51ToStereo_AVX;
}
#endif
#if HAVE_SSE_INTRINSICS
if (!filter && SDL_HasSSE()) {
filter = SDL_Convert51ToStereo_SSE;
}
#endif
if (!filter) {
filter = SDL_Convert51ToStereo;
}
if (SDL_AddAudioCVTFilter(cvt, filter) < 0) {
return -1;
}
src_channels = 2;
+1 -1
View File
@@ -65,7 +65,7 @@ test_device(const int iscapture, const char *fname, int flags, int (*test) (int
* information, making this information inaccessible at
* enumeration time
*/
SDL_AddAudioDevice(iscapture, fname, NULL, (void *) dummyhandle);
SDL_AddAudioDevice(iscapture, fname, NULL, (void *) (uintptr_t) dummyhandle);
}
}
}
+8 -2
View File
@@ -46,6 +46,10 @@
#include "SDL_loadso.h"
#include "../../thread/SDL_systhread.h"
/* should we include monitors in the device list? Set at SDL_Init time */
static SDL_bool include_monitors = SDL_FALSE;
#if (PA_API_VERSION < 12)
/** Return non-zero if the passed state is one of the connected states */
static SDL_INLINE int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
@@ -744,8 +748,8 @@ SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *da
{
SDL_AudioSpec spec;
if (i) {
/* Skip "monitor" sources. These are just output from other sinks. */
if (i->monitor_of_sink == PA_INVALID_INDEX) {
/* Maybe skip "monitor" sources. These are just output from other sinks. */
if (include_monitors || (i->monitor_of_sink == PA_INVALID_INDEX)) {
spec.freq = i->sample_spec.rate;
spec.channels = i->sample_spec.channels;
spec.format = PulseFormatToSDLFormat(i->sample_spec.format);
@@ -834,6 +838,8 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
return 0;
}
include_monitors = SDL_GetHintBoolean(SDL_HINT_AUDIO_INCLUDE_MONITORS, SDL_FALSE);
/* Set the function pointers */
impl->DetectDevices = PULSEAUDIO_DetectDevices;
impl->OpenDevice = PULSEAUDIO_OpenDevice;
+8 -2
View File
@@ -306,8 +306,14 @@ WASAPI_WaitDevice(_THIS)
UINT32 padding = 0;
if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) {
/*SDL_Log("WASAPI EVENT! padding=%u maxpadding=%u", (unsigned int)padding, (unsigned int)maxpadding);*/
if (padding <= maxpadding) {
break;
if (this->iscapture) {
if (padding > 0) {
break;
}
} else {
if (padding <= maxpadding) {
break;
}
}
}
} else if (waitResult != WAIT_TIMEOUT) {
+15 -2
View File
@@ -20,6 +20,7 @@
*/
#include "../../SDL_internal.h"
#include "SDL_dbus.h"
#include "SDL_atomic.h"
#if SDL_USE_LIBDBUS
/* we never link directly to libdbus. */
@@ -113,8 +114,12 @@ LoadDBUSLibrary(void)
return retval;
}
void
SDL_DBus_Init(void)
static SDL_SpinLock spinlock_dbus_init = 0;
/* you must hold spinlock_dbus_init before calling this! */
static void
SDL_DBus_Init_Spinlocked(void)
{
static SDL_bool is_dbus_available = SDL_TRUE;
if (!is_dbus_available) {
@@ -156,6 +161,14 @@ SDL_DBus_Init(void)
}
}
void
SDL_DBus_Init(void)
{
SDL_AtomicLock(&spinlock_dbus_init); /* make sure two threads can't init at same time, since this can happen before SDL_Init. */
SDL_DBus_Init_Spinlocked();
SDL_AtomicUnlock(&spinlock_dbus_init);
}
void
SDL_DBus_Quit(void)
{
+9
View File
@@ -44,8 +44,17 @@ WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
{
TCHAR buffer[1024];
char *message;
TCHAR *p = buffer;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0,
buffer, SDL_arraysize(buffer), NULL);
/* kill CR/LF that FormatMessage() sticks at the end */
while (*p) {
if (*p == '\r') {
*p = 0;
break;
}
++p;
}
message = WIN_StringToUTF8(buffer);
SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message);
SDL_free(message);
-66
View File
@@ -119,68 +119,6 @@ int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
return 0;
}
static void SDLCALL
WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue)
{
SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
/* HACK: prevent SDL from altering an app's .appxmanifest-set orientation
* from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS
* is getting registered.
*
* TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'.
*/
if ((oldValue == NULL) && (newValue == NULL)) {
return;
}
// Start with no orientation flags, then add each in as they're parsed
// from newValue.
unsigned int orientationFlags = 0;
if (newValue) {
std::istringstream tokenizer(newValue);
while (!tokenizer.eof()) {
std::string orientationName;
std::getline(tokenizer, orientationName, ' ');
if (orientationName == "LandscapeLeft") {
orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
} else if (orientationName == "LandscapeRight") {
orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
} else if (orientationName == "Portrait") {
orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
} else if (orientationName == "PortraitUpsideDown") {
orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
}
}
}
// If no valid orientation flags were specified, use a reasonable set of defaults:
if (!orientationFlags) {
// TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
orientationFlags = (unsigned int) ( \
DisplayOrientations::Landscape |
DisplayOrientations::LandscapeFlipped |
DisplayOrientations::Portrait |
DisplayOrientations::PortraitFlipped);
}
// Set the orientation/rotation preferences. Please note that this does
// not constitute a 100%-certain lock of a given set of possible
// orientations. According to Microsoft's documentation on WinRT [1]
// when a device is not capable of being rotated, Windows may ignore
// the orientation preferences, and stick to what the device is capable of
// displaying.
//
// [1] Documentation on the 'InitialRotationPreference' setting for a
// Windows app's manifest file describes how some orientation/rotation
// preferences may be ignored. See
// http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
// for details. Microsoft's "Display orientation sample" also gives an
// outline of how Windows treats device rotation
// (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations) orientationFlags;
}
static void
WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange()
{
@@ -397,10 +335,6 @@ void SDL_WinRTApp::SetWindow(CoreWindow^ window)
ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
#endif
// Register the hint, SDL_HINT_ORIENTATIONS, with SDL.
// TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly.
SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL);
#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps)
// Make sure we know when a user has opened the app's settings pane.
// This is needed in order to display a privacy policy, which needs
+8 -4
View File
@@ -1025,6 +1025,13 @@ SDL_GetSystemRAM(void)
}
}
#endif
#ifdef __VITA__
if (SDL_SystemRAM <= 0) {
/* Vita has 512MiB on SoC, that's split into 256MiB(+109MiB in extended memory mode) for app
+26MiB of physically continuous memory, +112MiB of CDRAM(VRAM) + system reserved memory. */
SDL_SystemRAM = 536870912;
}
#endif
#endif
}
return SDL_SystemRAM;
@@ -1080,9 +1087,6 @@ SDL_SIMDRealloc(void *mem, const size_t len)
ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *));
if (ptr == mem) {
return retval; /* Pointer didn't change, nothing to do */
}
if (ptr == NULL) {
return NULL; /* Out of memory, bail! */
}
@@ -1095,7 +1099,7 @@ SDL_SIMDRealloc(void *mem, const size_t len)
if (mem) {
ptrdiff = ((size_t) retval) - ((size_t) ptr);
if (memdiff != ptrdiff) { /* Delta has changed, copy to new offset! */
oldmem = (void*) (((size_t) ptr) + memdiff);
oldmem = (void*) (((uintptr_t) ptr) + memdiff);
/* Even though the data past the old `len` is undefined, this is the
* only length value we have, and it guarantees that we copy all the
+3
View File
@@ -812,3 +812,6 @@
#define SDL_TLSCleanup SDL_TLSCleanup_REAL
#define SDL_SetWindowAlwaysOnTop SDL_SetWindowAlwaysOnTop_REAL
#define SDL_FlashWindow SDL_FlashWindow_REAL
#define SDL_GameControllerSendEffect SDL_GameControllerSendEffect_REAL
#define SDL_JoystickSendEffect SDL_JoystickSendEffect_REAL
#define SDL_GameControllerGetSensorDataRate SDL_GameControllerGetSensorDataRate_REAL
+4 -1
View File
@@ -876,4 +876,7 @@ SDL_DYNAPI_PROC(int,SDL_AndroidShowToast,(const char *a, int b, int c, int d, in
SDL_DYNAPI_PROC(int,SDL_GetAudioDeviceSpec,(int a, int b, SDL_AudioSpec *c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_TLSCleanup,(void),(),)
SDL_DYNAPI_PROC(void,SDL_SetWindowAlwaysOnTop,(SDL_Window *a, SDL_bool b),(a,b),)
SDL_DYNAPI_PROC(int,SDL_FlashWindow,(SDL_Window *a, Uint32 b),(a, b),return)
SDL_DYNAPI_PROC(int,SDL_FlashWindow,(SDL_Window *a, SDL_FlashOperation b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerSendEffect,(SDL_GameController *a, const void *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_JoystickSendEffect,(SDL_Joystick *a, const void *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(float,SDL_GameControllerGetSensorDataRate,(SDL_GameController *a, SDL_SensorType b),(a,b),return)
+10 -3
View File
@@ -596,6 +596,9 @@ SDL_SendWakeupEvent()
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
if (_this->wakeup_window) {
_this->SendWakeupEvent(_this, _this->wakeup_window);
/* No more wakeup events needed until we enter a new wait */
_this->wakeup_window = NULL;
}
if (_this->wakeup_lock) {
SDL_UnlockMutex(_this->wakeup_lock);
@@ -785,10 +788,14 @@ SDL_PollEvent(SDL_Event * event)
static int
SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event, int timeout)
{
/* Release any keys held down from last frame */
SDL_ReleaseAutoReleaseKeys();
for (;;) {
/* Pump events on entry and each time we wake to ensure:
a) All pending events are batch processed after waking up from a wait
b) Waiting can be completely skipped if events are already available to be pumped
c) Periodic processing that takes place in some platform PumpEvents() functions happens
*/
SDL_PumpEvents();
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
int status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
/* If status == 0 we are going to block so wakeup will be needed. */
+5 -2
View File
@@ -605,6 +605,9 @@ SDL_SetKeymap(int start, SDL_Keycode * keys, int length)
void
SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
{
if (scancode >= SDL_NUM_SCANCODES) {
return;
}
SDL_scancode_names[scancode] = name;
}
@@ -675,7 +678,7 @@ SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode scancode)
Uint32 type;
Uint8 repeat = SDL_FALSE;
if (scancode == SDL_SCANCODE_UNKNOWN) {
if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
return 0;
}
@@ -800,7 +803,7 @@ SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode scancode)
allowing the user to escape the application */
SDL_MinimizeWindow(keyboard->focus);
}
return (posted);
}
+3 -4
View File
@@ -819,11 +819,10 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
mouse->scale_accum_y = 0.0f;
if (enabled && focusWindow) {
/* Center it in the focused window to prevent clicks from going through
* to background windows.
*/
SDL_SetMouseFocus(focusWindow);
SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
if (mouse->relative_mode_warp)
SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
}
if (mouse->focus) {
+3 -1
View File
@@ -68,7 +68,9 @@ SDL_GetBasePath(void)
path = (WCHAR *) ptr;
len = pGetModuleFileNameExW(GetCurrentProcess(), NULL, path, buflen);
if (len != buflen) {
/* if it truncated, then len >= buflen - 1 */
/* if there was enough room (or failure), len < buflen - 1 */
if (len < buflen - 1) {
break;
}
+37 -2
View File
@@ -1088,7 +1088,32 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned ch
return -1; // Controller was disconnected
}
// TODO: Implement timeout?
static uint32_t getms()
{
struct timeval now;
gettimeofday(&now, NULL);
return (uint32_t)(now.tv_sec * 1000 + now.tv_usec / 1000);
}
static void delayms(uint32_t ms)
{
int was_error;
struct timespec elapsed, tv;
/* Set the timeout interval */
elapsed.tv_sec = ms / 1000;
elapsed.tv_nsec = (ms % 1000) * 1000000;
do {
errno = 0;
tv.tv_sec = elapsed.tv_sec;
tv.tv_nsec = elapsed.tv_nsec;
was_error = nanosleep(&tv, &elapsed);
} while (was_error && (errno == EINTR));
}
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
{
if ( device )
@@ -1097,7 +1122,17 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned ch
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice )
{
return pDevice->GetInput( data, length );
int nResult = pDevice->GetInput( data, length );
if ( nResult == 0 && milliseconds > 0 )
{
uint32_t start = getms();
do
{
delayms( 1 );
nResult = pDevice->GetInput( data, length );
} while ( nResult == 0 && ( getms() - start ) < milliseconds );
}
return nResult;
}
LOGV( "controller was disconnected" );
}
+4 -1
View File
@@ -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)
+2 -2
View File
@@ -97,8 +97,8 @@ extern "C" {
} /* extern "C" */
#endif
#include <stdio.h>
#include <stdlib.h>
/*#include <stdio.h>*/
/*#include <stdlib.h>*/
#include "../hidapi/hidapi.h"
+68 -15
View File
@@ -485,7 +485,7 @@ static ControllerMapping_t *SDL_CreateMappingForAndroidController(SDL_JoystickGU
/* Accelerometer, shouldn't have a game controller mapping */
return NULL;
}
if (!(button_mask & face_button_mask) || !axis_mask) {
if (!(button_mask & face_button_mask)) {
/* We don't know what buttons or axes are supported, don't make up a mapping */
return NULL;
}
@@ -590,8 +590,8 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
/* 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));
if (SDL_IsJoystickXboxOneSeriesX(vendor, product)) {
/* XBox One Series X Controllers have a share button under the guide button */
if (SDL_IsJoystickXboxSeriesX(vendor, product)) {
/* XBox Series X Controllers have a share button under the guide button */
SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string));
} else if (SDL_IsJoystickXboxOneElite(vendor, product)) {
/* XBox One Elite Controllers have 4 back paddle buttons */
@@ -615,18 +615,22 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
/* Joy-Cons have extra buttons in the same place as paddles */
if (SDL_IsJoystickNintendoSwitchJoyConLeft(vendor, product)) {
SDL_strlcat(mapping_string, "paddle2:b17,paddle4:b19,", sizeof(mapping_string));
}
else if (SDL_IsJoystickNintendoSwitchJoyConRight(vendor, product)) {
} else if (SDL_IsJoystickNintendoSwitchJoyConRight(vendor, product)) {
SDL_strlcat(mapping_string, "paddle1:b16,paddle3:b18,", sizeof(mapping_string));
}
break;
case SDL_CONTROLLER_TYPE_AMAZON_LUNA:
/* Amazon Luna Controller has a mic button under the guide button */
SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string));
break;
case SDL_CONTROLLER_TYPE_GOOGLE_STADIA:
/* The Google Stadia controller has a share button and a Google Assistant button */
SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string));
break;
default:
if (vendor == 0 && product == 0) {
/* This is a Bluetooth Nintendo Switch Pro controller */
SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string));
} else if (vendor == USB_VENDOR_GOOGLE && product == USB_PRODUCT_GOOGLE_STADIA_CONTROLLER) {
/* The Google Stadia controller has a share button and a Google Assistant button */
SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string));
}
break;
}
@@ -652,6 +656,25 @@ static ControllerMapping_t *SDL_CreateMappingForRAWINPUTController(SDL_JoystickG
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
/*
* Helper function to guess at a mapping for WGI controllers
*/
static ControllerMapping_t *SDL_CreateMappingForWGIController(SDL_JoystickGUID guid)
{
SDL_bool existing;
char mapping_string[1024];
if (guid.data[15] != SDL_JOYSTICK_TYPE_GAMECONTROLLER) {
return NULL;
}
SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string));
SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:b10,dpdown:b12,dpleft:b13,dpright:b11,leftx:a1,lefty:a0~,rightx:a3,righty:a2~,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
return SDL_PrivateAddMappingForGUID(guid, mapping_string,
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
/*
* Helper function to scan the mappings database for a controller with the specified GUID
*/
@@ -684,6 +707,9 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
if (!mapping && SDL_IsJoystickRAWINPUT(guid)) {
mapping = SDL_CreateMappingForRAWINPUTController(guid);
}
if (!mapping && SDL_IsJoystickWGI(guid)) {
mapping = SDL_CreateMappingForWGIController(guid);
}
}
return mapping;
}
@@ -1156,15 +1182,12 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const
mapping = SDL_PrivateAddMappingForGUID(guid,
"none,X360 Wireless Controller,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",
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
} else if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) {
mapping = s_pXInputMapping;
}
}
#endif /* __LINUX__ */
if (!mapping && name && !SDL_IsJoystickWGI(guid)) {
if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) {
mapping = s_pXInputMapping;
}
}
if (!mapping) {
mapping = s_pDefaultMapping;
}
@@ -1779,11 +1802,12 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
/* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */
/* https://partner.steamgames.com/doc/features/steam_controller/steam_input_gamepad_emulation_bestpractices */
SDL_bool bSteamVirtualGamepad = SDL_FALSE;
#if defined(__LINUX__)
bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
bSteamVirtualGamepad = (vendor == USB_VENDOR_VALVE && product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD);
#elif defined(__MACOSX__)
bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1);
bSteamVirtualGamepad = (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 1);
#elif defined(__WIN32__)
/* We can't tell on Windows, but Steam will block others in input hooks */
bSteamVirtualGamepad = SDL_TRUE;
@@ -2175,6 +2199,29 @@ SDL_bool SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, S
return SDL_FALSE;
}
/*
* Get the data rate of a game controller sensor.
*/
float
SDL_GameControllerGetSensorDataRate(SDL_GameController *gamecontroller, SDL_SensorType type)
{
SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller);
int i;
if (!joystick) {
return 0.0f;
}
for (i = 0; i < joystick->nsensors; ++i) {
SDL_JoystickSensorInfo *sensor = &joystick->sensors[i];
if (sensor->type == type) {
return sensor->rate;
}
}
return 0.0f;
}
/*
* Get the current state of a game controller sensor.
*/
@@ -2406,6 +2453,12 @@ SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 gr
return SDL_JoystickSetLED(SDL_GameControllerGetJoystick(gamecontroller), red, green, blue);
}
int
SDL_GameControllerSendEffect(SDL_GameController *gamecontroller, const void *data, int size)
{
return SDL_JoystickSendEffect(SDL_GameControllerGetJoystick(gamecontroller), data, size);
}
void
SDL_GameControllerClose(SDL_GameController *gamecontroller)
{
+35 -13
View File
@@ -35,9 +35,14 @@ static const char *s_ControllerMappings [] =
"xinput,XInput 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,",
#endif
#if SDL_JOYSTICK_WGI
"03000000491900001904000000007700,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,",
"03000000d11800000094000000007700,Google Stadia 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:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
"030000007e0500000920000000007701,Nintendo Switch Pro Controller,a:b1,b:b0,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:b3,y:b2,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"030000007e0500000920000000007701,Nintendo Switch Pro Controller,a:b0,b:b1,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:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"030000004c050000c405000000007701,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,",
"030000004c050000e60c000000007700,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:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"0300000032150000000a000000007703,Razer Atrox Arcade Stick,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,x:b2,y:b3,",
"03000000de280000ff11000000007701,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a4,leftx:a1,lefty:a0~,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a2~,start:b7,x:b2,y:b3,",
#endif
#if SDL_JOYSTICK_DINPUT
"03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,",
@@ -95,6 +100,7 @@ static const char *s_ControllerMappings [] =
"030000006f0e00001901000000000000,Afterglow 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,",
"030000006f0e00001a01000000000000,Afterglow 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,",
"03000000d62000001d57000000000000,Airflo 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,",
"03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,",
"03000000d62000002a79000000000000,BDA PS4 Fightpad,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,",
"03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,",
"03000000d6200000e557000000000000,Batarang,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,",
@@ -127,6 +133,8 @@ static const char *s_ControllerMappings [] =
"030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
"030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,",
"78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,",
"03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,",
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,",
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,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:a4,start:b9,x:b3,y:b0,",
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,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,",
"03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,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:a3,righty:a2,start:b9,x:b3,y:b0,",
@@ -146,6 +154,7 @@ static const char *s_ControllerMappings [] =
"03000000f0250000c383000000000000,Gioteck VX2 Controller,a:b2,b:b1,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:b3,y:b0,",
"03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,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:b3,y:b0,",
"03000000f0250000c283000000000000,Gioteck,a:b2,b:b1,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:b3,y:b0,",
"03000000d11800000094000000000000,Google Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
"03000000632500002605000000000000,HJD-X,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:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
"030000000d0f00008400000000000000,HORI Fighting Commander,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:a5,start:b9,x:b0,y:b3,",
"030000000d0f00008500000000000000,HORI Fighting Commander,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,",
@@ -208,6 +217,7 @@ static const char *s_ControllerMappings [] =
"030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,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:b2,y:b3,",
"030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,",
"03000000152000000182000000000000,NGDS,a:b2,b:b1,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:a3,righty:a4,start:b9,x:b3,y:b0,",
"030000005509000000b4000000000000,NVIDIA Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"030000004b120000014d000000000000,NYKO AIRFLO EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,",
"03000000790000004318000000000000,Nintendo GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000790000004318000000000000,Nintendo GameCube Controller,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -297,7 +307,7 @@ static const char *s_ControllerMappings [] =
"030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,",
"030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,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:b3,y:b0,",
"03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,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:b3,y:b0,",
"03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
"03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
"03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,",
"03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
@@ -317,7 +327,6 @@ static const char *s_ControllerMappings [] =
"03000000d90400000200000000000000,TwinShock PS2,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,",
"03000000300f00000701000000000000,USB 4-Axis 12-Button Gamepad,a:b2,b:b1,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:a3,righty:a2,start:b9,x:b3,y:b0,",
"03000000341a00002308000000000000,USB Gamepad,a:b0,b:b1,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:b2,y:b3,",
"030000005509000000b4000000000000,USB Gamepad,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,",
"030000006b1400000203000000000000,USB Gamepad,a:b0,b:b1,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:b2,y:b3,",
"03000000790000000a00000000000000,USB Gamepad,a:b2,b:b1,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:a4,start:b9,x:b3,y:b0,",
"03000000f0250000c183000000000000,USB 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
@@ -375,7 +384,8 @@ static const char *s_ControllerMappings [] =
"03000000a00500003232000008010000,8BitDo Zero Gamepad,a:b1,b:b2,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000a00500003232000009010000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000a00500003232000009010000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000710100001904000000010000,Amazon Luna Gamepad,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,",
"03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,",
"03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,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,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"03000000d62000002a79000000010000,BDA PS4 Fightpad,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,",
@@ -384,10 +394,13 @@ static const char *s_ControllerMappings [] =
"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,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:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,",
"030000000d0f00008400000000010000,Fighting Commander,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,",
"030000000d0f00008500000000010000,Fighting Commander,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,",
"03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,",
"03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,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:a3,righty:a4,start:b9,x:b3,y:b0,",
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,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:b2,y:b3,",
"03000000c01100000140000000010000,GameStop PS4 Fun 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,",
"03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,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,",
"03000000d11800000094000000010000,Google Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
"030000000d0f00005f00000000000000,HORI Fighting Commander 4 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,",
"030000000d0f00005e00000000000000,HORI Fighting Commander 4 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000000d0f00004d00000000000000,HORI Gem Pad 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,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
@@ -446,8 +459,8 @@ static const char *s_ControllerMappings [] =
"03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,",
"030000004c050000cc09000000000000,Sony DualShock 4 V2,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,",
"030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,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,",
"03000000d11800000094000000010000,Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
"030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,",
"050000004e696d6275732b0000000000,SteelSeries Nimbus+,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,",
"03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,",
"03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,",
"03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,",
@@ -537,15 +550,17 @@ static const char *s_ControllerMappings [] =
"030000006f0e00003901000000430000,Afterglow Prismatic 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,",
"030000006f0e00001302000000010000,Afterglow,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,",
"03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
"03000000503200000110000000000000,Atari Classic Controller,a:b0,x:b1,back:b2,guide:b4,start:b3,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2",
"05000000503200000110000000000000,Atari Classic Controller,a:b0,x:b1,back:b2,guide:b4,start:b3,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2",
"03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,x:b3,y:b2,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
"05000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,x:b3,y:b2,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
"05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"05000000710100001904000000010000,Amazon Luna Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,",
"05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"03000000790000003018000011010000,Arcade Fightstick F300,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,start:b9,x:b0,y:b3,",
"03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,",
"05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,",
"03000000503200000210000000000000,Atari Game 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:b3,y:b2,",
"05000000503200000210000000000000,Atari Game 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:b3,y:b2,",
"03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,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,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"03000000d62000002a79000011010000,BDA PS4 Fightpad,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,",
"03000000120c0000f70e000011010000,Brook Universal Fighting Board,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:,lefty:,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:,righty:,start:b9,x:b0,y:b3,",
"03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,",
"03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,",
"03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,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:b3,y:b0,",
@@ -553,6 +568,8 @@ static const char *s_ControllerMappings [] =
"03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,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:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,",
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,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:a3,righty:a4,start:b9,x:b3,y:b0,",
"030000006f0e00003001000001010000,EA Sports 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,",
"03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"0300000079000000d418000000010000,GPD Win 2 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,",
"0500000047532067616d657061640000,GS Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,",
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,",
@@ -563,6 +580,7 @@ static const char *s_ControllerMappings [] =
"030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) Gamepad,a:b2,b:b1,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:b3,y:b0,",
"030000006f0e00001304000000010000,Generic X-Box 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,",
"03000000f0250000c183000010010000,Goodbetterbest Ltd USB 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,",
"03000000d11800000094000011010000,Google Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
"03000000280400000140000000010000,Gravis Gamepad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
"030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,",
"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,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:a3,righty:a2,start:b9,x:b2,y:b3,",
@@ -675,7 +693,9 @@ static const char *s_ControllerMappings [] =
"050000004c050000cc09000000010000,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,",
"050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,",
"050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,",
"030000004c050000e60c000000010000,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,",
"030000004c050000e60c000011010000,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,",
"030000004c050000e60c000011810000,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,",
"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,",
"030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,",
"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,",
@@ -716,7 +736,6 @@ static const char *s_ControllerMappings [] =
"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,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:a2,righty:a3,start:b8,x:b3,y:b0,",
"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,",
"03000000d11800000094000011010000,Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,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,",
"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,",
"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,",
@@ -758,6 +777,7 @@ static const char *s_ControllerMappings [] =
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
"050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"050000005e040000050b000003090000,Xbox One Elite Series 2,a:b0,b:b1,back:b121,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,",
"050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"030000005e040000ea02000000000000,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,",
"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,",
@@ -773,7 +793,6 @@ static const char *s_ControllerMappings [] =
"050000006964726f69643a636f6e0000,idroid:con,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,",
"03000000b50700001503000010010000,impact,a:b2,b:b3,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:a3,righty:a2,start:b9,x:b0,y:b1,",
"030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,",
"03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,righttrigger:b7,",
#endif
#if defined(__ANDROID__)
"05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b0,b:b1,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -808,6 +827,7 @@ static const char *s_ControllerMappings [] =
"05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000b404000011240000dfff3f00,Flydigi Vader 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"05000000d6020000e5890000dfff3f00,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,",
"0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
@@ -834,10 +854,10 @@ static const char *s_ControllerMappings [] =
"050000005e040000e002000000783f00,Xbox One S Controller,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,",
"050000005e040000ea02000000783f00,Xbox One S Controller,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,",
"050000005e040000fd020000ff7f3f00,Xbox One S Controller,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,",
"050000005e040000120b000000783f00,Xbox One Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,",
"050000005e040000130b0000ffff3f00,Xbox One Series X Controller,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,",
"050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,",
"050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,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,",
"050000005e040000120b000000783f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,",
"050000005e040000130b0000ffff3f00,Xbox Series X Controller,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,",
"050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", /* The DPAD doesn't seem to work on this controller on Android TV? */
"050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,",
"0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -858,6 +878,8 @@ static const char *s_ControllerMappings [] =
"05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,",
"050000005e040000050b0000df070001,Xbox Elite 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,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
"050000005e040000050b0000ff070001,Xbox Elite 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,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"050000005e040000130b0000df870001,Xbox Series X 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,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
"050000005e040000130b0000ff870001,Xbox Series X 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,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"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
+119 -34
View File
@@ -96,7 +96,7 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = {
&SDL_VIRTUAL_JoystickDriver,
#endif
#ifdef SDL_JOYSTICK_VITA
&SDL_VITA_JoystickDriver
&SDL_VITA_JoystickDriver,
#endif
#if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED)
&SDL_DUMMY_JoystickDriver
@@ -986,6 +986,24 @@ SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
return result;
}
int
SDL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
int result;
if (!SDL_PrivateJoystickValid(joystick)) {
return -1;
}
SDL_LockJoysticks();
result = joystick->driver->SendEffect(joystick, data, size);
SDL_UnlockJoysticks();
return result;
}
/*
* Close a joystick previously opened with SDL_JoystickOpen()
*/
@@ -1144,7 +1162,7 @@ void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers)
}
}
void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type)
void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate)
{
int nsensors = joystick->nsensors + 1;
SDL_JoystickSensorInfo *sensors = (SDL_JoystickSensorInfo *)SDL_realloc(joystick->sensors, (nsensors * sizeof(SDL_JoystickSensorInfo)));
@@ -1153,6 +1171,7 @@ void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type)
SDL_zerop(sensor);
sensor->type = type;
sensor->rate = rate;
joystick->nsensors = nsensors;
joystick->sensors = sensors;
@@ -1672,6 +1691,7 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
{ "Performance Designed Products", "PDP" },
{ "HORI CO.,LTD.", "HORI" },
{ "HORI CO.,LTD", "HORI" },
{ "Unknown ", "" },
};
const char *custom_name;
char *name;
@@ -1732,6 +1752,17 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
}
}
/* Perform any manufacturer replacements */
for (i = 0; i < SDL_arraysize(replacements); ++i) {
size_t prefixlen = SDL_strlen(replacements[i].prefix);
if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
size_t replacementlen = SDL_strlen(replacements[i].replacement);
SDL_memcpy(name, replacements[i].replacement, replacementlen);
SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1));
break;
}
}
/* Remove duplicate manufacturer or product in the name */
for (i = 1; i < (len - 1); ++i) {
int matchlen = PrefixMatch(name, &name[i]);
@@ -1746,17 +1777,6 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
}
}
/* Perform any manufacturer replacements */
for (i = 0; i < SDL_arraysize(replacements); ++i) {
size_t prefixlen = SDL_strlen(replacements[i].prefix);
if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
size_t replacementlen = SDL_strlen(replacements[i].replacement);
SDL_memcpy(name, replacements[i].replacement, replacementlen);
SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1));
break;
}
}
return name;
}
@@ -1879,6 +1899,16 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc
} 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:
@@ -1927,16 +1957,25 @@ SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id)
}
SDL_bool
SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id)
SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id)
{
if (vendor_id == USB_VENDOR_MICROSOFT) {
if (product_id == USB_PRODUCT_XBOX_ONE_SERIES_X ||
product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH) {
if (product_id == USB_PRODUCT_XBOX_SERIES_X ||
product_id == USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH) {
return SDL_TRUE;
}
}
if (vendor_id == USB_VENDOR_PDP) {
if (product_id == USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT ||
product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE ||
product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW) {
return SDL_TRUE;
}
}
if (vendor_id == USB_VENDOR_POWERA_ALT) {
if (product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_POWERA) {
if ((product_id >= 0x2001 && product_id <= 0x201a) ||
product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 ||
product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA) {
return SDL_TRUE;
}
}
@@ -1950,7 +1989,7 @@ SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id)
if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH ||
product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH ||
product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH ||
product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH) {
product_id == USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH) {
return SDL_TRUE;
}
}
@@ -1976,7 +2015,8 @@ SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id)
{
EControllerType eType = GuessControllerType(vendor_id, product_id);
return (eType == k_eControllerType_SwitchProController ||
eType == k_eControllerType_SwitchInputOnlyController);
eType == k_eControllerType_SwitchInputOnlyController ||
(vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP));
}
SDL_bool
@@ -2059,6 +2099,7 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
MAKE_VIDPID(0x046d, 0xc260), /* Logitech G29 (PS4) */
MAKE_VIDPID(0x046d, 0xc261), /* Logitech G920 (initial mode) */
MAKE_VIDPID(0x046d, 0xc262), /* Logitech G920 (active mode) */
MAKE_VIDPID(0x046d, 0xc26e), /* Logitech G923 */
MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */
MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */
@@ -2077,11 +2118,46 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
return SDL_FALSE;
}
static SDL_bool SDL_IsJoystickProductArcadeStick(Uint32 vidpid)
{
static Uint32 arcadestick_joysticks[] = {
MAKE_VIDPID(0x0079, 0x181a), /* Venom Arcade Stick */
MAKE_VIDPID(0x0f0d, 0x006a), /* Real Arcade Pro 4 */
MAKE_VIDPID(0x0079, 0x181b), /* Venom Arcade Stick */
MAKE_VIDPID(0x0c12, 0x0ef6), /* Hitbox Arcade Stick */
MAKE_VIDPID(0x0f0d, 0x008a), /* HORI Real Arcade Pro 4 */
MAKE_VIDPID(0x0f0d, 0x0016), /* Hori Real Arcade Pro.EX */
MAKE_VIDPID(0x0f0d, 0x001b), /* Hori Real Arcade Pro VX */
MAKE_VIDPID(0x0f0d, 0x008c), /* Hori Real Arcade Pro 4 */
MAKE_VIDPID(0x1bad, 0xf03d), /* Street Fighter IV Arcade Stick TE - Chun Li */
MAKE_VIDPID(0x1bad, 0xf502), /* Hori Real Arcade Pro.VX SA */
MAKE_VIDPID(0x1bad, 0xf504), /* Hori Real Arcade Pro. EX */
MAKE_VIDPID(0x1bad, 0xf506), /* Hori Real Arcade Pro.EX Premium VLX */
MAKE_VIDPID(0x24c6, 0x5000), /* Razer Atrox Arcade Stick */
MAKE_VIDPID(0x24c6, 0x5501), /* Hori Real Arcade Pro VX-SA */
MAKE_VIDPID(0x24c6, 0x550e), /* Hori Real Arcade Pro V Kai 360 */
MAKE_VIDPID(0x0f0d, 0x0063), /* Hori Real Arcade Pro Hayabusa (USA) Xbox One */
MAKE_VIDPID(0x0f0d, 0x0078), /* Hori Real Arcade Pro V Kai Xbox One */
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 */
};
int i;
for (i = 0; i < SDL_arraysize(arcadestick_joysticks); ++i) {
if (vidpid == arcadestick_joysticks[i]) {
return SDL_TRUE;
}
}
return SDL_FALSE;
}
static SDL_bool SDL_IsJoystickProductFlightStick(Uint32 vidpid)
{
static Uint32 flightstick_joysticks[] = {
MAKE_VIDPID(0x044f, 0x0402), /* HOTAS Warthog Joystick */
MAKE_VIDPID(0x0738, 0x2221), /* Saitek Pro Flight X-56 Rhino Stick */
MAKE_VIDPID(0x044f, 0xb10a), /* ThrustMaster, Inc. T.16000M Joystick */
};
int i;
@@ -2156,6 +2232,10 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
return SDL_JOYSTICK_TYPE_WHEEL;
}
if (SDL_IsJoystickProductArcadeStick(vidpid)) {
return SDL_JOYSTICK_TYPE_ARCADE_STICK;
}
if (SDL_IsJoystickProductFlightStick(vidpid)) {
return SDL_JOYSTICK_TYPE_FLIGHT_STICK;
}
@@ -2304,6 +2384,13 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
MAKE_VIDPID(0x2516, 0x001f), /* Cooler Master Storm Mizar Mouse */
MAKE_VIDPID(0x2516, 0x0028), /* Cooler Master Storm Alcor Mouse */
/*****************************************************************/
/* Additional entries */
/*****************************************************************/
/* Anne Pro II Keyboard */
MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard */
};
unsigned int i;
@@ -2661,25 +2748,23 @@ int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, const
if (sensor->type == type) {
if (sensor->enabled) {
num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
if (SDL_memcmp(data, sensor->data, num_values*sizeof(*data)) != 0) {
/* Update internal sensor state */
SDL_memcpy(sensor->data, data, num_values*sizeof(*data));
/* Update internal sensor state */
SDL_memcpy(sensor->data, data, num_values*sizeof(*data));
/* Post the event, if desired */
/* Post the event, if desired */
#if !SDL_EVENTS_DISABLED
if (SDL_GetEventState(SDL_CONTROLLERSENSORUPDATE) == SDL_ENABLE) {
SDL_Event event;
event.type = SDL_CONTROLLERSENSORUPDATE;
event.csensor.which = joystick->instance_id;
event.csensor.sensor = type;
num_values = SDL_min(num_values, SDL_arraysize(event.csensor.data));
SDL_memset(event.csensor.data, 0, sizeof(event.csensor.data));
SDL_memcpy(event.csensor.data, data, num_values*sizeof(*data));
posted = SDL_PushEvent(&event) == 1;
}
#endif /* !SDL_EVENTS_DISABLED */
if (SDL_GetEventState(SDL_CONTROLLERSENSORUPDATE) == SDL_ENABLE) {
SDL_Event event;
event.type = SDL_CONTROLLERSENSORUPDATE;
event.csensor.which = joystick->instance_id;
event.csensor.sensor = type;
num_values = SDL_min(num_values, SDL_arraysize(event.csensor.data));
SDL_memset(event.csensor.data, 0, sizeof(event.csensor.data));
SDL_memcpy(event.csensor.data, data, num_values*sizeof(*data));
posted = SDL_PushEvent(&event) == 1;
}
#endif /* !SDL_EVENTS_DISABLED */
}
break;
}
+3 -3
View File
@@ -65,8 +65,8 @@ extern SDL_GameControllerType SDL_GetJoystickGameControllerType(const char *name
/* Function to return whether a joystick is an Xbox One Elite controller */
extern SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick is an Xbox One Series X controller */
extern SDL_bool SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick is an Xbox Series X controller */
extern SDL_bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick is an Xbox One controller connected via Bluetooth */
extern SDL_bool SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id);
@@ -116,7 +116,7 @@ extern void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick);
/* Internal event queueing functions */
extern void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers);
extern void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type);
extern void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate);
extern void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance);
extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance);
extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick,
+4
View File
@@ -56,6 +56,7 @@ typedef struct _SDL_JoystickSensorInfo
{
SDL_SensorType type;
SDL_bool enabled;
float rate;
float data[3]; /* If this needs to expand, update SDL_ControllerSensorEvent */
} SDL_JoystickSensorInfo;
@@ -166,6 +167,9 @@ typedef struct _SDL_JoystickDriver
SDL_bool (*HasLED)(SDL_Joystick *joystick);
int (*SetLED)(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
/* General effects */
int (*SendEffect)(SDL_Joystick *joystick, const void *data, int size);
/* Sensor functionality */
int (*SetSensorsEnabled)(SDL_Joystick *joystick, SDL_bool enabled);
+14 -7
View File
@@ -581,7 +581,7 @@ ANDROID_JoystickGetDeviceInstanceID(int device_index)
}
static int
ANDROID_JoystickOpen(SDL_Joystick * joystick, int device_index)
ANDROID_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
SDL_joylist_item *item = JoystickByDevIndex(device_index);
@@ -605,25 +605,31 @@ ANDROID_JoystickOpen(SDL_Joystick * joystick, int device_index)
}
static int
ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
ANDROID_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
return SDL_Unsupported();
}
static int
ANDROID_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
ANDROID_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}
static SDL_bool
ANDROID_JoystickHasLED(SDL_Joystick * joystick)
ANDROID_JoystickHasLED(SDL_Joystick *joystick)
{
return SDL_FALSE;
}
static int
ANDROID_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
ANDROID_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static int
ANDROID_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
@@ -635,7 +641,7 @@ ANDROID_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
}
static void
ANDROID_JoystickUpdate(SDL_Joystick * joystick)
ANDROID_JoystickUpdate(SDL_Joystick *joystick)
{
SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
@@ -664,7 +670,7 @@ ANDROID_JoystickUpdate(SDL_Joystick * joystick)
}
static void
ANDROID_JoystickClose(SDL_Joystick * joystick)
ANDROID_JoystickClose(SDL_Joystick *joystick)
{
SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
if (item) {
@@ -715,6 +721,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickRumbleTriggers,
ANDROID_JoystickHasLED,
ANDROID_JoystickSetLED,
ANDROID_JoystickSendEffect,
ANDROID_JoystickSetSensorsEnabled,
ANDROID_JoystickUpdate,
ANDROID_JoystickClose,
+7
View File
@@ -789,6 +789,12 @@ BSD_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
return SDL_Unsupported();
}
static int
BSD_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
BSD_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -810,6 +816,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
BSD_JoystickRumbleTriggers,
BSD_JoystickHasLED,
BSD_JoystickSetLED,
BSD_JoystickSendEffect,
BSD_JoystickSetSensorsEnabled,
BSD_JoystickUpdate,
BSD_JoystickClose,
+50 -16
View File
@@ -51,7 +51,7 @@ typedef enum
k_eControllerType_SwitchJoyConLeft = 39,
k_eControllerType_SwitchJoyConRight = 40,
k_eControllerType_SwitchJoyConPair = 41,
k_eControllerType_SwitchInputOnlyController = 42,
k_eControllerType_SwitchInputOnlyController = 42,
k_eControllerType_MobileTouch = 43,
k_eControllerType_XInputSwitchController = 44, // Client-side only, used to mark Switch-compatible controllers as not supporting Switch controller protocol
k_eControllerType_PS5Controller = 45,
@@ -160,7 +160,7 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x1532, 0x1009 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Ultimate BT
{ MAKE_CONTROLLER_ID( 0x1532, 0x100A ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Tournament edition BT
{ MAKE_CONTROLLER_ID( 0x1532, 0x1100 ), k_eControllerType_PS4Controller, NULL }, // Razer RAION Fightpad - Trackpad, no gyro, lightbar hardcoded to green
{ MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller, NULL }, // PowerA - Fusion Fight Pad
{ MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller, NULL }, // PowerA Fusion Fight Pad
{ MAKE_CONTROLLER_ID( 0x7545, 0x0104 ), k_eControllerType_PS4Controller, NULL }, // Armor 3 or Level Up Cobra - At least one variant has gyro
{ MAKE_CONTROLLER_ID( 0x9886, 0x0025 ), k_eControllerType_PS4Controller, NULL }, // Astro C40
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0207 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro Fightstick w/ Touchpad for PS4
@@ -175,6 +175,7 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x146b, 0x1103 ), k_eControllerType_PS4Controller, NULL }, // NACON Asymetrical Controller -- on windows this doesn't enumerate
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0123 ), k_eControllerType_PS4Controller, NULL }, // HORI Wireless Controller Light (Japan only) - only over bt- over usb is xbox and pid 0x0124
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d13 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution 3
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0e20 ), k_eControllerType_PS4Controller, NULL }, // Brook Mars Controller - needs FW update to show up as Ps4 controller on PC. Has Gyro but touchpad is a single button.
{ MAKE_CONTROLLER_ID( 0x054c, 0x0ce6 ), k_eControllerType_PS5Controller, NULL }, // Sony PS5 Controller
@@ -255,7 +256,7 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x1689, 0xfd00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza Tournament Edition
{ MAKE_CONTROLLER_ID( 0x1689, 0xfd01 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza Classic Edition
{ MAKE_CONTROLLER_ID( 0x1689, 0xfe00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Sabertooth
{ MAKE_CONTROLLER_ID( 0x1949, 0x041a ), k_eControllerType_XBox360Controller, "Amazon Luna Gamepad" }, // Amazon Luna Gamepad
{ MAKE_CONTROLLER_ID( 0x1949, 0x041a ), k_eControllerType_XBox360Controller, "Amazon Luna Controller" }, // Amazon Luna Controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0x0002 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Rock Band Guitar
{ MAKE_CONTROLLER_ID( 0x1bad, 0x0003 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Rock Band Drumkit
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf016 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Xbox 360 Controller
@@ -325,8 +326,8 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, NULL }, // Microsoft X-Box One controller with XBOXGIP driver on Windows
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Series X pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Series X pad (Bluetooth)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad (Bluetooth)
{ MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController, NULL }, // Mad Catz FightStick TE 2
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x013B ), k_eControllerType_XBoxOneController, "PDP Xbox One Face-Off Controller" }, // PDP Face-Off Gamepad for Xbox One
@@ -392,6 +393,9 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02d5 ), k_eControllerType_XBoxOneController, "PDP Xbox One Red Camo" }, // PDP Wired Controller for Xbox One - Red Camo
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0346 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0446 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02da ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Afterglow" }, // PDP Xbox Series X Afterglow
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02d6 ), k_eControllerType_XBoxOneController, "Victrix Gambit Tournament Controller" }, // Victrix Gambit Tournament Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02d9 ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Midnight Blue" }, // PDP Xbox Series X Midnight Blue
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0063 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro Hayabusa (USA) Xbox One
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0067 ), k_eControllerType_XBoxOneController, NULL }, // HORIPAD ONE
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0078 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro V Kai Xbox One
@@ -399,7 +403,30 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x1532, 0x0a00 ), k_eControllerType_XBoxOneController, NULL }, // Razer Atrox Arcade Stick
{ MAKE_CONTROLLER_ID( 0x1532, 0x0a03 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wildcat
{ MAKE_CONTROLLER_ID( 0x1532, 0x0a14 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Ultimate
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2001 ), k_eControllerType_XBoxOneController, "PowerA Xbox One Series X Controller" }, // PowerA Xbox One Series X Wired Controller
{ MAKE_CONTROLLER_ID( 0x1532, 0x0a15 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Tournament Edition
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2001 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Black Inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2002 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Gray/White Inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2003 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Green Inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2004 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Pink inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2005 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller Core - Black
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2006 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller Core - White
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2009 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Red inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200a ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Blue inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200b ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Camo Metallic Red
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200c ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Camo Metallic Blue
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200d ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Seafoam Fade
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200e ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Midnight Blue
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200f ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Soldier Green
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2011 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired - Metallic Ice
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2012 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Cuphead EnWired Controller - Mugman
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2015 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Blue Hint
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2016 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Green Hint
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2017 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Cntroller - Arctic Camo
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2018 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Arc Lightning
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2019 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Royal Purple
{ MAKE_CONTROLLER_ID( 0x20d6, 0x201a ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Nebula
{ MAKE_CONTROLLER_ID( 0x20d6, 0x4001 ), k_eControllerType_XBoxOneController, "PowerA Fusion Pro 2 Controller" }, // PowerA Fusion Pro 2 Wired Controller (Xbox Series X style)
{ MAKE_CONTROLLER_ID( 0x20d6, 0x4002 ), k_eControllerType_XBoxOneController, "PowerA Spectra Infinity Controller" }, // PowerA Spectra Infinity Wired Controller (Xbox Series X style)
{ MAKE_CONTROLLER_ID( 0x24c6, 0x541a ), k_eControllerType_XBoxOneController, NULL }, // PowerA Xbox One Mini Wired Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x542a ), k_eControllerType_XBoxOneController, NULL }, // Xbox ONE spectra
{ MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController, "PowerA Xbox One Controller" }, // PowerA Xbox ONE liquid metal controller
@@ -518,7 +545,11 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0xf0d, 0xd8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xfff, 0x2a1 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x45e, 0x867 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
// Added 12-17-2020
{ MAKE_CONTROLLER_ID( 0x16d0, 0xf3f ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0x8f ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0xf501 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
//{ MAKE_CONTROLLER_ID( 0x1949, 0x0402 ), /*android*/, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x05ac, 0x0001 ), k_eControllerType_AppleController, NULL }, // MFI Extended Gamepad (generic entry for iOS/tvOS)
@@ -544,19 +575,22 @@ static const ControllerDescription_t arrControllers[] = {
#else
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00dc ), k_eControllerType_SwitchProController, "HORI Fighting Commander" },
#endif
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Wired Fight Pad Pro for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0180 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Wired Pro Controller for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0181 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Deluxe Wired Pro Controller for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa711 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Wired Controller Plus/PowerA Wired Controller Nintendo GameCube Style
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa712 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA - Fusion Fight Pad
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa713 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA - Super Mario Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0186 ), k_eControllerType_SwitchProController, NULL }, // PDP Afterglow Wireless Switch Controller - working gyro. USB doesn't work
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0184 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Wired Deluxe+ Audio Controller
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00aa ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Real Arcade Pro V Hayabusa in Switch Mode
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0188 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Afterglow Wired Deluxe+ Audio Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Wired Fight Pad Pro for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0186 ), k_eControllerType_SwitchProController, NULL }, // PDP Afterglow Wireless Switch Controller - working gyro. USB is for charging only. Many later "Wireless" line devices w/ gyro also use this vid/pid
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0187 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Rockcandy Wired Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0188 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Afterglow Wired Deluxe+ Audio Controller
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00aa ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Real Arcade Pro V Hayabusa in Switch Mode
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa711 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Wired Controller Plus/PowerA Wired Controller Nintendo GameCube Style
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa712 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Fusion Fight Pad
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa713 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Super Mario Controller
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa714 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Spectra Controller
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa715 ), k_eControllerType_SwitchInputOnlyController, NULL }, // Power A Fusion Wireless Arcade Stick (USB Mode) Over BT is shows up as 057e 2009
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa716 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Fusion Pro Controller - USB requires toggling switch on back of device
// Valve products - don't add to public list
// Valve products
{ MAKE_CONTROLLER_ID( 0x0000, 0x11fb ), k_eControllerType_MobileTouch, NULL }, // Streaming mobile touch virtual controls
{ MAKE_CONTROLLER_ID( 0x28de, 0x1101 ), k_eControllerType_SteamController, NULL }, // Valve Legacy Steam Controller (CHELL)
{ MAKE_CONTROLLER_ID( 0x28de, 0x1102 ), k_eControllerType_SteamController, NULL }, // Valve wired Steam Controller (D0G)
@@ -691,11 +725,11 @@ static SDL_INLINE int GetDefaultDeadzoneSizeForControllerType( EControllerType e
case k_eControllerType_AppleController:
case k_eControllerType_AndroidController:
case k_eControllerType_PS3Controller:
case k_eControllerType_PS5Controller:
return 10000;
case k_eControllerType_SteamControllerV2:
return 8192;
case k_eControllerType_PS4Controller:
case k_eControllerType_PS5Controller:
return 4096;
case k_eControllerType_SwitchJoyConLeft:
case k_eControllerType_SwitchJoyConRight:
+14 -7
View File
@@ -784,7 +784,7 @@ DARWIN_JoystickGetDeviceInstanceID(int device_index)
}
static int
DARWIN_JoystickOpen(SDL_Joystick * joystick, int device_index)
DARWIN_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
recDevice *device = GetDeviceForIndex(device_index);
@@ -894,7 +894,7 @@ DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude)
}
static int
DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
DARWIN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
HRESULT result;
recDevice *device = joystick->hwdata;
@@ -934,19 +934,25 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
}
static int
DARWIN_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
DARWIN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}
static SDL_bool
DARWIN_JoystickHasLED(SDL_Joystick * joystick)
DARWIN_JoystickHasLED(SDL_Joystick *joystick)
{
return SDL_FALSE;
}
static int
DARWIN_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
DARWIN_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static int
DARWIN_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
@@ -958,7 +964,7 @@ DARWIN_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
}
static void
DARWIN_JoystickUpdate(SDL_Joystick * joystick)
DARWIN_JoystickUpdate(SDL_Joystick *joystick)
{
recDevice *device = joystick->hwdata;
recElement *element;
@@ -1063,7 +1069,7 @@ DARWIN_JoystickUpdate(SDL_Joystick * joystick)
}
static void
DARWIN_JoystickClose(SDL_Joystick * joystick)
DARWIN_JoystickClose(SDL_Joystick *joystick)
{
recDevice *device = joystick->hwdata;
if (device) {
@@ -1107,6 +1113,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
DARWIN_JoystickRumbleTriggers,
DARWIN_JoystickHasLED,
DARWIN_JoystickSetLED,
DARWIN_JoystickSendEffect,
DARWIN_JoystickSetSensorsEnabled,
DARWIN_JoystickUpdate,
DARWIN_JoystickClose,
+7
View File
@@ -107,6 +107,12 @@ DUMMY_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
return SDL_Unsupported();
}
static int
DUMMY_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
DUMMY_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -149,6 +155,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
DUMMY_JoystickRumbleTriggers,
DUMMY_JoystickHasLED,
DUMMY_JoystickSetLED,
DUMMY_JoystickSendEffect,
DUMMY_JoystickSetSensorsEnabled,
DUMMY_JoystickUpdate,
DUMMY_JoystickClose,
@@ -426,6 +426,12 @@ EMSCRIPTEN_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8
return SDL_Unsupported();
}
static int
EMSCRIPTEN_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
EMSCRIPTEN_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -447,6 +453,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
EMSCRIPTEN_JoystickRumbleTriggers,
EMSCRIPTEN_JoystickHasLED,
EMSCRIPTEN_JoystickSetLED,
EMSCRIPTEN_JoystickSendEffect,
EMSCRIPTEN_JoystickSetSensorsEnabled,
EMSCRIPTEN_JoystickUpdate,
EMSCRIPTEN_JoystickClose,
+7
View File
@@ -281,6 +281,12 @@ extern "C"
return SDL_Unsupported();
}
static int HAIKU_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int HAIKU_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
return SDL_Unsupported();
@@ -301,6 +307,7 @@ extern "C"
HAIKU_JoystickRumbleTriggers,
HAIKU_JoystickHasLED,
HAIKU_JoystickSetLED,
HAIKU_JoystickSendEffect,
HAIKU_JoystickSetSensorsEnabled,
HAIKU_JoystickUpdate,
HAIKU_JoystickClose,
@@ -476,6 +476,12 @@ HIDAPI_DriverGameCube_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *jo
return SDL_Unsupported();
}
static int
HIDAPI_DriverGameCube_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverGameCube_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -528,6 +534,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
HIDAPI_DriverGameCube_RumbleJoystickTriggers,
HIDAPI_DriverGameCube_HasJoystickLED,
HIDAPI_DriverGameCube_SetJoystickLED,
HIDAPI_DriverGameCube_SendJoystickEffect,
HIDAPI_DriverGameCube_SetJoystickSensorsEnabled,
HIDAPI_DriverGameCube_CloseJoystick,
HIDAPI_DriverGameCube_FreeDevice,
+456
View File
@@ -0,0 +1,456 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#include "SDL_hints.h"
#include "SDL_events.h"
#include "SDL_joystick.h"
#include "SDL_gamecontroller.h"
#include "../SDL_sysjoystick.h"
#include "SDL_hidapijoystick_c.h"
#include "SDL_hidapi_rumble.h"
#ifdef SDL_JOYSTICK_HIDAPI_LUNA
/* Define this if you want to log all packets from the controller */
/*#define DEBUG_LUNA_PROTOCOL*/
enum
{
SDL_CONTROLLER_BUTTON_LUNA_MIC = 15,
SDL_CONTROLLER_NUM_LUNA_BUTTONS,
};
typedef struct {
Uint8 last_state[USB_PACKET_LENGTH];
} SDL_DriverLuna_Context;
static SDL_bool
HIDAPI_DriverLuna_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
return (type == SDL_CONTROLLER_TYPE_AMAZON_LUNA) ? SDL_TRUE : SDL_FALSE;
}
static const char *
HIDAPI_DriverLuna_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Amazon Luna Controller";
}
static SDL_bool
HIDAPI_DriverLuna_InitDevice(SDL_HIDAPI_Device *device)
{
return HIDAPI_JoystickConnected(device, NULL);
}
static int
HIDAPI_DriverLuna_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id)
{
return -1;
}
static void
HIDAPI_DriverLuna_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index)
{
}
static SDL_bool
HIDAPI_DriverLuna_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
SDL_DriverLuna_Context *ctx;
ctx = (SDL_DriverLuna_Context *)SDL_calloc(1, sizeof(*ctx));
if (!ctx) {
SDL_OutOfMemory();
return SDL_FALSE;
}
device->dev = hid_open_path(device->path, 0);
if (!device->dev) {
SDL_SetError("Couldn't open %s", device->path);
SDL_free(ctx);
return SDL_FALSE;
}
device->context = ctx;
/* Initialize the joystick capabilities */
joystick->nbuttons = SDL_CONTROLLER_NUM_LUNA_BUTTONS;
joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
joystick->serial = NULL;
return SDL_TRUE;
}
static int
HIDAPI_DriverLuna_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
if (device->product_id == BLUETOOTH_PRODUCT_LUNA_CONTROLLER) {
/* Same packet as on Xbox One controllers connected via Bluetooth */
Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB };
/* Magnitude is 1..100 so scale the 16-bit input here */
rumble_packet[4] = low_frequency_rumble / 655;
rumble_packet[5] = high_frequency_rumble / 655;
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
return SDL_SetError("Couldn't send rumble packet");
}
return 0;
} else {
/* FIXME: Is there a rumble packet over USB? */
return SDL_Unsupported();
}
}
static int
HIDAPI_DriverLuna_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}
static SDL_bool
HIDAPI_DriverLuna_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
return SDL_FALSE;
}
static int
HIDAPI_DriverLuna_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverLuna_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverLuna_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
return SDL_Unsupported();
}
static void
HIDAPI_DriverLuna_HandleUSBStatePacket(SDL_Joystick *joystick, SDL_DriverLuna_Context *ctx, Uint8 *data, int size)
{
if (ctx->last_state[1] != data[1]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[1] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[1] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[1] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[1] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[1] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[1] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[1] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
}
if (ctx->last_state[2] != data[2]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LUNA_MIC, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[2] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[2] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
}
if (ctx->last_state[3] != data[3]) {
SDL_bool dpad_up = SDL_FALSE;
SDL_bool dpad_down = SDL_FALSE;
SDL_bool dpad_left = SDL_FALSE;
SDL_bool dpad_right = SDL_FALSE;
switch (data[3] & 0xf) {
case 0:
dpad_up = SDL_TRUE;
break;
case 1:
dpad_up = SDL_TRUE;
dpad_right = SDL_TRUE;
break;
case 2:
dpad_right = SDL_TRUE;
break;
case 3:
dpad_right = SDL_TRUE;
dpad_down = SDL_TRUE;
break;
case 4:
dpad_down = SDL_TRUE;
break;
case 5:
dpad_left = SDL_TRUE;
dpad_down = SDL_TRUE;
break;
case 6:
dpad_left = SDL_TRUE;
break;
case 7:
dpad_up = SDL_TRUE;
dpad_left = SDL_TRUE;
break;
default:
break;
}
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
}
#define READ_STICK_AXIS(offset) \
(data[offset] == 0x7f ? 0 : \
(Sint16)HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16))
{
Sint16 axis = READ_STICK_AXIS(4);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
axis = READ_STICK_AXIS(5);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
axis = READ_STICK_AXIS(6);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
axis = READ_STICK_AXIS(7);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
}
#undef READ_STICK_AXIS
#define READ_TRIGGER_AXIS(offset) \
(Sint16)HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16)
{
Sint16 axis = READ_TRIGGER_AXIS(8);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
axis = READ_TRIGGER_AXIS(9);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
}
#undef READ_TRIGGER_AXIS
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}
static void
HIDAPI_DriverLuna_HandleBluetoothStatePacket(SDL_Joystick *joystick, SDL_DriverLuna_Context *ctx, Uint8 *data, int size)
{
if (size >= 2 && data[0] == 0x02) {
/* Home button has dedicated report */
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x1) ? SDL_PRESSED : SDL_RELEASED);
return;
}
if (size >= 2 && data[0] == 0x04) {
/* Battery level report */
int level = data[1] * 100 / 0xFF;
if (level == 0) {
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
}
else if (level <= 20) {
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
}
else if (level <= 70) {
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
}
else {
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
return;
}
if (size < 17 || data[0] != 0x01) {
/* We don't know how to handle this report */
return;
}
if (ctx->last_state[13] != data[13]) {
SDL_bool dpad_up = SDL_FALSE;
SDL_bool dpad_down = SDL_FALSE;
SDL_bool dpad_left = SDL_FALSE;
SDL_bool dpad_right = SDL_FALSE;
switch (data[13] & 0xf) {
case 1:
dpad_up = SDL_TRUE;
break;
case 2:
dpad_up = SDL_TRUE;
dpad_right = SDL_TRUE;
break;
case 3:
dpad_right = SDL_TRUE;
break;
case 4:
dpad_right = SDL_TRUE;
dpad_down = SDL_TRUE;
break;
case 5:
dpad_down = SDL_TRUE;
break;
case 6:
dpad_left = SDL_TRUE;
dpad_down = SDL_TRUE;
break;
case 7:
dpad_left = SDL_TRUE;
break;
case 8:
dpad_up = SDL_TRUE;
dpad_left = SDL_TRUE;
break;
default:
break;
}
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
}
if (ctx->last_state[14] != data[14]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED);
}
if (ctx->last_state[15] != data[15]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x20) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
}
if (ctx->last_state[16] != data[16]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LUNA_MIC, (data[16] & 0x02) ? SDL_PRESSED : SDL_RELEASED);
}
#define READ_STICK_AXIS(offset) \
(data[offset] == 0x7f ? 0 : \
(Sint16)HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16))
{
Sint16 axis = READ_STICK_AXIS(2);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
axis = READ_STICK_AXIS(4);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
axis = READ_STICK_AXIS(6);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
axis = READ_STICK_AXIS(8);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
}
#undef READ_STICK_AXIS
#define READ_TRIGGER_AXIS(offset) \
(Sint16)HIDAPI_RemapVal((float)((int)(((data[offset] | (data[offset + 1] << 8)) & 0x3ff) - 0x200)), 0x00 - 0x200, 0x3ff - 0x200, SDL_MIN_SINT16, SDL_MAX_SINT16)
{
Sint16 axis = READ_TRIGGER_AXIS(9);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
axis = READ_TRIGGER_AXIS(11);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
}
#undef READ_TRIGGER_AXIS
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}
static SDL_bool
HIDAPI_DriverLuna_UpdateDevice(SDL_HIDAPI_Device *device)
{
SDL_DriverLuna_Context *ctx = (SDL_DriverLuna_Context *)device->context;
SDL_Joystick *joystick = NULL;
Uint8 data[USB_PACKET_LENGTH];
int size = 0;
if (device->num_joysticks > 0) {
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
}
if (!joystick) {
return SDL_FALSE;
}
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
#ifdef DEBUG_LUNA_PROTOCOL
HIDAPI_DumpPacket("Amazon Luna packet: size = %d", data, size);
#endif
switch (size) {
case 10:
HIDAPI_DriverLuna_HandleUSBStatePacket(joystick, ctx, data, size);
break;
default:
HIDAPI_DriverLuna_HandleBluetoothStatePacket(joystick, ctx, data, size);
break;
}
}
if (size < 0) {
/* Read error, device is disconnected */
HIDAPI_JoystickDisconnected(device, joystick->instance_id);
}
return (size >= 0);
}
static void
HIDAPI_DriverLuna_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
SDL_LockMutex(device->dev_lock);
{
if (device->dev) {
hid_close(device->dev);
device->dev = NULL;
}
SDL_free(device->context);
device->context = NULL;
}
SDL_UnlockMutex(device->dev_lock);
}
static void
HIDAPI_DriverLuna_FreeDevice(SDL_HIDAPI_Device *device)
{
}
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna =
{
SDL_HINT_JOYSTICK_HIDAPI_LUNA,
SDL_TRUE,
HIDAPI_DriverLuna_IsSupportedDevice,
HIDAPI_DriverLuna_GetDeviceName,
HIDAPI_DriverLuna_InitDevice,
HIDAPI_DriverLuna_GetDevicePlayerIndex,
HIDAPI_DriverLuna_SetDevicePlayerIndex,
HIDAPI_DriverLuna_UpdateDevice,
HIDAPI_DriverLuna_OpenJoystick,
HIDAPI_DriverLuna_RumbleJoystick,
HIDAPI_DriverLuna_RumbleJoystickTriggers,
HIDAPI_DriverLuna_HasJoystickLED,
HIDAPI_DriverLuna_SetJoystickLED,
HIDAPI_DriverLuna_SendJoystickEffect,
HIDAPI_DriverLuna_SetJoystickSensorsEnabled,
HIDAPI_DriverLuna_CloseJoystick,
HIDAPI_DriverLuna_FreeDevice,
};
#endif /* SDL_JOYSTICK_HIDAPI_LUNA */
#endif /* SDL_JOYSTICK_HIDAPI */
/* vi: set ts=4 sw=4 expandtab: */
+63 -46
View File
@@ -146,6 +146,8 @@ typedef struct {
} SDL_DriverPS4_Context;
static int HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size);
static SDL_bool
HIDAPI_DriverPS4_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
@@ -385,61 +387,26 @@ static int
HIDAPI_DriverPS4_UpdateEffects(SDL_HIDAPI_Device *device)
{
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
DS4EffectsState_t *effects;
Uint8 data[78];
int report_size, offset;
if (!ctx->effects_supported) {
return SDL_Unsupported();
}
DS4EffectsState_t effects;
if (!ctx->enhanced_mode) {
return SDL_Unsupported();
}
SDL_zero(data);
SDL_zero(effects);
if (ctx->is_bluetooth) {
data[0] = k_EPS4ReportIdBluetoothEffects;
data[1] = 0xC0 | 0x04; /* Magic value HID + CRC, also sets interval to 4ms for samples */
data[3] = 0x03; /* 0x1 is rumble, 0x2 is lightbar, 0x4 is the blink interval */
report_size = 78;
offset = 6;
} else {
data[0] = k_EPS4ReportIdUsbEffects;
data[1] = 0x07; /* Magic value */
report_size = 32;
offset = 4;
}
effects = (DS4EffectsState_t *)&data[offset];
effects->ucRumbleLeft = ctx->rumble_left;
effects->ucRumbleRight = ctx->rumble_right;
effects.ucRumbleLeft = ctx->rumble_left;
effects.ucRumbleRight = ctx->rumble_right;
/* Populate the LED state with the appropriate color from our lookup table */
if (ctx->color_set) {
effects->ucLedRed = ctx->led_red;
effects->ucLedGreen = ctx->led_green;
effects->ucLedBlue = ctx->led_blue;
effects.ucLedRed = ctx->led_red;
effects.ucLedGreen = ctx->led_green;
effects.ucLedBlue = ctx->led_blue;
} else {
SetLedsForPlayerIndex(effects, ctx->player_index);
SetLedsForPlayerIndex(&effects, ctx->player_index);
}
if (ctx->is_bluetooth) {
/* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
Uint32 unCRC;
unCRC = SDL_crc32(0, &ubHdr, 1);
unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
}
if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) {
return SDL_SetError("Couldn't send rumble packet");
}
return 0;
return HIDAPI_DriverPS4_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects));
}
static void
@@ -465,8 +432,8 @@ HIDAPI_DriverPS4_SetEnhancedMode(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
ctx->enhanced_mode = SDL_TRUE;
SDL_PrivateJoystickAddTouchpad(joystick, 2);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f);
HIDAPI_DriverPS4_UpdateEffects(device);
}
@@ -650,6 +617,55 @@ HIDAPI_DriverPS4_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
return HIDAPI_DriverPS4_UpdateEffects(device);
}
static int
HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size)
{
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
Uint8 data[78];
int report_size, offset;
if (!ctx->effects_supported) {
return SDL_Unsupported();
}
if (!ctx->enhanced_mode) {
HIDAPI_DriverPS4_SetEnhancedMode(device, joystick);
}
SDL_zero(data);
if (ctx->is_bluetooth) {
data[0] = k_EPS4ReportIdBluetoothEffects;
data[1] = 0xC0 | 0x04; /* Magic value HID + CRC, also sets interval to 4ms for samples */
data[3] = 0x03; /* 0x1 is rumble, 0x2 is lightbar, 0x4 is the blink interval */
report_size = 78;
offset = 6;
} else {
data[0] = k_EPS4ReportIdUsbEffects;
data[1] = 0x07; /* Magic value */
report_size = 32;
offset = 4;
}
SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size));
if (ctx->is_bluetooth) {
/* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
Uint32 unCRC;
unCRC = SDL_crc32(0, &ubHdr, 1);
unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
}
if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) {
return SDL_SetError("Couldn't send rumble packet");
}
return 0;
}
static int
HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -921,6 +937,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
HIDAPI_DriverPS4_RumbleJoystickTriggers,
HIDAPI_DriverPS4_HasJoystickLED,
HIDAPI_DriverPS4_SetJoystickLED,
HIDAPI_DriverPS4_SendJoystickEffect,
HIDAPI_DriverPS4_SetJoystickSensorsEnabled,
HIDAPI_DriverPS4_CloseJoystick,
HIDAPI_DriverPS4_FreeDevice,
+85 -66
View File
@@ -175,6 +175,8 @@ typedef struct {
} SDL_DriverPS5_Context;
static int HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size);
static SDL_bool
HIDAPI_DriverPS5_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
@@ -375,32 +377,13 @@ static int
HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, int effect_mask)
{
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
DS5EffectsState_t *effects;
Uint8 data[78];
int report_size, offset;
Uint8 *pending_data;
int *pending_size;
int maximum_size;
DS5EffectsState_t effects;
if (!ctx->enhanced_mode) {
return SDL_Unsupported();
}
SDL_zero(data);
if (ctx->is_bluetooth) {
data[0] = k_EPS5ReportIdBluetoothEffects;
data[1] = 0x02; /* Magic value */
report_size = 78;
offset = 2;
} else {
data[0] = k_EPS5ReportIdUsbEffects;
report_size = 48;
offset = 1;
}
effects = (DS5EffectsState_t *)&data[offset];
SDL_zero(effects);
/* Make sure the Bluetooth connection sequence has completed before sending LED color change */
if (ctx->is_bluetooth &&
@@ -412,79 +395,53 @@ HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, int effect_mask)
}
if (ctx->rumble_left || ctx->rumble_right) {
effects->ucEnableBits1 |= 0x01; /* Enable rumble emulation */
effects->ucEnableBits1 |= 0x02; /* Disable audio haptics */
effects.ucEnableBits1 |= 0x01; /* Enable rumble emulation */
effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */
/* Shift to reduce effective rumble strength to match Xbox controllers */
effects->ucRumbleLeft = ctx->rumble_left >> 1;
effects->ucRumbleRight = ctx->rumble_right >> 1;
effects.ucRumbleLeft = ctx->rumble_left >> 1;
effects.ucRumbleRight = ctx->rumble_right >> 1;
} else {
/* Leaving emulated rumble bits off will restore audio haptics */
}
if ((effect_mask & k_EDS5EffectRumbleStart) != 0) {
effects->ucEnableBits1 |= 0x02; /* Disable audio haptics */
effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */
}
if ((effect_mask & k_EDS5EffectRumble) != 0) {
/* Already handled above */
}
if ((effect_mask & k_EDS5EffectLEDReset) != 0) {
effects->ucEnableBits2 |= 0x08; /* Reset LED state */
effects.ucEnableBits2 |= 0x08; /* Reset LED state */
}
if ((effect_mask & k_EDS5EffectLED) != 0) {
effects->ucEnableBits2 |= 0x04; /* Enable LED color */
effects.ucEnableBits2 |= 0x04; /* Enable LED color */
/* Populate the LED state with the appropriate color from our lookup table */
if (ctx->color_set) {
effects->ucLedRed = ctx->led_red;
effects->ucLedGreen = ctx->led_green;
effects->ucLedBlue = ctx->led_blue;
effects.ucLedRed = ctx->led_red;
effects.ucLedGreen = ctx->led_green;
effects.ucLedBlue = ctx->led_blue;
} else {
SetLedsForPlayerIndex(effects, ctx->player_index);
SetLedsForPlayerIndex(&effects, ctx->player_index);
}
}
if ((effect_mask & k_EDS5EffectPadLights) != 0) {
effects->ucEnableBits2 |= 0x10; /* Enable touchpad lights */
effects.ucEnableBits2 |= 0x10; /* Enable touchpad lights */
if (ctx->player_lights) {
SetLightsForPlayerIndex(effects, ctx->player_index);
SetLightsForPlayerIndex(&effects, ctx->player_index);
} else {
effects->ucPadLights = 0x00;
effects.ucPadLights = 0x00;
}
}
if ((effect_mask & k_EDS5EffectMicLight) != 0) {
effects->ucEnableBits2 |= 0x01; /* Enable microphone light */
effects.ucEnableBits2 |= 0x01; /* Enable microphone light */
effects->ucMicLightMode = 0; /* Bitmask, 0x00 = off, 0x01 = solid, 0x02 = pulse */
effects.ucMicLightMode = 0; /* Bitmask, 0x00 = off, 0x01 = solid, 0x02 = pulse */
}
if (ctx->is_bluetooth) {
/* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
Uint32 unCRC;
unCRC = SDL_crc32(0, &ubHdr, 1);
unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
}
if (SDL_HIDAPI_LockRumble() < 0) {
return -1;
}
/* See if we can update an existing pending request */
if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) {
DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[offset];
if (report_size == *pending_size &&
effects->ucEnableBits1 == pending_effects->ucEnableBits1 &&
effects->ucEnableBits2 == pending_effects->ucEnableBits2) {
/* We're simply updating the data for this request */
SDL_memcpy(pending_data, data, report_size);
SDL_HIDAPI_UnlockRumble();
return 0;
}
}
return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size);
return HIDAPI_DriverPS5_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects));
}
static void
@@ -531,8 +488,8 @@ HIDAPI_DriverPS5_SetEnhancedMode(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
ctx->enhanced_mode = SDL_TRUE;
SDL_PrivateJoystickAddTouchpad(joystick, 2);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f);
/* Switch into enhanced report mode */
HIDAPI_DriverPS5_UpdateEffects(device, 0);
@@ -725,6 +682,67 @@ HIDAPI_DriverPS5_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
return HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED);
}
static int
HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size)
{
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
Uint8 data[78];
int report_size, offset;
Uint8 *pending_data;
int *pending_size;
int maximum_size;
if (!ctx->enhanced_mode) {
HIDAPI_DriverPS5_SetEnhancedMode(device, joystick);
}
SDL_zero(data);
if (ctx->is_bluetooth) {
data[0] = k_EPS5ReportIdBluetoothEffects;
data[1] = 0x02; /* Magic value */
report_size = 78;
offset = 2;
} else {
data[0] = k_EPS5ReportIdUsbEffects;
report_size = 48;
offset = 1;
}
SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size));
if (ctx->is_bluetooth) {
/* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */
Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */
Uint32 unCRC;
unCRC = SDL_crc32(0, &ubHdr, 1);
unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC)));
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
}
if (SDL_HIDAPI_LockRumble() < 0) {
return -1;
}
/* See if we can update an existing pending request */
if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) {
DS5EffectsState_t *effects = (DS5EffectsState_t *)&data[offset];
DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[offset];
if (report_size == *pending_size &&
effects->ucEnableBits1 == pending_effects->ucEnableBits1 &&
effects->ucEnableBits2 == pending_effects->ucEnableBits2) {
/* We're simply updating the data for this request */
SDL_memcpy(pending_data, data, report_size);
SDL_HIDAPI_UnlockRumble();
return 0;
}
}
return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size);
}
static int
HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1082,6 +1100,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
HIDAPI_DriverPS5_RumbleJoystickTriggers,
HIDAPI_DriverPS5_HasJoystickLED,
HIDAPI_DriverPS5_SetJoystickLED,
HIDAPI_DriverPS5_SendJoystickEffect,
HIDAPI_DriverPS5_SetJoystickSensorsEnabled,
HIDAPI_DriverPS5_CloseJoystick,
HIDAPI_DriverPS5_FreeDevice,
+8 -4
View File
@@ -51,10 +51,7 @@ typedef struct {
static SDL_bool
HIDAPI_DriverStadia_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
if (vendor_id == USB_VENDOR_GOOGLE && product_id == USB_PRODUCT_GOOGLE_STADIA_CONTROLLER) {
return SDL_TRUE;
}
return SDL_FALSE;
return (type == SDL_CONTROLLER_TYPE_GOOGLE_STADIA) ? SDL_TRUE : SDL_FALSE;
}
static const char *
@@ -141,6 +138,12 @@ HIDAPI_DriverStadia_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joys
return SDL_Unsupported();
}
static int
HIDAPI_DriverStadia_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverStadia_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -314,6 +317,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia =
HIDAPI_DriverStadia_RumbleJoystickTriggers,
HIDAPI_DriverStadia_HasJoystickLED,
HIDAPI_DriverStadia_SetJoystickLED,
HIDAPI_DriverStadia_SendJoystickEffect,
HIDAPI_DriverStadia_SetJoystickSensorsEnabled,
HIDAPI_DriverStadia_CloseJoystick,
HIDAPI_DriverStadia_FreeDevice,
+7
View File
@@ -1058,6 +1058,12 @@ HIDAPI_DriverSteam_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
return SDL_Unsupported();
}
static int
HIDAPI_DriverSteam_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverSteam_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1207,6 +1213,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
HIDAPI_DriverSteam_RumbleJoystickTriggers,
HIDAPI_DriverSteam_HasJoystickLED,
HIDAPI_DriverSteam_SetJoystickLED,
HIDAPI_DriverSteam_SendJoystickEffect,
HIDAPI_DriverSteam_SetSensorsEnabled,
HIDAPI_DriverSteam_CloseJoystick,
HIDAPI_DriverSteam_FreeDevice,
+115 -55
View File
@@ -323,6 +323,10 @@ HIDAPI_DriverSwitch_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
/* Give a user friendly name for this controller */
if (vendor_id == USB_VENDOR_NINTENDO) {
if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
return "Nintendo Switch Joy-Con Grip";
}
if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT) {
return "Nintendo Switch Joy-Con Left";
}
@@ -491,6 +495,64 @@ static SDL_bool WriteProprietary(SDL_DriverSwitch_Context *ctx, ESwitchProprieta
return SDL_FALSE;
}
static Uint8 EncodeRumbleHighAmplitude(Uint16 amplitude) {
/* More information about these values can be found here:
* https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md
*/
Uint16 hfa[101][2] = { {0, 0x0},{514, 0x2},{775, 0x4},{921, 0x6},{1096, 0x8},{1303, 0x0a},{1550, 0x0c},
{1843, 0x0e},{2192, 0x10},{2606, 0x12},{3100, 0x14},{3686, 0x16},{4383, 0x18},{5213, 0x1a},
{6199, 0x1c},{7372, 0x1e},{7698, 0x20},{8039, 0x22},{8395, 0x24},{8767, 0x26},{9155, 0x28},
{9560, 0x2a},{9984, 0x2c},{10426, 0x2e},{10887, 0x30},{11369, 0x32},{11873, 0x34},{12398, 0x36},
{12947, 0x38},{13520, 0x3a},{14119, 0x3c},{14744, 0x3e},{15067, 0x40},{15397, 0x42},{15734, 0x44},
{16079, 0x46},{16431, 0x48},{16790, 0x4a},{17158, 0x4c},{17534, 0x4e},{17918, 0x50},{18310, 0x52},
{18711, 0x54},{19121, 0x56},{19540, 0x58},{19967, 0x5a},{20405, 0x5c},{20851, 0x5e},{21308, 0x60},
{21775, 0x62},{22251, 0x64},{22739, 0x66},{23236, 0x68},{23745, 0x6a},{24265, 0x6c},{24797, 0x6e},
{25340, 0x70},{25894, 0x72},{26462, 0x74},{27041, 0x76},{27633, 0x78},{28238, 0x7a},{28856, 0x7c},
{29488, 0x7e},{30134, 0x80},{30794, 0x82},{31468, 0x84},{32157, 0x86},{32861, 0x88},{33581, 0x8a},
{34316, 0x8c},{35068, 0x8e},{35836, 0x90},{36620, 0x92},{37422, 0x94},{38242, 0x96},{39079, 0x98},
{39935, 0x9a},{40809, 0x9c},{41703, 0x9e},{42616, 0xa0},{43549, 0xa2},{44503, 0xa4},{45477, 0xa6},
{46473, 0xa8},{47491, 0xaa},{48531, 0xac},{49593, 0xae},{50679, 0xb0},{51789, 0xb2},{52923, 0xb4},
{54082, 0xb6},{55266, 0xb8},{56476, 0xba},{57713, 0xbc},{58977, 0xbe},{60268, 0xc0},{61588, 0xc2},
{62936, 0xc4},{64315, 0xc6},{65535, 0xc8} };
int index = 0;
for ( ; index < 101; index++) {
if (amplitude <= hfa[index][0]) {
return (Uint8)hfa[index][1];
}
}
return (Uint8)hfa[100][1];
}
static Uint16 EncodeRumbleLowAmplitude(Uint16 amplitude) {
/* More information about these values can be found here:
* https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md
*/
Uint16 lfa[101][2] = { {0, 0x0040},{514, 0x8040},{775, 0x0041},{921, 0x8041},{1096, 0x0042},
{1303, 0x8042},{1550, 0x0043},{1843, 0x8043},{2192, 0x0044},{2606, 0x8044},{3100, 0x0045},
{3686, 0x8045},{4383, 0x0046},{5213, 0x8046},{6199, 0x0047},{7372, 0x8047},{7698, 0x0048},
{8039, 0x8048},{8395, 0x0049},{8767, 0x8049},{9155, 0x004a},{9560, 0x804a},{9984, 0x004b},
{10426, 0x804b},{10887, 0x004c},{11369, 0x804c},{11873, 0x004d},{12398, 0x804d},{12947, 0x004e},
{13520, 0x804e},{14119, 0x004f},{14744, 0x804f},{15067, 0x0050},{15397, 0x8050},{15734, 0x0051},
{16079, 0x8051},{16431, 0x0052},{16790, 0x8052},{17158, 0x0053},{17534, 0x8053},{17918, 0x0054},
{18310, 0x8054},{18711, 0x0055},{19121, 0x8055},{19540, 0x0056},{19967, 0x8056},{20405, 0x0057},
{20851, 0x8057},{21308, 0x0058},{21775, 0x8058},{22251, 0x0059},{22739, 0x8059},{23236, 0x005a},
{23745, 0x805a},{24265, 0x005b},{24797, 0x805b},{25340, 0x005c},{25894, 0x805c},{26462, 0x005d},
{27041, 0x805d},{27633, 0x005e},{28238, 0x805e},{28856, 0x005f},{29488, 0x805f},{30134, 0x0060},
{30794, 0x8060},{31468, 0x0061},{32157, 0x8061},{32861, 0x0062},{33581, 0x8062},{34316, 0x0063},
{35068, 0x8063},{35836, 0x0064},{36620, 0x8064},{37422, 0x0065},{38242, 0x8065},{39079, 0x0066},
{39935, 0x8066},{40809, 0x0067},{41703, 0x8067},{42616, 0x0068},{43549, 0x8068},{44503, 0x0069},
{45477, 0x8069},{46473, 0x006a},{47491, 0x806a},{48531, 0x006b},{49593, 0x806b},{50679, 0x006c},
{51789, 0x806c},{52923, 0x006d},{54082, 0x806d},{55266, 0x006e},{56476, 0x806e},{57713, 0x006f},
{58977, 0x806f},{60268, 0x0070},{61588, 0x8070},{62936, 0x0071},{64315, 0x8071},{65535, 0x0072} };
int index = 0;
for (; index < 101; index++) {
if (amplitude <= lfa[index][0]) {
return lfa[index][1];
}
}
return lfa[100][1];
}
static void SetNeutralRumble(SwitchRumbleData_t *pRumble)
{
pRumble->rgucData[0] = 0x00;
@@ -584,7 +646,8 @@ static SDL_bool BTrySetupUSB(SDL_DriverSwitch_Context *ctx)
/*return SDL_FALSE;*/
}
if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Handshake, NULL, 0, SDL_TRUE)) {
return SDL_FALSE;
/* This fails on the right Joy-Con when plugged into the charging grip */
/*return SDL_FALSE;*/
}
if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE)) {
return SDL_FALSE;
@@ -834,14 +897,15 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
*/
if (device->vendor_id == USB_VENDOR_NINTENDO &&
(device->product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO ||
device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP ||
device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT ||
device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT)) {
input_mode = k_eSwitchInputReportIDs_FullControllerState;
}
if (input_mode == k_eSwitchInputReportIDs_FullControllerState) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 200.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 200.0f);
ctx->m_bHasSensors = SDL_TRUE;
}
@@ -941,19 +1005,15 @@ HIDAPI_DriverSwitch_ActuallyRumbleJoystick(SDL_DriverSwitch_Context *ctx, Uint16
* https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md
*/
const Uint16 k_usHighFreq = 0x0074;
const Uint8 k_ucHighFreqAmp = 0xBE;
const Uint8 k_ucHighFreqAmp = EncodeRumbleHighAmplitude(high_frequency_rumble);
const Uint8 k_ucLowFreq = 0x3D;
const Uint16 k_usLowFreqAmp = 0x806F;
const Uint16 k_usLowFreqAmp = EncodeRumbleLowAmplitude(low_frequency_rumble);
if (low_frequency_rumble) {
if (low_frequency_rumble || high_frequency_rumble) {
EncodeRumble(&ctx->m_RumblePacket.rumbleData[0], k_usHighFreq, k_ucHighFreqAmp, k_ucLowFreq, k_usLowFreqAmp);
} else {
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]);
}
if (high_frequency_rumble) {
EncodeRumble(&ctx->m_RumblePacket.rumbleData[1], k_usHighFreq, k_ucHighFreqAmp, k_ucLowFreq, k_usLowFreqAmp);
} else {
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]);
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]);
}
@@ -1003,6 +1063,10 @@ HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
{
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
if (ctx->m_bInputOnly) {
return SDL_Unsupported();
}
if (ctx->m_bRumblePending) {
if (HIDAPI_DriverSwitch_SendPendingRumble(ctx) < 0) {
return -1;
@@ -1052,6 +1116,12 @@ HIDAPI_DriverSwitch_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joys
return SDL_Unsupported();
}
static int
HIDAPI_DriverSwitch_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1269,6 +1339,33 @@ static void HandleSimpleControllerState(SDL_Joystick *joystick, SDL_DriverSwitch
ctx->m_lastSimpleState = *packet;
}
static void SendSensorUpdate(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SDL_SensorType type, Sint16 *values)
{
float data[3];
/* Note the order of components has been shuffled to match PlayStation controllers,
* since that's our de facto standard from already supporting those controllers, and
* users will want consistent axis mappings across devices.
*/
if (type == SDL_SENSOR_GYRO) {
data[0] = -HIDAPI_DriverSwitch_ScaleGyro(values[1]);
data[1] = HIDAPI_DriverSwitch_ScaleGyro(values[2]);
data[2] = -HIDAPI_DriverSwitch_ScaleGyro(values[0]);
} else {
data[0] = -HIDAPI_DriverSwitch_ScaleAccel(values[1]);
data[1] = HIDAPI_DriverSwitch_ScaleAccel(values[2]);
data[2] = -HIDAPI_DriverSwitch_ScaleAccel(values[0]);
}
/* Right Joy-Con flips some axes, so let's flip them back for consistency */
if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
data[0] = -data[0];
data[1] = -data[1];
}
SDL_PrivateJoystickSensor(joystick, type, data, 3);
}
static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet)
{
Sint16 axis;
@@ -1352,51 +1449,13 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
}
if (ctx->m_bReportSensors) {
float data[3];
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[2].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[1].sGyroX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, &packet->imuState[0].sGyroX);
/* Note the order of components has been shuffled to match PlayStation controllers,
* since that's our de facto standard from already supporting those controllers, and
* users will want consistent axis mappings across devices.
*/
data[0] = HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[0].sGyroY);
data[1] = HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[0].sGyroZ);
data[2] = HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[0].sGyroX);
data[0] += HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[1].sGyroY);
data[1] += HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[1].sGyroZ);
data[2] += HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[1].sGyroX);
data[0] += HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[2].sGyroY);
data[1] += HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[2].sGyroZ);
data[2] += HIDAPI_DriverSwitch_ScaleGyro(packet->imuState[2].sGyroX);
data[0] /= -3.f;
data[1] /= 3.f;
data[2] /= -3.f;
/* Right Joy-Con flips some axes, so let's flip them back for consistency */
if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
data[0] = -data[0];
data[1] = -data[1];
}
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, data, 3);
data[0] = HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[0].sAccelY);
data[1] = HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[0].sAccelZ);
data[2] = HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[0].sAccelX);
data[0] += HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[1].sAccelY);
data[1] += HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[1].sAccelZ);
data[2] += HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[1].sAccelX);
data[0] += HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[2].sAccelY);
data[1] += HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[2].sAccelZ);
data[2] += HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[2].sAccelX);
data[0] /= -3.f;
data[1] /= 3.f;
data[2] /= -3.f;
/* Right Joy-Con flips some axes, so let's flip them back for consistency */
if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
data[0] = -data[0];
data[1] = -data[1];
}
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, data, 3);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[2].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[1].sAccelX);
SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, &packet->imuState[0].sAccelX);
}
ctx->m_lastFullState = *packet;
@@ -1497,6 +1556,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
HIDAPI_DriverSwitch_RumbleJoystickTriggers,
HIDAPI_DriverSwitch_HasJoystickLED,
HIDAPI_DriverSwitch_SetJoystickLED,
HIDAPI_DriverSwitch_SendJoystickEffect,
HIDAPI_DriverSwitch_SetJoystickSensorsEnabled,
HIDAPI_DriverSwitch_CloseJoystick,
HIDAPI_DriverSwitch_FreeDevice,
@@ -216,6 +216,12 @@ HIDAPI_DriverXbox360_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joy
return SDL_Unsupported();
}
static int
HIDAPI_DriverXbox360_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverXbox360_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -342,6 +348,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
HIDAPI_DriverXbox360_RumbleJoystickTriggers,
HIDAPI_DriverXbox360_HasJoystickLED,
HIDAPI_DriverXbox360_SetJoystickLED,
HIDAPI_DriverXbox360_SendJoystickEffect,
HIDAPI_DriverXbox360_SetJoystickSensorsEnabled,
HIDAPI_DriverXbox360_CloseJoystick,
HIDAPI_DriverXbox360_FreeDevice,
@@ -186,6 +186,12 @@ HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *jo
return SDL_Unsupported();
}
static int
HIDAPI_DriverXbox360W_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -339,6 +345,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
HIDAPI_DriverXbox360W_RumbleJoystickTriggers,
HIDAPI_DriverXbox360W_HasJoystickLED,
HIDAPI_DriverXbox360W_SetJoystickLED,
HIDAPI_DriverXbox360W_SendJoystickEffect,
HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled,
HIDAPI_DriverXbox360W_CloseJoystick,
HIDAPI_DriverXbox360W_FreeDevice,
+15 -3
View File
@@ -145,7 +145,7 @@ ControllerHasTriggerRumble(Uint16 vendor_id, Uint16 product_id)
static SDL_bool
ControllerHasShareButton(Uint16 vendor_id, Uint16 product_id)
{
return SDL_IsJoystickXboxOneSeriesX(vendor_id, product_id);
return SDL_IsJoystickXboxSeriesX(vendor_id, product_id);
}
static void
@@ -439,6 +439,12 @@ HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joy
return SDL_Unsupported();
}
static int
HIDAPI_DriverXboxOne_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -480,15 +486,20 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
/* Xbox Series X firmware version 5.0, report is 36 bytes, share button is in byte 18
* Xbox Series X firmware version 5.1, report is 44 bytes, share button is in byte 18
* Xbox Series X firmware version 5.5, report is 48 bytes, share button is in byte 22
* Victrix Gambit Tournament Controller, report is 50 bytes, share button is in byte 32
*/
if (size < 48) {
if (ctx->last_state[18] != data[18]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[18] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
}
} else {
} else if (size == 48) {
if (ctx->last_state[22] != data[22]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[22] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
}
} else if (size == 50) {
if (ctx->last_state[32] != data[32]) {
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[32] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
}
}
}
@@ -618,7 +629,7 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons16(SDL_Joystick *joystick, SDL_Driver
* Xbox One S with firmware 4.8.1923 uses a 17 byte packet with BACK button in byte 16 and the GUIDE button in a separate packet (on Windows), or in byte 15 (on Linux)
* Xbox One Elite Series 2 with firmware 4.7.1872 uses a 55 byte packet with BACK button in byte 16, paddles starting at byte 33, and the GUIDE button in a separate packet
* Xbox One Elite Series 2 with firmware 4.8.1908 uses a 33 byte packet with BACK button in byte 16, paddles starting at byte 17, and the GUIDE button in a separate packet
* Xbox One Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17
* Xbox Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17
*/
static void
HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
@@ -1078,6 +1089,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
HIDAPI_DriverXboxOne_RumbleJoystickTriggers,
HIDAPI_DriverXboxOne_HasJoystickLED,
HIDAPI_DriverXboxOne_SetJoystickLED,
HIDAPI_DriverXboxOne_SendJoystickEffect,
HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled,
HIDAPI_DriverXboxOne_CloseJoystick,
HIDAPI_DriverXboxOne_FreeDevice,
+69 -13
View File
@@ -47,19 +47,19 @@
#include <IOKit/usb/USBSpec.h>
#endif
#if defined(__LINUX__)
#include "../../core/linux/SDL_udev.h"
#ifdef SDL_USE_LIBUDEV
#include "../../core/linux/SDL_udev.h"
#include <poll.h>
#include <unistd.h>
#endif
#ifdef HAVE_INOTIFY
#include <unistd.h> /* just in case we didn't use that SDL_USE_LIBUDEV block... */
#include <errno.h> /* errno, strerror */
#include <fcntl.h>
#include <limits.h> /* For the definition of NAME_MAX */
#include <sys/inotify.h>
#endif
#include <unistd.h>
#endif
#if defined(SDL_USE_LIBUDEV)
typedef enum
@@ -81,6 +81,9 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = {
#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE
&SDL_HIDAPI_DriverGameCube,
#endif
#ifdef SDL_JOYSTICK_HIDAPI_LUNA
&SDL_HIDAPI_DriverLuna,
#endif
#ifdef SDL_JOYSTICK_HIDAPI_PS4
&SDL_HIDAPI_DriverPS4,
#endif
@@ -562,7 +565,7 @@ HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float
}
static void HIDAPI_JoystickDetect(void);
static void HIDAPI_JoystickClose(SDL_Joystick * joystick);
static void HIDAPI_JoystickClose(SDL_Joystick *joystick);
static SDL_bool
HIDAPI_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
@@ -1107,6 +1110,40 @@ HIDAPI_IsEquivalentToDevice(Uint16 vendor_id, Uint16 product_id, SDL_HIDAPI_Devi
return SDL_FALSE;
}
SDL_bool
HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type)
{
SDL_HIDAPI_Device *device;
SDL_bool result = SDL_FALSE;
/* Make sure we're initialized, as this could be called from other drivers during startup */
if (HIDAPI_JoystickInit() < 0) {
return SDL_FALSE;
}
if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) {
HIDAPI_UpdateDeviceList();
SDL_AtomicUnlock(&SDL_HIDAPI_spinlock);
}
SDL_LockJoysticks();
device = SDL_HIDAPI_devices;
while (device) {
if (device->driver &&
SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == type) {
result = SDL_TRUE;
break;
}
device = device->next;
}
SDL_UnlockJoysticks();
#ifdef DEBUG_HIDAPI
SDL_Log("HIDAPI_IsDeviceTypePresent() returning %s for %d\n", result ? "true" : "false", type);
#endif
return result;
}
SDL_bool
HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
{
@@ -1149,6 +1186,7 @@ HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, cons
if (device->driver &&
HIDAPI_IsEquivalentToDevice(vendor_id, product_id, device)) {
result = SDL_TRUE;
break;
}
device = device->next;
}
@@ -1266,7 +1304,7 @@ HIDAPI_JoystickGetDeviceInstanceID(int device_index)
}
static int
HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index)
HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
SDL_JoystickID joystickID;
SDL_HIDAPI_Device *device = HIDAPI_GetDeviceByIndex(device_index, &joystickID);
@@ -1292,7 +1330,7 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index)
}
static int
HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
int result;
@@ -1309,7 +1347,7 @@ HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
}
static int
HIDAPI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
int result;
@@ -1326,7 +1364,7 @@ HIDAPI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint1
}
static SDL_bool
HIDAPI_JoystickHasLED(SDL_Joystick * joystick)
HIDAPI_JoystickHasLED(SDL_Joystick *joystick)
{
SDL_bool result = SDL_FALSE;
@@ -1340,7 +1378,7 @@ HIDAPI_JoystickHasLED(SDL_Joystick * joystick)
}
static int
HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
int result;
@@ -1357,7 +1395,24 @@ HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blu
}
static int
HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick * joystick, SDL_bool enabled)
HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
int result;
if (joystick->hwdata) {
SDL_HIDAPI_Device *device = joystick->hwdata->device;
result = device->driver->SendJoystickEffect(device, joystick, data, size);
} else {
SDL_SetError("SendEffect failed, device disconnected");
result = -1;
}
return result;
}
static int
HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
int result;
@@ -1374,13 +1429,13 @@ HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick * joystick, SDL_bool enabled)
}
static void
HIDAPI_JoystickUpdate(SDL_Joystick * joystick)
HIDAPI_JoystickUpdate(SDL_Joystick *joystick)
{
/* This is handled in SDL_HIDAPI_UpdateDevices() */
}
static void
HIDAPI_JoystickClose(SDL_Joystick * joystick)
HIDAPI_JoystickClose(SDL_Joystick *joystick)
{
if (joystick->hwdata) {
SDL_HIDAPI_Device *device = joystick->hwdata->device;
@@ -1467,6 +1522,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
HIDAPI_JoystickRumbleTriggers,
HIDAPI_JoystickHasLED,
HIDAPI_JoystickSetLED,
HIDAPI_JoystickSendEffect,
HIDAPI_JoystickSetSensorsEnabled,
HIDAPI_JoystickUpdate,
HIDAPI_JoystickClose,
@@ -32,6 +32,7 @@
/* This is the full set of HIDAPI drivers available */
#define SDL_JOYSTICK_HIDAPI_GAMECUBE
#define SDL_JOYSTICK_HIDAPI_LUNA
#define SDL_JOYSTICK_HIDAPI_PS4
#define SDL_JOYSTICK_HIDAPI_PS5
#define SDL_JOYSTICK_HIDAPI_STADIA
@@ -98,6 +99,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
int (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble);
SDL_bool (*HasJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
int (*SendJoystickEffect)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size);
int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled);
void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
void (*FreeDevice)(SDL_HIDAPI_Device *device);
@@ -107,6 +109,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
/* HIDAPI device support */
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia;
@@ -116,6 +119,9 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne;
/* Return true if a HID device is present and supported as a joystick of the given type */
extern SDL_bool HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type);
/* Return true if a HID device is present and supported as a joystick */
extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);
+141 -62
View File
@@ -27,6 +27,7 @@
#include "SDL_stdinc.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
#include "../hidapi/SDL_hidapijoystick_c.h"
#include "../usb_ids.h"
#include "SDL_mfijoystick_c.h"
@@ -53,6 +54,7 @@
static id connectObserver = nil;
static id disconnectObserver = nil;
static NSString *GCInputXboxShareButton = @"Button Share";
#include <Availability.h>
#include <objc/message.h>
@@ -127,7 +129,49 @@ GetDeviceForIndex(int device_index)
}
#ifdef SDL_JOYSTICK_MFI
static void
static BOOL
IsControllerPS4(GCController *controller)
{
if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
if ([controller.productCategory isEqualToString:@"DualShock 4"]) {
return TRUE;
}
} else {
if ([controller.vendorName containsString: @"DUALSHOCK"]) {
return TRUE;
}
}
return FALSE;
}
static BOOL
IsControllerPS5(GCController *controller)
{
if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
if ([controller.productCategory isEqualToString:@"DualSense"]) {
return TRUE;
}
} else {
if ([controller.vendorName containsString: @"DualSense"]) {
return TRUE;
}
}
return FALSE;
}
static BOOL
IsControllerXbox(GCController *controller)
{
if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
if ([controller.productCategory isEqualToString:@"Xbox One"]) {
return TRUE;
}
} else {
if ([controller.vendorName containsString: @"Xbox"]) {
return TRUE;
}
}
return FALSE;
}
static BOOL
IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
{
Uint16 *guid16 = (Uint16 *)device->guid.data;
@@ -152,14 +196,23 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
if (controller.extendedGamepad) {
GCExtendedGamepad *gamepad = controller.extendedGamepad;
BOOL is_xbox = [controller.vendorName containsString: @"Xbox"];
BOOL is_ps4 = [controller.vendorName containsString: @"DUALSHOCK"];
BOOL is_ps5 = [controller.vendorName containsString: @"DualSense"];
BOOL is_xbox = IsControllerXbox(controller);
BOOL is_ps4 = IsControllerPS4(controller);
BOOL is_ps5 = IsControllerPS5(controller);
#if TARGET_OS_TV
BOOL is_MFi = (!is_xbox && !is_ps4 && !is_ps5);
#endif
int nbuttons = 0;
#ifdef SDL_JOYSTICK_HIDAPI
if ((is_xbox && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_XBOXONE)) ||
(is_ps4 && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_PS4)) ||
(is_ps5 && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_PS5))) {
/* The HIDAPI driver is taking care of this device */
return FALSE;
}
#endif
/* These buttons are part of the original MFi spec */
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B);
@@ -228,6 +281,11 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_PADDLE4);
++nbuttons;
}
if (controller.physicalInputProfile.buttons[GCInputXboxShareButton] != nil) {
device->has_xbox_share_button = SDL_TRUE;
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_MISC1);
++nbuttons;
}
}
#endif
#pragma clang diagnostic pop
@@ -238,6 +296,10 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
/* Assume Xbox One Elite Series 2 Controller unless/until GCController flows VID/PID */
product = USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH;
subtype = 1;
} else if (device->has_xbox_share_button) {
/* Assume Xbox Series X Controller unless/until GCController flows VID/PID */
product = USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH;
subtype = 1;
} else {
/* Assume Xbox One S BLE Controller unless/until GCController flows VID/PID */
product = USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH;
@@ -255,7 +317,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
} else if (is_ps5) {
vendor = USB_VENDOR_SONY;
product = USB_PRODUCT_SONY_DS5;
subtype = 0;
subtype = 0;
} else {
vendor = USB_VENDOR_APPLE;
product = 1;
@@ -332,6 +394,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
/* This will be set when the first button press of the controller is
* detected. */
controller.playerIndex = -1;
return TRUE;
}
#endif /* SDL_JOYSTICK_MFI */
@@ -380,7 +443,10 @@ IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
#endif /* SDL_JOYSTICK_iOS_ACCELEROMETER */
} else if (controller) {
#ifdef SDL_JOYSTICK_MFI
IOS_AddMFIJoystickDevice(device, controller);
if (!IOS_AddMFIJoystickDevice(device, controller)) {
SDL_free(device);
return;
}
#else
SDL_free(device);
return;
@@ -654,10 +720,10 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
GCController *controller = joystick->hwdata->controller;
GCMotion *motion = controller.motion;
if (motion && motion.hasRotationRate) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f);
}
if (motion && motion.hasGravityAndUserAcceleration) {
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f);
}
}
#endif /* ENABLE_MFI_SENSORS */
@@ -665,12 +731,12 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
GCController *controller = joystick->hwdata->controller;
if (controller.extendedGamepad) {
GCExtendedGamepad *gamepad = controller.extendedGamepad;
if ([gamepad.buttonOptions isBoundToSystemGesture]) {
gamepad.buttonOptions.preferredSystemGestureState = GCSystemGestureStateDisabled;
}
}
for (id key in controller.physicalInputProfile.buttons) {
GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key];
if ([button isBoundToSystemGesture]) {
button.preferredSystemGestureState = GCSystemGestureStateDisabled;
}
}
}
#endif /* ENABLE_MFI_SYSTEM_GESTURE_STATE */
@@ -857,6 +923,10 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
controller.physicalInputProfile.buttons[GCInputXboxPaddleFour].isPressed);
*/
}
if (joystick->hwdata->has_xbox_share_button) {
buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxShareButton].isPressed;
}
#endif
#pragma clang diagnostic pop
@@ -1005,23 +1075,23 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
#ifdef ENABLE_MFI_RUMBLE
@interface SDL_RumbleMotor : NSObject
@property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0));
@property(nonatomic,strong) id<CHHapticPatternPlayer> player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0));
@property bool active;
@end
@implementation SDL_RumbleMotor {
CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0));
id<CHHapticPatternPlayer> player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0));
bool active;
}
-(void)cleanup
{
if (self->player != nil) {
[self->player cancelAndReturnError:nil];
self->player = nil;
if (self.player != nil) {
[self.player cancelAndReturnError:nil];
self.player = nil;
}
if (self->engine != nil) {
[self->engine stopWithCompletionHandler:nil];
self->engine = nil;
if (self.engine != nil) {
[self.engine stopWithCompletionHandler:nil];
self.engine = nil;
}
}
@@ -1029,21 +1099,21 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
{
@autoreleasepool {
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
NSError *error;
NSError *error = nil;
if (self->engine == nil) {
if (self.engine == nil) {
return SDL_SetError("Haptics engine was stopped");
}
if (intensity == 0.0f) {
if (self->player && self->active) {
[self->player stopAtTime:0 error:&error];
if (self.player && self.active) {
[self.player stopAtTime:0 error:&error];
}
self->active = false;
self.active = false;
return 0;
}
if (self->player == nil) {
if (self.player == nil) {
CHHapticEventParameter *param = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:1.0f];
CHHapticEvent *event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObjects:param, nil] relativeTime:0 duration:GCHapticDurationInfinite];
CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:event] parameters:[[NSArray alloc] init] error:&error];
@@ -1051,22 +1121,22 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
return SDL_SetError("Couldn't create haptic pattern: %s", [error.localizedDescription UTF8String]);
}
self->player = [self->engine createPlayerWithPattern:pattern error:&error];
self.player = [self.engine createPlayerWithPattern:pattern error:&error];
if (error != nil) {
return SDL_SetError("Couldn't create haptic player: %s", [error.localizedDescription UTF8String]);
}
self->active = false;
self.active = false;
}
CHHapticDynamicParameter *param = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:intensity relativeTime:0];
[self->player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error];
[self.player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error];
if (error != nil) {
return SDL_SetError("Couldn't update haptic player: %s", [error.localizedDescription UTF8String]);
}
if (!self->active) {
[self->player startAtTime:0 error:&error];
self->active = true;
if (!self.active) {
[self.player startAtTime:0 error:&error];
self.active = true;
}
}
@@ -1080,36 +1150,36 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
self = [super init];
NSError *error;
self->engine = [controller.haptics createEngineWithLocality:locality];
if (self->engine == nil) {
self.engine = [controller.haptics createEngineWithLocality:locality];
if (self.engine == nil) {
SDL_SetError("Couldn't create haptics engine");
return nil;
}
[self->engine startAndReturnError:&error];
[self.engine startAndReturnError:&error];
if (error != nil) {
SDL_SetError("Couldn't start haptics engine");
return nil;
}
__weak typeof(self) weakSelf = self;
self->engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) {
self.engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) {
SDL_RumbleMotor *_this = weakSelf;
if (_this == nil) {
return;
}
_this->player = nil;
_this->engine = nil;
_this.player = nil;
_this.engine = nil;
};
self->engine.resetHandler = ^{
self.engine.resetHandler = ^{
SDL_RumbleMotor *_this = weakSelf;
if (_this == nil) {
return;
}
_this->player = nil;
[_this->engine startAndReturnError:nil];
_this.player = nil;
[_this.engine startAndReturnError:nil];
};
return self;
@@ -1119,13 +1189,13 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
@end
@interface SDL_RumbleContext : NSObject
@property(nonatomic,strong) SDL_RumbleMotor *m_low_frequency_motor;
@property(nonatomic,strong) SDL_RumbleMotor *m_high_frequency_motor;
@property(nonatomic,strong) SDL_RumbleMotor *m_left_trigger_motor;
@property(nonatomic,strong) SDL_RumbleMotor *m_right_trigger_motor;
@end
@implementation SDL_RumbleContext {
SDL_RumbleMotor *m_low_frequency_motor;
SDL_RumbleMotor *m_high_frequency_motor;
SDL_RumbleMotor *m_left_trigger_motor;
SDL_RumbleMotor *m_right_trigger_motor;
}
-(id) initWithLowFrequencyMotor:(SDL_RumbleMotor*)low_frequency_motor
@@ -1134,10 +1204,10 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
RightTriggerMotor:(SDL_RumbleMotor*)right_trigger_motor
{
self = [super init];
self->m_low_frequency_motor = low_frequency_motor;
self->m_high_frequency_motor = high_frequency_motor;
self->m_left_trigger_motor = left_trigger_motor;
self->m_right_trigger_motor = right_trigger_motor;
self.m_low_frequency_motor = low_frequency_motor;
self.m_high_frequency_motor = high_frequency_motor;
self.m_left_trigger_motor = left_trigger_motor;
self.m_right_trigger_motor = right_trigger_motor;
return self;
}
@@ -1145,8 +1215,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
{
int result = 0;
result += [self->m_low_frequency_motor setIntensity:((float)low_frequency_rumble / 65535.0f)];
result += [self->m_high_frequency_motor setIntensity:((float)high_frequency_rumble / 65535.0f)];
result += [self.m_low_frequency_motor setIntensity:((float)low_frequency_rumble / 65535.0f)];
result += [self.m_high_frequency_motor setIntensity:((float)high_frequency_rumble / 65535.0f)];
return ((result < 0) ? -1 : 0);
}
@@ -1154,9 +1224,9 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
{
int result = 0;
if (self->m_left_trigger_motor && self->m_right_trigger_motor) {
result += [self->m_left_trigger_motor setIntensity:((float)left_rumble / 65535.0f)];
result += [self->m_right_trigger_motor setIntensity:((float)right_rumble / 65535.0f)];
if (self.m_left_trigger_motor && self.m_right_trigger_motor) {
result += [self.m_left_trigger_motor setIntensity:((float)left_rumble / 65535.0f)];
result += [self.m_right_trigger_motor setIntensity:((float)right_rumble / 65535.0f)];
} else {
result = SDL_Unsupported();
}
@@ -1165,8 +1235,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
-(void)cleanup
{
[self->m_low_frequency_motor cleanup];
[self->m_high_frequency_motor cleanup];
[self.m_low_frequency_motor cleanup];
[self.m_high_frequency_motor cleanup];
}
@end
@@ -1283,6 +1353,12 @@ IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
return SDL_Unsupported();
}
static int
IOS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1353,9 +1429,11 @@ IOS_JoystickClose(SDL_Joystick *joystick)
#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
GCController *controller = joystick->hwdata->controller;
if (controller.extendedGamepad) {
GCExtendedGamepad *gamepad = controller.extendedGamepad;
gamepad.buttonOptions.preferredSystemGestureState = GCSystemGestureStateEnabled;
for (id key in controller.physicalInputProfile.buttons) {
GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key];
if ([button isBoundToSystemGesture]) {
button.preferredSystemGestureState = GCSystemGestureStateEnabled;
}
}
}
#endif /* ENABLE_MFI_SYSTEM_GESTURE_STATE */
@@ -1434,6 +1512,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
IOS_JoystickRumbleTriggers,
IOS_JoystickHasLED,
IOS_JoystickSetLED,
IOS_JoystickSendEffect,
IOS_JoystickSetSensorsEnabled,
IOS_JoystickUpdate,
IOS_JoystickClose,
@@ -50,6 +50,7 @@ typedef struct joystick_hwdata
Uint32 button_mask;
SDL_bool has_dualshock_touchpad;
SDL_bool has_xbox_paddles;
SDL_bool has_xbox_share_button;
struct joystick_hwdata *next;
} joystick_hwdata;
+91 -48
View File
@@ -589,6 +589,18 @@ LINUX_InotifyJoystickDetect(void)
* have to do this the first time, to detect devices that already existed
* before we started; in the non-inotify code path we do this repeatedly
* (polling). */
static int
filter_entries(const struct dirent *entry)
{
return (SDL_strlen(entry->d_name) > 5 && SDL_strncmp(entry->d_name, "event", 5) == 0);
}
static int
sort_entries(const struct dirent **a, const struct dirent **b)
{
int numA = SDL_atoi((*a)->d_name+5);
int numB = SDL_atoi((*b)->d_name+5);
return (numA - numB);
}
static void
LINUX_FallbackJoystickDetect(void)
{
@@ -600,22 +612,18 @@ LINUX_FallbackJoystickDetect(void)
/* Opening input devices can generate synchronous device I/O, so avoid it if we can */
if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) {
DIR *folder;
struct dirent *dent;
int i, count;
struct dirent **entries;
char path[PATH_MAX];
folder = opendir("/dev/input");
if (folder) {
while ((dent = readdir(folder))) {
int len = SDL_strlen(dent->d_name);
if (len > 5 && SDL_strncmp(dent->d_name, "event", 5) == 0) {
char path[PATH_MAX];
SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", dent->d_name);
MaybeAddDevice(path);
}
}
count = scandir("/dev/input", &entries, filter_entries, sort_entries);
for (i = 0; i < count; ++i) {
SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name);
MaybeAddDevice(path);
closedir(folder);
free(entries[i]); /* This should NOT be SDL_free() */
}
free(entries); /* This should NOT be SDL_free() */
last_input_dir_mtime = sb.st_mtime;
}
@@ -965,6 +973,48 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
}
/* This is used to do the heavy lifting for LINUX_JoystickOpen and
also LINUX_JoystickGetGamepadMapping, so we can query the hardware
without adding an opened SDL_Joystick object to the system.
This expects `joystick->hwdata` to be allocated and will not free it
on error. Returns -1 on error, 0 on success. */
static int
PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item)
{
joystick->hwdata->item = item;
joystick->hwdata->guid = item->guid;
joystick->hwdata->effect.id = -1;
joystick->hwdata->m_bSteamController = item->m_bSteamController;
SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map));
if (item->m_bSteamController) {
joystick->hwdata->fd = -1;
SDL_GetSteamControllerInputs(&joystick->nbuttons,
&joystick->naxes,
&joystick->nhats);
} else {
const int fd = open(item->path, O_RDWR, 0);
if (fd < 0) {
return SDL_SetError("Unable to open %s", item->path);
}
joystick->hwdata->fd = fd;
joystick->hwdata->fname = SDL_strdup(item->path);
if (joystick->hwdata->fname == NULL) {
close(fd);
return SDL_OutOfMemory();
}
/* Set the joystick to non-blocking read mode */
fcntl(fd, F_SETFL, O_NONBLOCK);
/* Get the number of buttons and axes on the joystick */
ConfigJoystick(joystick, fd);
}
return 0;
}
/* Function to open a joystick for use.
The joystick to open is specified by the device index.
This should fill the nbuttons and naxes fields of the joystick structure.
@@ -985,39 +1035,11 @@ LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index)
if (joystick->hwdata == NULL) {
return SDL_OutOfMemory();
}
joystick->hwdata->item = item;
joystick->hwdata->guid = item->guid;
joystick->hwdata->effect.id = -1;
joystick->hwdata->m_bSteamController = item->m_bSteamController;
SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map));
if (item->m_bSteamController) {
joystick->hwdata->fd = -1;
SDL_GetSteamControllerInputs(&joystick->nbuttons,
&joystick->naxes,
&joystick->nhats);
} else {
int fd = open(item->path, O_RDWR, 0);
if (fd < 0) {
SDL_free(joystick->hwdata);
joystick->hwdata = NULL;
return SDL_SetError("Unable to open %s", item->path);
}
joystick->hwdata->fd = fd;
joystick->hwdata->fname = SDL_strdup(item->path);
if (joystick->hwdata->fname == NULL) {
SDL_free(joystick->hwdata);
joystick->hwdata = NULL;
close(fd);
return SDL_OutOfMemory();
}
/* Set the joystick to non-blocking read mode */
fcntl(fd, F_SETFL, O_NONBLOCK);
/* Get the number of buttons and axes on the joystick */
ConfigJoystick(joystick, fd);
if (PrepareJoystickHwdata(joystick, item) == -1) {
SDL_free(joystick->hwdata);
joystick->hwdata = NULL;
return -1; /* SDL_SetError will already have been called */
}
SDL_assert(item->hwdata == NULL);
@@ -1026,7 +1048,7 @@ LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index)
/* mark joystick as fresh and ready */
joystick->hwdata->fresh = SDL_TRUE;
return (0);
return 0;
}
static int
@@ -1089,6 +1111,12 @@ LINUX_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
return SDL_Unsupported();
}
static int
LINUX_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1411,18 +1439,32 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
return SDL_TRUE;
}
/* We temporarily open the device to check how it's configured. Make
a fake SDL_Joystick object to do so. */
joystick = (SDL_Joystick *) SDL_calloc(sizeof(*joystick), 1);
if (joystick == NULL) {
SDL_OutOfMemory();
return SDL_FALSE;
}
/* We temporarily open the device to check how it's configured. */
if (LINUX_JoystickOpen(joystick, device_index) < 0) {
joystick->hwdata = (struct joystick_hwdata *)
SDL_calloc(1, sizeof(*joystick->hwdata));
if (joystick->hwdata == NULL) {
SDL_free(joystick);
SDL_OutOfMemory();
return SDL_FALSE;
}
if (PrepareJoystickHwdata(joystick, item) == -1) {
SDL_free(joystick->hwdata);
SDL_free(joystick);
return SDL_FALSE; /* SDL_SetError will already have been called */
}
/* don't assign `item->hwdata` so it's not in any global state. */
/* it is now safe to call LINUX_JoystickClose on this fake joystick. */
if (!joystick->hwdata->has_key[BTN_GAMEPAD]) {
/* Not a gamepad according to the specs. */
LINUX_JoystickClose(joystick);
@@ -1603,6 +1645,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
LINUX_JoystickRumbleTriggers,
LINUX_JoystickHasLED,
LINUX_JoystickSetLED,
LINUX_JoystickSendEffect,
LINUX_JoystickSetSensorsEnabled,
LINUX_JoystickUpdate,
LINUX_JoystickClose,
+6
View File
@@ -484,6 +484,11 @@ static int OS2_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Ui
return SDL_Unsupported();
}
static int OS2_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int OS2_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
return SDL_Unsupported();
@@ -777,6 +782,7 @@ SDL_JoystickDriver SDL_OS2_JoystickDriver =
OS2_JoystickRumbleTriggers,
OS2_JoystickHasLED,
OS2_JoystickSetLED,
OS2_JoystickSendEffect,
OS2_JoystickSetSensorsEnabled,
OS2_JoystickUpdate,
OS2_JoystickClose,
+7
View File
@@ -220,6 +220,12 @@ PSP_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
return SDL_Unsupported();
}
static int
PSP_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int PSP_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
return SDL_Unsupported();
@@ -307,6 +313,7 @@ SDL_JoystickDriver SDL_PSP_JoystickDriver =
PSP_JoystickRumbleTriggers,
PSP_JoystickHasLED,
PSP_JoystickSetLED,
PSP_JoystickSendEffect,
PSP_JoystickSetSensorsEnabled,
PSP_JoystickUpdate,
PSP_JoystickClose,
+1 -1
View File
@@ -67,7 +67,7 @@ def write_controllers():
for entry in sorted(controllers, key=lambda entry: entry[2]+"-"+entry[1]):
line = "".join(entry) + "\n"
line = line.replace("\t", " ")
if not line.endswith(",\n") and not line.endswith("*/\n"):
if not line.endswith(",\n") and not line.endswith("*/\n") and not line.endswith(",\r\n") and not line.endswith("*/\r\n"):
print("Warning: '%s' is missing a comma at the end of the line" % (line))
output.write(line)
+19 -4
View File
@@ -24,6 +24,7 @@
/* Definitions of useful USB VID/PID values */
#define USB_VENDOR_AMAZON 0x1949
#define USB_VENDOR_APPLE 0x05ac
#define USB_VENDOR_GOOGLE 0x18d1
#define USB_VENDOR_HYPERKIN 0x2e24
@@ -31,19 +32,21 @@
#define USB_VENDOR_NINTENDO 0x057e
#define USB_VENDOR_NVIDIA 0x0955
#define USB_VENDOR_PDP 0x0e6f
#define USB_VENDOR_POWERA_ALT 0x20d6
#define USB_VENDOR_POWERA 0x24c6
#define USB_VENDOR_POWERA_ALT 0x20d6
#define USB_VENDOR_RAZER 0x1532
#define USB_VENDOR_SHENZHEN 0x0079
#define USB_VENDOR_SONY 0x054c
#define USB_VENDOR_VALVE 0x28de
#define USB_PRODUCT_AMAZON_LUNA_CONTROLLER 0x0419
#define USB_PRODUCT_GOOGLE_STADIA_CONTROLLER 0x9400
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER 0x1846
#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337
#define USB_PRODUCT_NINTENDO_SWITCH_PRO 0x2009
#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT 0x2006
#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT 0x2007
#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP 0x200e
#define USB_PRODUCT_RAZER_PANTHERA 0x0401
#define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008
#define USB_PRODUCT_RAZER_ATROX 0x0a00
@@ -52,6 +55,7 @@
#define USB_PRODUCT_SONY_DS4_SLIM 0x09cc
#define USB_PRODUCT_SONY_DS5 0x0ce6
#define USB_PRODUCT_XBOX360_XUSB_CONTROLLER 0x02a1 /* XUSB driver software PID */
#define USB_PRODUCT_XBOX360_WIRED_CONTROLLER 0x028e
#define USB_PRODUCT_XBOX360_WIRELESS_RECEIVER 0x0719
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00
@@ -59,11 +63,16 @@
#define USB_PRODUCT_XBOX_ONE_S 0x02ea
#define USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH 0x02e0
#define USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH 0x02fd
#define USB_PRODUCT_XBOX_ONE_SERIES_X 0x0b12
#define USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH 0x0b13
#define USB_PRODUCT_XBOX_ONE_SERIES_X_POWERA 0x2001
#define USB_PRODUCT_XBOX_SERIES_X 0x0b12
#define USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH 0x0b13
#define USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT 0x02d6
#define USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE 0x02d9
#define USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW 0x02da
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 0x4001
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA 0x4002
#define USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER 0x02ff /* XBOXGIP driver software PID */
#define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER 0x02fe /* Made up product ID for XInput */
#define USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD 0x11ff
/* USB usage pages */
#define USB_USAGEPAGE_GENERIC_DESKTOP 0x0001
@@ -88,6 +97,12 @@
#define USB_USAGE_GENERIC_WHEEL 0x0038
#define USB_USAGE_GENERIC_HAT 0x0039
/* Bluetooth SIG assigned Company Identifiers
https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers/ */
#define BLUETOOTH_VENDOR_AMAZON 0x0171
#define BLUETOOTH_PRODUCT_LUNA_CONTROLLER 0x0419
#endif /* usb_ids_h_ */
/* vi: set ts=4 sw=4 expandtab: */
+19 -12
View File
@@ -164,7 +164,7 @@ SDL_JoystickDetachVirtualInner(int device_index)
int
SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value)
SDL_JoystickSetVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value)
{
joystick_hwdata *hwdata;
@@ -176,7 +176,7 @@ SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value)
}
hwdata = (joystick_hwdata *)joystick->hwdata;
if (axis < 0 || axis >= hwdata->nbuttons) {
if (axis < 0 || axis >= hwdata->naxes) {
SDL_UnlockJoysticks();
return SDL_SetError("Invalid axis index");
}
@@ -189,7 +189,7 @@ SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value)
int
SDL_JoystickSetVirtualButtonInner(SDL_Joystick * joystick, int button, Uint8 value)
SDL_JoystickSetVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 value)
{
joystick_hwdata *hwdata;
@@ -214,7 +214,7 @@ SDL_JoystickSetVirtualButtonInner(SDL_Joystick * joystick, int button, Uint8 val
int
SDL_JoystickSetVirtualHatInner(SDL_Joystick * joystick, int hat, Uint8 value)
SDL_JoystickSetVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value)
{
joystick_hwdata *hwdata;
@@ -226,7 +226,7 @@ SDL_JoystickSetVirtualHatInner(SDL_Joystick * joystick, int hat, Uint8 value)
}
hwdata = (joystick_hwdata *)joystick->hwdata;
if (hat < 0 || hat >= hwdata->nbuttons) {
if (hat < 0 || hat >= hwdata->nhats) {
SDL_UnlockJoysticks();
return SDL_SetError("Invalid hat index");
}
@@ -313,7 +313,7 @@ VIRTUAL_JoystickGetDeviceInstanceID(int device_index)
static int
VIRTUAL_JoystickOpen(SDL_Joystick * joystick, int device_index)
VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
if (!hwdata) {
@@ -333,27 +333,33 @@ VIRTUAL_JoystickOpen(SDL_Joystick * joystick, int device_index)
static int
VIRTUAL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
return SDL_Unsupported();
}
static int
VIRTUAL_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}
static SDL_bool
VIRTUAL_JoystickHasLED(SDL_Joystick * joystick)
VIRTUAL_JoystickHasLED(SDL_Joystick *joystick)
{
return SDL_FALSE;
}
static int
VIRTUAL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static int
VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
@@ -366,7 +372,7 @@ VIRTUAL_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
static void
VIRTUAL_JoystickUpdate(SDL_Joystick * joystick)
VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
{
joystick_hwdata *hwdata;
int i;
@@ -393,7 +399,7 @@ VIRTUAL_JoystickUpdate(SDL_Joystick * joystick)
static void
VIRTUAL_JoystickClose(SDL_Joystick * joystick)
VIRTUAL_JoystickClose(SDL_Joystick *joystick)
{
joystick_hwdata *hwdata;
@@ -438,6 +444,7 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
VIRTUAL_JoystickRumbleTriggers,
VIRTUAL_JoystickHasLED,
VIRTUAL_JoystickSetLED,
VIRTUAL_JoystickSendEffect,
VIRTUAL_JoystickSetSensorsEnabled,
VIRTUAL_JoystickUpdate,
VIRTUAL_JoystickClose,
+11 -4
View File
@@ -347,7 +347,7 @@ SDL_JoystickGUID VITA_JoystickGetDeviceGUID( int device_index )
}
static int
VITA_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
VITA_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
int index = (int) SDL_JoystickInstanceID(joystick);
SceCtrlActuator act;
@@ -360,13 +360,13 @@ VITA_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16
}
static int
VITA_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left, Uint16 right)
VITA_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right)
{
return SDL_Unsupported();
}
static SDL_bool
VITA_JoystickHasLED(SDL_Joystick * joystick)
VITA_JoystickHasLED(SDL_Joystick *joystick)
{
// always return true for now
return SDL_TRUE;
@@ -374,13 +374,19 @@ VITA_JoystickHasLED(SDL_Joystick * joystick)
static int
VITA_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
VITA_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
int index = (int) SDL_JoystickInstanceID(joystick);
sceCtrlSetLightBar(ext_port_map[index], red, green, blue);
return 0;
}
static int
VITA_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
VITA_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -405,6 +411,7 @@ SDL_JoystickDriver SDL_VITA_JoystickDriver =
VITA_JoystickHasLED,
VITA_JoystickSetLED,
VITA_JoystickSendEffect,
VITA_JoystickSetSensorsEnabled,
VITA_JoystickUpdate,
+108 -76
View File
@@ -34,7 +34,7 @@
#define DIDFT_OPTIONAL 0x80000000
#endif
#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */
#define INPUT_QSIZE 128 /* Buffer up to 128 input messages */
#define JOY_AXIS_THRESHOLD (((SDL_JOYSTICK_AXIS_MAX)-(SDL_JOYSTICK_AXIS_MIN))/100) /* 1% motion */
#define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF)
@@ -245,7 +245,7 @@ SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char* hidPath)
type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0);
if (type == SDL_CONTROLLER_TYPE_XBOX360 ||
type == SDL_CONTROLLER_TYPE_XBOXONE ||
(vendor_id == 0x28DE && product_id == 0x11FF)) {
(vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD)) {
return SDL_TRUE;
}
@@ -425,7 +425,7 @@ SDL_DINPUT_JoystickInit(void)
/* helper function for direct input, gets called for each connected joystick */
static BOOL CALLBACK
EnumJoysticksCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
{
#define CHECK(exp) { if(!(exp)) goto err; }
JoyStick_DeviceData *pNewJoystick = NULL;
@@ -534,31 +534,56 @@ err:
void
SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
{
IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY);
IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickDetectCallback, pContext, DIEDFL_ATTACHEDONLY);
}
/* helper function for direct input, gets called for each connected joystick */
typedef struct
{
Uint16 vendor;
Uint16 product;
SDL_bool present;
} Joystick_PresentData;
static BOOL CALLBACK
EnumJoystickPresentCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
{
#define CHECK(exp) { if(!(exp)) goto err; }
Joystick_PresentData *pData = (Joystick_PresentData *)pContext;
Uint16 vendor = 0;
Uint16 product = 0;
LPDIRECTINPUTDEVICE8 device = NULL;
/* We are only supporting HID devices. */
CHECK((pDeviceInstance->dwDevType & DIDEVTYPE_HID) != 0);
CHECK(SUCCEEDED(IDirectInput8_CreateDevice(dinput, &pDeviceInstance->guidInstance, &device, NULL)));
CHECK(QueryDeviceInfo(device, &vendor, &product));
if (vendor == pData->vendor && product == pData->product) {
pData->present = SDL_TRUE;
return DIENUM_STOP; /* get next device, please */
}
err:
if (device) {
IDirectInputDevice8_Release(device);
}
return DIENUM_CONTINUE; /* get next device, please */
#undef CHECK
}
SDL_bool
SDL_DINPUT_JoystickPresent(Uint16 vendor_id, Uint16 product_id, Uint16 version_number)
{
JoyStick_DeviceData* joystick = SYS_Joystick;
Uint16 vendor = 0;
Uint16 product = 0;
Uint16 version = 0;
Joystick_PresentData data;
while (joystick) {
SDL_GetJoystickGUIDInfo(joystick->guid, &vendor, &product, &version);
if (!joystick->bXInputDevice &&
vendor == vendor_id &&
product == product_id &&
version == version_number) {
return SDL_TRUE;
}
joystick = joystick->pNext;
}
return SDL_FALSE;
data.vendor = vendor_id;
data.product = product_id;
data.present = SDL_FALSE;
IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickPresentCallback, &data, DIEDFL_ATTACHEDONLY);
return data.present;
}
static BOOL CALLBACK
@@ -922,60 +947,6 @@ TranslatePOV(DWORD value)
return HAT_VALS[value];
}
static void
UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick)
{
int i;
HRESULT result;
DWORD numevents;
DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
numevents = INPUT_QSIZE;
result =
IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
sizeof(DIDEVICEOBJECTDATA), evtbuf,
&numevents, 0);
if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
result =
IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
sizeof(DIDEVICEOBJECTDATA),
evtbuf, &numevents, 0);
}
/* Handle the events or punt */
if (FAILED(result)) {
return;
}
for (i = 0; i < (int)numevents; ++i) {
int j;
for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
const input_t *in = &joystick->hwdata->Inputs[j];
if (evtbuf[i].dwOfs != in->ofs)
continue;
switch (in->type) {
case AXIS:
SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData);
break;
case BUTTON:
SDL_PrivateJoystickButton(joystick, in->num,
(Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED));
break;
case HAT:
{
Uint8 pos = TranslatePOV(evtbuf[i].dwData);
SDL_PrivateJoystickHat(joystick, in->num, pos);
}
break;
}
}
}
}
/* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly,
* but instead should call SDL_PrivateJoystick*() to deliver events
@@ -1050,6 +1021,67 @@ UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick)
}
}
static void
UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick)
{
int i;
HRESULT result;
DWORD numevents;
DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
numevents = INPUT_QSIZE;
result =
IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
sizeof(DIDEVICEOBJECTDATA), evtbuf,
&numevents, 0);
if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
result =
IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
sizeof(DIDEVICEOBJECTDATA),
evtbuf, &numevents, 0);
}
/* Handle the events or punt */
if (FAILED(result)) {
return;
}
for (i = 0; i < (int)numevents; ++i) {
int j;
for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
const input_t *in = &joystick->hwdata->Inputs[j];
if (evtbuf[i].dwOfs != in->ofs)
continue;
switch (in->type) {
case AXIS:
SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData);
break;
case BUTTON:
SDL_PrivateJoystickButton(joystick, in->num,
(Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED));
break;
case HAT:
{
Uint8 pos = TranslatePOV(evtbuf[i].dwData);
SDL_PrivateJoystickHat(joystick, in->num, pos);
}
break;
}
}
}
if (result == DI_BUFFEROVERFLOW) {
/* Our buffer wasn't big enough to hold all the queued events,
* so poll the device to make sure we have the complete state.
*/
UpdateDINPUTJoystickState_Polled(joystick);
}
}
void
SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
{
+10 -3
View File
@@ -244,7 +244,7 @@ static SDL_JoystickID WINMM_JoystickGetDeviceInstanceID(int device_index)
It returns 0, or -1 if there is an error.
*/
static int
WINMM_JoystickOpen(SDL_Joystick * joystick, int device_index)
WINMM_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
int index, i;
int caps_flags[MAX_AXES - 2] =
@@ -345,6 +345,12 @@ WINMM_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
return SDL_Unsupported();
}
static int
WINMM_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int WINMM_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
return SDL_Unsupported();
@@ -356,7 +362,7 @@ static int WINMM_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enab
* and update joystick device state.
*/
static void
WINMM_JoystickUpdate(SDL_Joystick * joystick)
WINMM_JoystickUpdate(SDL_Joystick *joystick)
{
MMRESULT result;
int i;
@@ -414,7 +420,7 @@ WINMM_JoystickUpdate(SDL_Joystick * joystick)
/* Function to close a joystick after use */
static void
WINMM_JoystickClose(SDL_Joystick * joystick)
WINMM_JoystickClose(SDL_Joystick *joystick)
{
SDL_free(joystick->hwdata);
}
@@ -496,6 +502,7 @@ SDL_JoystickDriver SDL_WINMM_JoystickDriver =
WINMM_JoystickRumbleTriggers,
WINMM_JoystickHasLED,
WINMM_JoystickSetLED,
WINMM_JoystickSendEffect,
WINMM_JoystickSetSensorsEnabled,
WINMM_JoystickUpdate,
WINMM_JoystickClose,
+8 -1
View File
@@ -1042,7 +1042,7 @@ RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
/* We'll try to get guide button and trigger axes from XInput */
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
xinput_device_change = SDL_TRUE;
ctx->xinput_enabled = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_CORRELATE_XINPUT, SDL_TRUE);
ctx->xinput_enabled = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT, SDL_TRUE);
if (ctx->xinput_enabled && (WIN_LoadXInputDLL() < 0 || !XINPUTGETSTATE)) {
ctx->xinput_enabled = SDL_FALSE;
}
@@ -1289,6 +1289,12 @@ RAWINPUT_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 bl
return SDL_Unsupported();
}
static int
RAWINPUT_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int
RAWINPUT_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
@@ -1924,6 +1930,7 @@ SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver =
RAWINPUT_JoystickRumbleTriggers,
RAWINPUT_JoystickHasLED,
RAWINPUT_JoystickSetLED,
RAWINPUT_JoystickSendEffect,
RAWINPUT_JoystickSetSensorsEnabled,
RAWINPUT_JoystickUpdate,
RAWINPUT_JoystickClose,
@@ -206,6 +206,9 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
}
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
}
if (!name) {
name = "";
}
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IGameController, (void **)&gamecontroller);
if (SUCCEEDED(hr)) {
@@ -486,7 +489,7 @@ WGI_JoystickGetDeviceInstanceID(int device_index)
}
static int
WGI_JoystickOpen(SDL_Joystick * joystick, int device_index)
WGI_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
WindowsGamingInputControllerState *state = &wgi.controllers[device_index];
struct joystick_hwdata *hwdata;
@@ -558,7 +561,7 @@ WGI_JoystickOpen(SDL_Joystick * joystick, int device_index)
}
static int
WGI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
WGI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
struct joystick_hwdata *hwdata = joystick->hwdata;
@@ -579,7 +582,7 @@ WGI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16
}
static int
WGI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
WGI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
struct joystick_hwdata *hwdata = joystick->hwdata;
@@ -600,13 +603,19 @@ WGI_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 r
}
static SDL_bool
WGI_JoystickHasLED(SDL_Joystick * joystick)
WGI_JoystickHasLED(SDL_Joystick *joystick)
{
return SDL_FALSE;
}
static int
WGI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
WGI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static int
WGI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
@@ -643,7 +652,7 @@ ConvertHatValue(__x_ABI_CWindows_CGaming_CInput_CGameControllerSwitchPosition va
}
static void
WGI_JoystickUpdate(SDL_Joystick * joystick)
WGI_JoystickUpdate(SDL_Joystick *joystick)
{
struct joystick_hwdata *hwdata = joystick->hwdata;
HRESULT hr;
@@ -677,7 +686,7 @@ WGI_JoystickUpdate(SDL_Joystick * joystick)
}
static void
WGI_JoystickClose(SDL_Joystick * joystick)
WGI_JoystickClose(SDL_Joystick *joystick)
{
struct joystick_hwdata *hwdata = joystick->hwdata;
@@ -738,7 +747,51 @@ WGI_JoystickQuit(void)
}
SDL_zero(wgi);
WIN_CoUninitialize();
/* Don't uninitialize COM because of what appears to be a bug in Microsoft WGI reference counting.
*
* If you plug in a non-Xbox controller and let the application run for 30 seconds, then it crashes in CoUninitialize()
* with this stack trace:
Windows.Gaming.Input.dll!GameController::~GameController(void) Unknown
Windows.Gaming.Input.dll!GameController::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Gaming::Input::IGameController,struct Windows::Gaming::Input::IGameControllerBatteryInfo,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerPrivate>,class Microsoft::WRL::FtmBase>::Release(void) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::AggregableRuntimeClass<struct Windows::Gaming::Input::IGamepad,struct Windows::Gaming::Input::IGamepad2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGipGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IHidGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IXusbGameControllerInputSink>,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil>::Release(void) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>() Unknown
Windows.Gaming.Input.dll!`eh vector destructor iterator'(void *,unsigned int,int,void (*)(void *)) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::~GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>(void) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Foundation::Collections::IIterable<class Windows::Gaming::Input::ArcadeStick *>,struct Windows::Foundation::Collections::IVectorView<class Windows::Gaming::Input::ArcadeStick *>,class Microsoft::WRL::FtmBase>::Release(void) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::~CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>(void) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::ICustomGameControllerFactory> >,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil,0>::Release(void) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>() Unknown
Windows.Gaming.Input.dll!NtList<struct FactoryManager::FactoryListEntry>::~NtList<struct FactoryManager::FactoryListEntry>(void) Unknown
Windows.Gaming.Input.dll!FactoryManager::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics>,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerFactoryManagerStaticsPrivate>,0>::Release(void) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Details::TerminateMap(class Microsoft::WRL::Details::ModuleBase *,unsigned short const *,bool) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Module<1,class Microsoft::WRL::Details::DefaultModule<1> >::~Module<1,class Microsoft::WRL::Details::DefaultModule<1> >(void) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Details::DefaultModule<1>::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!`dynamic atexit destructor for 'Microsoft::WRL::Details::StaticStorage<Microsoft::WRL::Details::DefaultModule<1>,0,int>::instance_''() Unknown
Windows.Gaming.Input.dll!__CRT_INIT@12() Unknown
Windows.Gaming.Input.dll!__DllMainCRTStartup() Unknown
ntdll.dll!_LdrxCallInitRoutine@16() Unknown
ntdll.dll!LdrpCallInitRoutine() Unknown
ntdll.dll!LdrpProcessDetachNode() Unknown
ntdll.dll!LdrpUnloadNode() Unknown
ntdll.dll!LdrpDecrementModuleLoadCountEx() Unknown
ntdll.dll!LdrUnloadDll() Unknown
KernelBase.dll!FreeLibrary() Unknown
combase.dll!FreeLibraryWithLogging(LoadOrFreeWhy why, HINSTANCE__ * hMod, const wchar_t * pswzOptionalFileName) Line 193 C++
combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3311 C++
combase.dll!CClassCache::CFinishComposite::Finish() Line 3421 C++
combase.dll!CClassCache::CleanUpDllsForProcess() Line 7009 C++
[Inline Frame] combase.dll!CCCleanUpDllsForProcess() Line 8773 C++
combase.dll!ProcessUninitialize() Line 2243 C++
combase.dll!DecrementProcessInitializeCount() Line 993 C++
combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 4126 C++
combase.dll!CoUninitialize() Line 3945 C++
*/
/* WIN_CoUninitialize(); */
}
static SDL_bool
@@ -762,6 +815,7 @@ SDL_JoystickDriver SDL_WGI_JoystickDriver =
WGI_JoystickRumbleTriggers,
WGI_JoystickHasLED,
WGI_JoystickSetLED,
WGI_JoystickSendEffect,
WGI_JoystickSetSensorsEnabled,
WGI_JoystickUpdate,
WGI_JoystickClose,
+144 -35
View File
@@ -59,6 +59,77 @@
#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
#endif
/* CM_Register_Notification definitions */
#define CR_SUCCESS (0x00000000)
DECLARE_HANDLE(HCMNOTIFICATION);
typedef HCMNOTIFICATION* PHCMNOTIFICATION;
typedef enum _CM_NOTIFY_FILTER_TYPE {
CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE = 0,
CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE,
CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE,
CM_NOTIFY_FILTER_TYPE_MAX
} CM_NOTIFY_FILTER_TYPE, * PCM_NOTIFY_FILTER_TYPE;
typedef struct _CM_NOTIFY_FILTER {
DWORD cbSize;
DWORD Flags;
CM_NOTIFY_FILTER_TYPE FilterType;
DWORD Reserved;
union {
struct {
GUID ClassGuid;
} DeviceInterface;
struct {
HANDLE hTarget;
} DeviceHandle;
struct {
WCHAR InstanceId[200];
} DeviceInstance;
} u;
} CM_NOTIFY_FILTER, * PCM_NOTIFY_FILTER;
typedef enum _CM_NOTIFY_ACTION {
CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL = 0,
CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL,
CM_NOTIFY_ACTION_DEVICEQUERYREMOVE,
CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED,
CM_NOTIFY_ACTION_DEVICEREMOVEPENDING,
CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE,
CM_NOTIFY_ACTION_DEVICECUSTOMEVENT,
CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED,
CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED,
CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED,
CM_NOTIFY_ACTION_MAX
} CM_NOTIFY_ACTION, * PCM_NOTIFY_ACTION;
typedef struct _CM_NOTIFY_EVENT_DATA {
CM_NOTIFY_FILTER_TYPE FilterType;
DWORD Reserved;
union {
struct {
GUID ClassGuid;
WCHAR SymbolicLink[ANYSIZE_ARRAY];
} DeviceInterface;
struct {
GUID EventGuid;
LONG NameOffset;
DWORD DataSize;
BYTE Data[ANYSIZE_ARRAY];
} DeviceHandle;
struct {
WCHAR InstanceId[ANYSIZE_ARRAY];
} DeviceInstance;
} u;
} CM_NOTIFY_EVENT_DATA, * PCM_NOTIFY_EVENT_DATA;
typedef DWORD (CALLBACK *PCM_NOTIFY_CALLBACK)(HCMNOTIFICATION hNotify, PVOID Context, CM_NOTIFY_ACTION Action, PCM_NOTIFY_EVENT_DATA EventData, DWORD EventDataSize);
typedef DWORD (WINAPI *CM_Register_NotificationFunc)(PCM_NOTIFY_FILTER pFilter, PVOID pContext, PCM_NOTIFY_CALLBACK pCallback, PHCMNOTIFICATION pNotifyContext);
typedef DWORD (WINAPI *CM_Unregister_NotificationFunc)(HCMNOTIFICATION NotifyContext);
/* local variables */
static SDL_bool s_bJoystickThread = SDL_FALSE;
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
@@ -66,35 +137,64 @@ static SDL_cond *s_condJoystickThread = NULL;
static SDL_mutex *s_mutexJoyStickEnum = NULL;
static SDL_Thread *s_joystickThread = NULL;
static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
#ifdef __WINRT__
#ifndef __WINRT__
static HMODULE cfgmgr32_lib_handle;
static CM_Register_NotificationFunc CM_Register_Notification;
static CM_Unregister_NotificationFunc CM_Unregister_Notification;
static HCMNOTIFICATION s_DeviceNotificationFuncHandle;
typedef struct
{
int unused;
} SDL_DeviceNotificationData;
static void
SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
static DWORD CALLBACK
SDL_DeviceNotificationFunc(HCMNOTIFICATION hNotify, PVOID context, CM_NOTIFY_ACTION action, PCM_NOTIFY_EVENT_DATA eventData, DWORD event_data_size)
{
if (action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL ||
action == CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL) {
s_bWindowsDeviceChanged = SDL_TRUE;
}
return ERROR_SUCCESS;
}
static int
SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
static void
SDL_CleanupDeviceNotificationFunc(void)
{
return 0;
if (cfgmgr32_lib_handle) {
if (s_DeviceNotificationFuncHandle) {
CM_Unregister_Notification(s_DeviceNotificationFuncHandle);
s_DeviceNotificationFuncHandle = NULL;
}
FreeLibrary(cfgmgr32_lib_handle);
cfgmgr32_lib_handle = NULL;
}
}
static SDL_bool
SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex)
SDL_CreateDeviceNotificationFunc(void)
{
cfgmgr32_lib_handle = LoadLibraryA("cfgmgr32.dll");
if (cfgmgr32_lib_handle) {
CM_Register_Notification = (CM_Register_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Register_Notification");
CM_Unregister_Notification = (CM_Unregister_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Unregister_Notification");
if (CM_Register_Notification && CM_Unregister_Notification) {
CM_NOTIFY_FILTER notify_filter;
SDL_zero(notify_filter);
notify_filter.cbSize = sizeof(notify_filter);
notify_filter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE;
notify_filter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_HID;
if (CM_Register_Notification(&notify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) {
return SDL_TRUE;
}
}
}
SDL_CleanupDeviceNotificationFunc();
return SDL_FALSE;
}
#else /* !__WINRT__ */
typedef struct
{
HRESULT coinitialized;
@@ -164,7 +264,6 @@ static int
SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
{
DEV_BROADCAST_DEVICEINTERFACE dbh;
GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
SDL_zerop(data);
@@ -228,8 +327,6 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex
return (lastret != -1) ? SDL_TRUE : SDL_FALSE;
}
#endif /* __WINRT__ */
static SDL_DeviceNotificationData s_notification_data;
/* Function/thread to scan the system for joysticks. */
@@ -310,9 +407,7 @@ SDL_StopJoystickThread(void)
s_bJoystickThreadQuit = SDL_TRUE;
SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */
SDL_UnlockMutex(s_mutexJoyStickEnum);
#ifndef __WINRT__
PostThreadMessage(SDL_GetThreadID(s_joystickThread), WM_QUIT, 0, 0);
#endif
SDL_WaitThread(s_joystickThread, NULL); /* wait for it to bugger off */
SDL_DestroyCond(s_condJoystickThread);
@@ -324,6 +419,8 @@ SDL_StopJoystickThread(void)
s_joystickThread = NULL;
}
#endif /* !__WINRT__ */
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
{
device->send_add_event = SDL_TRUE;
@@ -356,15 +453,9 @@ WINDOWS_JoystickInit(void)
WINDOWS_JoystickDetect();
#ifdef __WINRT__
/* FIXME: WinRT silently does not support device notifications.
* Revisit this if UWP ever adds support in a future release.
*/
s_bJoystickThread = SDL_TRUE;
if (SDL_StartJoystickThread() < 0) {
return -1;
}
#else
#ifndef __WINRT__
SDL_CreateDeviceNotificationFunc();
s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE);
if (s_bJoystickThread) {
if (SDL_StartJoystickThread() < 0) {
@@ -526,7 +617,7 @@ WINDOWS_JoystickGetDeviceInstanceID(int device_index)
It returns 0, or -1 if there is an error.
*/
static int
WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
WINDOWS_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
JoyStick_DeviceData *device = SYS_Joystick;
int index;
@@ -552,7 +643,7 @@ WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
}
static int
WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
WINDOWS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
if (joystick->hwdata->bXInputDevice) {
return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble);
@@ -562,19 +653,25 @@ WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
}
static int
WINDOWS_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
WINDOWS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}
static SDL_bool
WINDOWS_JoystickHasLED(SDL_Joystick * joystick)
WINDOWS_JoystickHasLED(SDL_Joystick *joystick)
{
return SDL_FALSE;
}
static int
WINDOWS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
WINDOWS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static int
WINDOWS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
@@ -586,7 +683,7 @@ WINDOWS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
}
static void
WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
WINDOWS_JoystickUpdate(SDL_Joystick *joystick)
{
if (!joystick->hwdata) {
return;
@@ -601,7 +698,7 @@ WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
/* Function to close a joystick after use */
static void
WINDOWS_JoystickClose(SDL_Joystick * joystick)
WINDOWS_JoystickClose(SDL_Joystick *joystick)
{
if (joystick->hwdata->bXInputDevice) {
SDL_XINPUT_JoystickClose(joystick);
@@ -626,12 +723,16 @@ WINDOWS_JoystickQuit(void)
}
SYS_Joystick = NULL;
#ifndef __WINRT__
if (s_bJoystickThread) {
SDL_StopJoystickThread();
} else {
SDL_CleanupDeviceNotification(&s_notification_data);
}
SDL_CleanupDeviceNotificationFunc();
#endif
SDL_DINPUT_JoystickQuit();
SDL_XINPUT_JoystickQuit();
@@ -659,6 +760,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
WINDOWS_JoystickRumbleTriggers,
WINDOWS_JoystickHasLED,
WINDOWS_JoystickSetLED,
WINDOWS_JoystickSendEffect,
WINDOWS_JoystickSetSensorsEnabled,
WINDOWS_JoystickUpdate,
WINDOWS_JoystickClose,
@@ -666,6 +768,13 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
WINDOWS_JoystickGetGamepadMapping
};
#else
#if SDL_JOYSTICK_RAWINPUT
/* The RAWINPUT driver needs the device notification setup above */
#error SDL_JOYSTICK_RAWINPUT requires SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT
#endif
#endif /* SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT */
/* vi: set ts=4 sw=4 expandtab: */
-3
View File
@@ -15,9 +15,6 @@ main(int argc, char *argv[])
}
#else
/* Nothing to do on this platform */
int
SDL_main_stub_symbol(void);
int
SDL_main_stub_symbol(void)
{
+2
View File
@@ -6,6 +6,7 @@
/* Include the SDL main definition header */
#include "SDL_main.h"
#ifndef SDL_MAIN_HANDLED
#ifdef main
#undef main
#endif
@@ -15,5 +16,6 @@ main(int argc, char *argv[])
{
return SDL_UIKitRunApp(argc, argv, SDL_main);
}
#endif /* !SDL_MAIN_HANDLED */
/* vi: set ts=4 sw=4 expandtab: */
+5 -5
View File
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,0,15,0
PRODUCTVERSION 2,0,15,0
FILEVERSION 2,0,16,0
PRODUCTVERSION 2,0,16,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
@@ -23,12 +23,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL\0"
VALUE "FileVersion", "2, 0, 15, 0\0"
VALUE "FileVersion", "2, 0, 16, 0\0"
VALUE "InternalName", "SDL\0"
VALUE "LegalCopyright", "Copyright © 2021 Sam Lantinga\0"
VALUE "LegalCopyright", "Copyright (C) 2021 Sam Lantinga\0"
VALUE "OriginalFilename", "SDL2.dll\0"
VALUE "ProductName", "Simple DirectMedia Layer\0"
VALUE "ProductVersion", "2, 0, 15, 0\0"
VALUE "ProductVersion", "2, 0, 16, 0\0"
END
END
BLOCK "VarFileInfo"
+4 -1
View File
@@ -33,8 +33,11 @@ SDL_SYS_OpenURL(const char *url)
{
const pid_t pid1 = fork();
if (pid1 == 0) { /* child process */
pid_t pid2;
/* Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam */
unsetenv("LD_PRELOAD");
/* Notice this is vfork and not fork! */
const pid_t pid2 = vfork();
pid2 = vfork();
if (pid2 == 0) { /* Grandchild process will try to launch the url */
execlp("xdg-open", "xdg-open", url, NULL);
_exit(EXIT_FAILURE);
+17 -5
View File
@@ -119,9 +119,6 @@ static const SDL_RenderDriver *render_drivers[] = {
#if SDL_VIDEO_RENDER_VITA_GXM
&VITA_GXM_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_VITA_GLES2
&VITA_GLES2_RenderDriver,
#endif
#if SDL_VIDEO_RENDER_SW
&SW_RenderDriver
#endif
@@ -622,6 +619,17 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_SetRenderTarget(renderer, NULL);
}
/* Update the DPI scale if the window has been resized. */
if (window && renderer->GetOutputSize) {
int window_w, window_h;
int output_w, output_h;
if (renderer->GetOutputSize(renderer, &output_w, &output_h) == 0) {
SDL_GetWindowSize(renderer->window, &window_w, &window_h);
renderer->dpi_scale.x = (float)window_w / output_w;
renderer->dpi_scale.y = (float)window_h / output_h;
}
}
if (renderer->logical_w) {
UpdateLogicalSize(renderer);
} else {
@@ -2669,7 +2677,9 @@ RenderDrawLinesWithRects(SDL_Renderer * renderer,
}
}
retval += QueueCmdFillRects(renderer, frects, nrects);
if (nrects) {
retval += QueueCmdFillRects(renderer, frects, nrects);
}
SDL_small_free(frects, isstack);
@@ -2724,7 +2734,9 @@ RenderDrawLinesWithRectsF(SDL_Renderer * renderer,
}
}
retval += QueueCmdFillRects(renderer, frects, nrects);
if (nrects) {
retval += QueueCmdFillRects(renderer, frects, nrects);
}
SDL_small_free(frects, isstack);
-1
View File
@@ -250,7 +250,6 @@ extern SDL_RenderDriver DirectFB_RenderDriver;
extern SDL_RenderDriver METAL_RenderDriver;
extern SDL_RenderDriver PSP_RenderDriver;
extern SDL_RenderDriver SW_RenderDriver;
extern SDL_RenderDriver VITA_GLES2_RenderDriver;
extern SDL_RenderDriver VITA_GXM_RenderDriver;
/* Blend mode functions */
+5 -4
View File
@@ -1318,20 +1318,21 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
const SDL_Rect *viewport = &data->drawstate.viewport;
const int backw = istarget ? renderer->target->w : data->pparams.BackBufferWidth;
const int backh = istarget ? renderer->target->h : data->pparams.BackBufferHeight;
const SDL_bool viewport_equal = ((viewport->x == 0) && (viewport->y == 0) && (viewport->w == backw) && (viewport->h == backh)) ? SDL_TRUE : SDL_FALSE;
if (data->drawstate.cliprect_enabled) {
if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) {
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, FALSE);
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled;
}
/* Don't reset the viewport if we don't have to! */
if (!viewport->x && !viewport->y && (viewport->w == backw) && (viewport->h == backh)) {
if (!data->drawstate.viewport_dirty && viewport_equal) {
IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
} else {
/* Clear is defined to clear the entire render target */
const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f };
IDirect3DDevice9_SetViewport(data->device, &wholeviewport);
data->drawstate.viewport_dirty = SDL_TRUE;
data->drawstate.viewport_dirty = SDL_TRUE; /* we still need to (re)set orthographic projection, so always mark it dirty. */
IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
}
+3 -1
View File
@@ -183,11 +183,13 @@ typedef struct
static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
#if defined(__WINRT__) && NTDDI_VERSION > NTDDI_WIN8
static const GUID SDL_IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } };
#endif
static const GUID SDL_IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } };
static const GUID SDL_IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };
static const GUID SDL_IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } };
static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };
/*static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };*/
#ifdef __GNUC__
#pragma GCC diagnostic pop
+4 -4
View File
@@ -961,7 +961,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
}
if (texture) {
data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 8)));
data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + (sizeof (GLfloat) * 8)));
}
if (GLES2_SelectProgram(data, imgsrc, texture ? texture->w : 0, texture ? texture->h : 0) < 0) {
@@ -1004,7 +1004,7 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
}
/* all drawing commands use this */
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) cmd->data.draw.first);
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (uintptr_t) cmd->data.draw.first);
if (is_copy_ex != was_copy_ex) {
if (is_copy_ex) {
@@ -1018,8 +1018,8 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
}
if (is_copy_ex) {
data->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 16)));
data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 24)));
data->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + (sizeof (GLfloat) * 16)));
data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + (sizeof (GLfloat) * 24)));
}
return 0;
+70 -71
View File
@@ -38,6 +38,12 @@
#include <psp2/common_dialog.h>
/* #define DEBUG_RAZOR */
#if DEBUG_RAZOR
#include <psp2/sysmodule.h>
#endif
static SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags);
static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event);
@@ -109,14 +115,12 @@ SDL_RenderDriver VITA_GXM_RenderDriver = {
.info = {
.name = "VITA gxm",
.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
.num_texture_formats = 6,
.num_texture_formats = 4,
.texture_formats = {
[0] = SDL_PIXELFORMAT_ABGR8888,
[1] = SDL_PIXELFORMAT_ARGB8888,
[2] = SDL_PIXELFORMAT_RGB888,
[3] = SDL_PIXELFORMAT_BGR888,
[4] = SDL_PIXELFORMAT_RGB565,
[5] = SDL_PIXELFORMAT_BGR565
[2] = SDL_PIXELFORMAT_RGB565,
[3] = SDL_PIXELFORMAT_BGR565
},
.max_texture_width = 4096,
.max_texture_height = 4096,
@@ -157,6 +161,7 @@ StartDrawing(SDL_Renderer *renderer)
data->drawstate.fragment_program = NULL;
data->drawstate.last_command = -1;
data->drawstate.texture_color = 0xFFFFFFFF;
data->drawstate.viewport_dirty = SDL_TRUE;
// reset blend mode
// data->currentBlendMode = SDL_BLENDMODE_BLEND;
@@ -252,6 +257,11 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
data->displayData.wait_vblank = SDL_FALSE;
}
#if DEBUG_RAZOR
sceSysmoduleLoadModule( SCE_SYSMODULE_RAZOR_HUD );
sceSysmoduleLoadModule( SCE_SYSMODULE_RAZOR_CAPTURE );
#endif
if (gxm_init(renderer) != 0)
{
return NULL;
@@ -379,7 +389,7 @@ VITA_GXM_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL
static int
VITA_GXM_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
{
return 0; // nothing to do here
return 0;
}
static void
@@ -417,7 +427,7 @@ VITA_GXM_SetBlendMode(VITA_GXM_RenderData *data, int blendMode)
static int
VITA_GXM_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
{
return 0; // TODO
return 0;
}
static int
@@ -457,6 +467,7 @@ VITA_GXM_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const
vertex[i].z = +0.5f;
vertex[i].color = color;
}
return 0;
}
@@ -536,22 +547,12 @@ VITA_GXM_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const S
return 0;
}
#define PI 3.14159265358979f
#define degToRad(x) ((x)*PI/180.f)
#define degToRad(x) ((x)*M_PI/180.f)
void MathSincos(float r, float *s, float *c)
{
*s = sinf(r);
*c = cosf(r);
}
void Swap(float *a, float *b)
{
float n=*a;
*a = *b;
*b = n;
*s = SDL_sin(r);
*c = SDL_cos(r);
}
static int
@@ -609,19 +610,14 @@ VITA_GXM_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Textur
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
{
texture_vertex *vertices;
float u0, v0, u1, v1;
float s, c;
float cw, sw, ch, sh;
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
const float centerx = center->x;
const float centery = center->y;
const float x = dstrect->x + centerx;
const float y = dstrect->y + centery;
const float width = dstrect->w - centerx;
const float height = dstrect->h - centery;
texture_vertex *vertices;
float u0, v0, u1, v1;
float x0, y0, x1, y1;
float s, c;
const float centerx = center->x + dstrect->x;
const float centery = center->y + dstrect->y;
cmd->data.draw.count = 1;
@@ -633,52 +629,62 @@ VITA_GXM_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Textur
cmd->data.draw.first = (size_t)vertices;
cmd->data.draw.texture = texture;
if (flip & SDL_FLIP_HORIZONTAL) {
x0 = dstrect->x + dstrect->w;
x1 = dstrect->x;
} else {
x0 = dstrect->x;
x1 = dstrect->x + dstrect->w;
}
if (flip & SDL_FLIP_VERTICAL) {
y0 = dstrect->y + dstrect->h;
y1 = dstrect->y;
} else {
y0 = dstrect->y;
y1 = dstrect->y + dstrect->h;
}
u0 = (float)srcrect->x / (float)texture->w;
v0 = (float)srcrect->y / (float)texture->h;
u1 = (float)(srcrect->x + srcrect->w) / (float)texture->w;
v1 = (float)(srcrect->y + srcrect->h) / (float)texture->h;
if (flip & SDL_FLIP_VERTICAL) {
Swap(&v0, &v1);
}
if (flip & SDL_FLIP_HORIZONTAL) {
Swap(&u0, &u1);
}
MathSincos(degToRad(angle), &s, &c);
cw = c * width;
sw = s * width;
ch = c * height;
sh = s * height;
vertices[0].x = x - cw + sh;
vertices[0].y = y - sw - ch;
vertices[0].x = x0 - centerx;
vertices[0].y = y0 - centery;
vertices[0].z = +0.5f;
vertices[0].u = u0;
vertices[0].v = v0;
vertices[1].x = x + cw + sh;
vertices[1].y = y + sw - ch;
vertices[1].x = x1 - centerx;
vertices[1].y = y0 - centery;
vertices[1].z = +0.5f;
vertices[1].u = u1;
vertices[1].v = v0;
vertices[2].x = x - cw - sh;
vertices[2].y = y - sw + ch;
vertices[2].x = x0 - centerx;
vertices[2].y = y1 - centery;
vertices[2].z = +0.5f;
vertices[2].u = u0;
vertices[2].v = v1;
vertices[3].x = x + cw - sh;
vertices[3].y = y + sw + ch;
vertices[3].x = x1 - centerx;
vertices[3].y = y1 - centery;
vertices[3].z = +0.5f;
vertices[3].u = u1;
vertices[3].v = v1;
for (int i = 0; i < 4; ++i)
{
float _x = vertices[i].x;
float _y = vertices[i].y;
vertices[i].x = _x * c - _y * s + centerx;
vertices[i].y = _x * s + _y * c + centery;
}
return 0;
}
@@ -690,6 +696,7 @@ VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
float clear_color[4];
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
unset_clip_rectangle(data);
clear_color[0] = (cmd->data.color.r)/255.0f;
clear_color[1] = (cmd->data.color.g)/255.0f;
@@ -710,6 +717,7 @@ VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
sceGxmSetVertexStream(data->gxm_context, 0, data->clearVertices);
sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 3);
data->drawstate.cliprect_dirty = SDL_TRUE;
return 0;
}
@@ -779,7 +787,7 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd, SDL_bool s
float y_scale = -(sh);
float y_off = viewport->y + sh;
sceGxmSetViewport(data->gxm_context, x_off, x_scale, y_off, y_scale, -0.5f, 0.5f);
sceGxmSetViewport(data->gxm_context, x_off, x_scale, y_off, y_scale, 0.5f, 0.5f);
if (viewport->w && viewport->h) {
init_orthographic_matrix(data->ortho_matrix,
@@ -802,11 +810,8 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd, SDL_bool s
}
if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
const SDL_Rect *viewport = &data->drawstate.viewport;
const SDL_Rect *rect = &data->drawstate.cliprect;
set_clip_rectangle(data, viewport->x + rect->x,
data->drawstate.target ? viewport->y + rect->y : data->drawstate.drawableh - viewport->y - rect->y - rect->h,
rect->w, rect->h);
set_clip_rectangle(data, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
data->drawstate.cliprect_dirty = SDL_FALSE;
}
@@ -1110,6 +1115,12 @@ VITA_GXM_RenderPresent(SDL_Renderer *renderer)
sceCommonDialogUpdate(&updateParam);
#if DEBUG_RAZOR
sceGxmPadHeartbeat(
(const SceGxmColorSurface *)&data->displaySurface[data->backBufferIndex],
(SceGxmSyncObject *)data->displayBufferSync[data->backBufferIndex]
);
#endif
sceGxmDisplayQueueAddEntry(
data->displayBufferSync[data->frontBufferIndex], // OLD fb
@@ -1144,20 +1155,8 @@ VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
sceGxmFinish(data->gxm_context);
if (vita_texture->tex->gxm_rendertarget) {
sceGxmDestroyRenderTarget(vita_texture->tex->gxm_rendertarget);
}
free_gxm_texture(vita_texture->tex);
if (vita_texture->tex->depth_UID) {
mem_gpu_free(vita_texture->tex->depth_UID);
}
if (vita_texture->tex->palette_UID) {
mem_gpu_free(vita_texture->tex->palette_UID);
}
mem_gpu_free(vita_texture->tex->data_UID);
SDL_free(vita_texture->tex);
SDL_free(vita_texture);
texture->driverdata = NULL;
@@ -124,30 +124,30 @@ static const unsigned char gxm_shader_color_f[gxm_shader_color_f_size] = {
0x7e, 0x0d, 0x80, 0x40,
};
#define gxm_shader_color_v_size 344
#define gxm_shader_color_v_size 352
static const unsigned char gxm_shader_color_v[gxm_shader_color_v_size] = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
0x55, 0x01, 0x00, 0x00, 0x2e, 0x35, 0x0f, 0x26,
0x23, 0x46, 0x37, 0xbb, 0x00, 0x00, 0x19, 0x00,
0x5d, 0x01, 0x00, 0x00, 0x4a, 0xb6, 0x4f, 0x7b,
0x51, 0x19, 0x1a, 0xae, 0x00, 0x00, 0x19, 0x00,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0xe8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
0xa8, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa,
@@ -158,6 +158,7 @@ static const unsigned char gxm_shader_color_v[gxm_shader_color_v_size] = {
0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18,
0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18,
0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18,
0x40, 0x00, 0x10, 0x41, 0x09, 0x05, 0x82, 0x38,
0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb,
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
@@ -1001,9 +1001,6 @@ free_gxm_texture(gxm_texture *texture)
if (texture->depth_UID) {
mem_gpu_free(texture->depth_UID);
}
if (texture->palette_UID) {
mem_gpu_free(texture->palette_UID);
}
mem_gpu_free(texture->data_UID);
SDL_free(texture);
}
@@ -1070,29 +1067,6 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
/* Create the gxm texture */
sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0);
if ((format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_P8) {
const int pal_size = 256 * sizeof(uint32_t);
void *texture_palette = mem_gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
pal_size,
SCE_GXM_PALETTE_ALIGNMENT,
SCE_GXM_MEMORY_ATTRIB_READ,
&texture->palette_UID);
if (!texture_palette) {
texture->palette_UID = 0;
free_gxm_texture(texture);
return NULL;
}
SDL_memset(texture_palette, 0, pal_size);
sceGxmTextureSetPalette(&texture->gxm_tex, texture_palette);
} else {
texture->palette_UID = 0;
}
if (isRenderTarget) {
void *depthBufferData;
const uint32_t alignedWidth = ALIGN(w, SCE_GXM_TILE_SIZEX);
@@ -76,7 +76,6 @@ typedef struct texture_vertex {
typedef struct gxm_texture {
SceGxmTexture gxm_tex;
SceUID data_UID;
SceUID palette_UID;
SceGxmRenderTarget *gxm_rendertarget;
SceGxmColorSurface gxm_colorsurface;
SceGxmDepthStencilSurface gxm_depthstencil;
+4 -2
View File
@@ -2,10 +2,12 @@ void main(
float3 aPosition,
float4 aColor,
uniform float4x4 wvp,
float4 out vPosition : POSITION,
float4 out vColor : COLOR
out float4 vPosition : POSITION,
out float4 vColor : COLOR,
out float pSize : PSIZE
)
{
vPosition = mul(float4(aPosition, 1.f), wvp);
vColor = aColor;
pSize = 1.f;
}
+2 -2
View File
@@ -2,8 +2,8 @@ void main(
float3 aPosition,
float2 aTexcoord,
uniform float4x4 wvp,
float4 out vPosition : POSITION,
float2 out vTexcoord : TEXCOORD0
out float4 vPosition : POSITION,
out float2 vTexcoord : TEXCOORD0
)
{
vPosition = mul(float4(aPosition, 1.f), wvp);
+4 -4
View File
@@ -55,13 +55,13 @@ SDL_COMPILE_TIME_ASSERT(iconv_t, sizeof (iconv_t) <= sizeof (SDL_iconv_t));
SDL_iconv_t
SDL_iconv_open(const char *tocode, const char *fromcode)
{
return (SDL_iconv_t) ((size_t) iconv_open(tocode, fromcode));
return (SDL_iconv_t) ((uintptr_t) iconv_open(tocode, fromcode));
}
int
SDL_iconv_close(SDL_iconv_t cd)
{
return iconv_close((iconv_t) ((size_t) cd));
return iconv_close((iconv_t) ((uintptr_t) cd));
}
size_t
@@ -71,9 +71,9 @@ SDL_iconv(SDL_iconv_t cd,
{
size_t retCode;
#ifdef ICONV_INBUF_NONCONST
retCode = iconv((iconv_t) ((size_t) cd), (char **) inbuf, inbytesleft, outbuf, outbytesleft);
retCode = iconv((iconv_t) ((uintptr_t) cd), (char **) inbuf, inbytesleft, outbuf, outbytesleft);
#else
retCode = iconv((iconv_t) ((size_t) cd), inbuf, inbytesleft, outbuf, outbytesleft);
retCode = iconv((iconv_t) ((uintptr_t) cd), inbuf, inbytesleft, outbuf, outbytesleft);
#endif
if (retCode == (size_t) - 1) {
switch (errno) {
+2 -2
View File
@@ -281,7 +281,7 @@ SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len)
* execute a 32-bit set. Set first bytes manually if needed until it is
* aligned. */
value1 = (Uint8)c;
while ((intptr_t)dstp1 & 0x3) {
while ((uintptr_t)dstp1 & 0x3) {
if (len--) {
*dstp1++ = value1;
} else {
@@ -329,7 +329,7 @@ SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src,
using Uint32* pointers, so we need to make sure the pointers are
aligned before we loop using them.
*/
if (((intptr_t)src & 0x3) || ((intptr_t)dst & 0x3)) {
if (((uintptr_t)src & 0x3) || ((uintptr_t)dst & 0x3)) {
/* Do an unaligned byte copy */
Uint8 *srcp1 = (Uint8 *)src;
Uint8 *dstp1 = (Uint8 *)dst;
+24 -1
View File
@@ -37,7 +37,7 @@ static const char *video_usage[] = {
"[--scale N]", "[--depth N]", "[--refresh R]", "[--vsync]", "[--noframe]",
"[--resizable]", "[--minimize]", "[--maximize]", "[--grab]", "[--keyboard-grab]",
"[--shown]", "[--hidden]", "[--input-focus]", "[--mouse-focus]",
"[--allow-highdpi]", "[--usable-bounds]"
"[--flash-on-focus-loss]", "[--allow-highdpi]", "[--usable-bounds]"
};
static const char *audio_usage[] = {
@@ -441,6 +441,10 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index)
state->window_flags |= SDL_WINDOW_MOUSE_FOCUS;
return 1;
}
if (SDL_strcasecmp(argv[index], "--flash-on-focus-loss") == 0) {
state->flash_on_focus_loss = SDL_TRUE;
return 1;
}
if (SDL_strcasecmp(argv[index], "--grab") == 0) {
state->window_flags |= SDL_WINDOW_MOUSE_GRABBED;
return 1;
@@ -1808,6 +1812,16 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
}
}
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
if (state->flash_on_focus_loss) {
SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
if (window) {
SDL_FlashWindow(window, SDL_FLASH_UNTIL_FOCUSED);
}
}
break;
default:
break;
}
break;
case SDL_KEYDOWN: {
@@ -1958,6 +1972,15 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
SDL_free(text);
}
break;
case SDLK_f:
if (withControl) {
/* Ctrl-F flash the window */
SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
if (window) {
SDL_FlashWindow(window, SDL_FLASH_BRIEFLY);
}
}
break;
case SDLK_g:
if (withControl) {
/* Ctrl-G toggle mouse grab */
+1 -1
View File
@@ -34,7 +34,7 @@ SDL_memcpySSE(Uint8 * dst, const Uint8 * src, int len)
__m128 values[4];
for (i = len / 64; i--;) {
_mm_prefetch(src, _MM_HINT_NTA);
_mm_prefetch((const char *)src, _MM_HINT_NTA);
values[0] = *(__m128 *) (src + 0);
values[1] = *(__m128 *) (src + 16);
values[2] = *(__m128 *) (src + 32);
+2 -2
View File
@@ -411,9 +411,9 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
biClrUsed = 1 << biBitCount;
}
if (biClrUsed > palette->ncolors) {
if (biClrUsed > (Uint32)palette->ncolors) {
biClrUsed = 1 << biBitCount; /* try forcing it? */
if (biClrUsed > palette->ncolors) {
if (biClrUsed > (Uint32)palette->ncolors) {
SDL_SetError("Unsupported or incorrect biClrUsed field");
was_error = SDL_TRUE;
goto done;
+2 -2
View File
@@ -507,12 +507,12 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
}
if (_this->egl_data->eglGetPlatformDisplay) {
_this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(size_t)native_display, NULL);
_this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(uintptr_t)native_display, NULL);
} else {
if (SDL_EGL_HasExtension(_this, SDL_EGL_CLIENT_EXTENSION, "EGL_EXT_platform_base")) {
_this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(_this, "eglGetPlatformDisplayEXT");
if (_this->egl_data->eglGetPlatformDisplayEXT) {
_this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(size_t)native_display, NULL);
_this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(uintptr_t)native_display, NULL);
}
}
}
+1 -1
View File
@@ -240,7 +240,7 @@ struct SDL_VideoDevice
int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window);
void (*OnWindowEnter) (_THIS, SDL_Window * window);
int (*FlashWindow) (_THIS, SDL_Window * window, Uint32 flash_count);
int (*FlashWindow) (_THIS, SDL_Window * window, SDL_FlashOperation operation);
/* * * */
/*
+64 -15
View File
@@ -492,17 +492,27 @@ SDL_VideoInit(const char *driver_name)
}
/* Select the proper video driver */
index = 0;
i = index = 0;
video = NULL;
if (driver_name == NULL) {
driver_name = SDL_getenv("SDL_VIDEODRIVER");
}
if (driver_name != NULL) {
for (i = 0; bootstrap[i]; ++i) {
if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) {
video = bootstrap[i]->create(index);
break;
const char *driver_attempt = driver_name;
while(driver_attempt != NULL && *driver_attempt != 0 && video == NULL) {
const char* driver_attempt_end = SDL_strchr(driver_attempt, ',');
size_t driver_attempt_len = (driver_attempt_end != NULL) ? (driver_attempt_end - driver_attempt)
: SDL_strlen(driver_attempt);
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)) {
video = bootstrap[i]->create(index);
break;
}
}
driver_attempt = (driver_attempt_end != NULL) ? (driver_attempt_end + 1) : NULL;
}
} else {
for (i = 0; bootstrap[i]; ++i) {
@@ -1153,7 +1163,16 @@ SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode)
if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
SDL_DisplayMode fullscreen_mode;
if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) {
SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode);
if (SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode) == 0) {
#ifndef ANDROID
/* Android may not resize the window to exactly what our fullscreen mode is, especially on
* windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't
* use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such,
* Android's SetWindowFullscreen will generate the window event for us with the proper final size.
*/
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, fullscreen_mode.w, fullscreen_mode.h);
#endif
}
}
}
return 0;
@@ -1349,11 +1368,11 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
/* Generate a mode change event here */
if (resized) {
#ifndef ANDROID
// Android may not resize the window to exactly what our fullscreen mode is, especially on
// windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't
// use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such,
// Android's SetWindowFullscreen will generate the window event for us with the proper final size.
/* Android may not resize the window to exactly what our fullscreen mode is, especially on
* windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't
* use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such,
* Android's SetWindowFullscreen will generate the window event for us with the proper final size.
*/
SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED,
fullscreen_mode.w, fullscreen_mode.h);
#endif
@@ -1589,6 +1608,22 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
displayIndex = SDL_GetIndexOfDisplay(display);
SDL_GetDisplayBounds(displayIndex, &bounds);
/* for real fullscreen we might switch the resolution, so get width and height
* from closest supported mode and use that instead of current resolution
*/
if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP
&& (bounds.w != w || bounds.h != h)) {
SDL_DisplayMode fullscreen_mode, closest_mode;
SDL_zero(fullscreen_mode);
fullscreen_mode.w = w;
fullscreen_mode.h = h;
if (SDL_GetClosestDisplayModeForDisplay(display, &fullscreen_mode, &closest_mode) != NULL) {
bounds.w = closest_mode.w;
bounds.h = closest_mode.h;
}
}
window->fullscreen_mode.w = bounds.w;
window->fullscreen_mode.h = bounds.h;
window->x = bounds.x;
window->y = bounds.y;
window->w = bounds.w;
@@ -2793,12 +2828,12 @@ SDL_GetGrabbedWindow(void)
}
int
SDL_FlashWindow(SDL_Window * window, Uint32 flash_count)
SDL_FlashWindow(SDL_Window * window, SDL_FlashOperation operation)
{
CHECK_WINDOW_MAGIC(window, -1);
if (_this->FlashWindow) {
return _this->FlashWindow(_this, window, flash_count);
return _this->FlashWindow(_this, window, operation);
}
return SDL_Unsupported();
@@ -2820,7 +2855,10 @@ void
SDL_OnWindowResized(SDL_Window * window)
{
window->surface_valid = SDL_FALSE;
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
if (!window->is_destroying) {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
}
}
void
@@ -2878,6 +2916,8 @@ SDL_OnWindowFocusGained(SDL_Window * window)
static SDL_bool
ShouldMinimizeOnFocusLoss(SDL_Window * window)
{
const char *hint;
if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) {
return SDL_FALSE;
}
@@ -2893,12 +2933,21 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window)
#ifdef __ANDROID__
{
extern SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss(void);
if (! Android_JNI_ShouldMinimizeOnFocusLoss()) {
if (!Android_JNI_ShouldMinimizeOnFocusLoss()) {
return SDL_FALSE;
}
}
#endif
/* Real fullscreen windows should minimize on focus loss so the desktop video mode is restored */
hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS);
if (!hint || !*hint || SDL_strcasecmp(hint, "auto") == 0) {
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
return SDL_FALSE;
} else {
return SDL_TRUE;
}
}
return SDL_GetHintBoolean(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_FALSE);
}
+2
View File
@@ -31,6 +31,8 @@ extern void Cocoa_StartTextInput(_THIS);
extern void Cocoa_StopTextInput(_THIS);
extern void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect);
extern void Cocoa_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
#endif /* SDL_cocoakeyboard_h_ */
/* vi: set ts=4 sw=4 expandtab: */
+17
View File
@@ -602,6 +602,23 @@ Cocoa_QuitKeyboard(_THIS)
{
}
typedef int CGSConnection;
typedef enum {
CGSGlobalHotKeyEnable = 0,
CGSGlobalHotKeyDisable = 1,
} CGSGlobalHotKeyOperatingMode;
extern CGSConnection _CGSDefaultConnection(void);
extern CGError CGSSetGlobalHotKeyOperatingMode(CGSConnection connection, CGSGlobalHotKeyOperatingMode mode);
void
Cocoa_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
#if SDL_MAC_NO_SANDBOX
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), grabbed ? CGSGlobalHotKeyDisable : CGSGlobalHotKeyEnable);
#endif
}
#endif /* SDL_VIDEO_DRIVER_COCOA */
/* vi: set ts=4 sw=4 expandtab: */
+18 -9
View File
@@ -89,10 +89,8 @@
@end
/* Display a Cocoa message box */
int
Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{ @autoreleasepool
static void
Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue)
{
Cocoa_RegisterApp();
@@ -133,11 +131,8 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease];
[presenter performSelectorOnMainThread:@selector(showAlert:)
withObject:alert
waitUntilDone:YES];
[presenter showAlert:alert];
int returnValue = 0;
NSInteger clicked = presenter->clicked;
if (clicked >= NSAlertFirstButtonReturn) {
clicked -= NSAlertFirstButtonReturn;
@@ -145,10 +140,24 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
clicked = messageboxdata->numbuttons - 1 - clicked;
}
*buttonid = buttons[clicked].buttonid;
*returnValue = 0;
} else {
returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked);
*returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked);
}
}
/* Display a Cocoa message box */
int
Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{ @autoreleasepool
{
__block int returnValue = 0;
if ([NSThread isMainThread]) {
Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue);
} else {
dispatch_sync(dispatch_get_main_queue(), ^{ Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); });
}
return returnValue;
}}
+46 -3
View File
@@ -215,8 +215,8 @@ Cocoa_WarpMouseGlobal(int x, int y)
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse->focus) {
SDL_WindowData *data = (SDL_WindowData *) mouse->focus->driverdata;
if ([data->listener isMoving]) {
DLog("Postponing warp, window being moved.");
if ([data->listener isMovingOrFocusClickPending]) {
DLog("Postponing warp, window being moved or focused.");
[data->listener setPendingMoveX:x Y:y];
return 0;
}
@@ -271,7 +271,7 @@ Cocoa_SetRelativeMouseMode(SDL_bool enabled)
* if it is being moved right now.
*/
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if ([data->listener isMoving]) {
if ([data->listener isMovingOrFocusClickPending]) {
return 0;
}
@@ -353,6 +353,34 @@ Cocoa_InitMouse(_THIS)
return 0;
}
static void
Cocoa_HandleTitleButtonEvent(_THIS, NSEvent *event)
{
SDL_Window *window;
NSWindow *nswindow = [event window];
for (window = _this->windows; window; window = window->next) {
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
if (data && data->nswindow == nswindow) {
switch ([event type]) {
case NSEventTypeLeftMouseDown:
case NSEventTypeRightMouseDown:
case NSEventTypeOtherMouseDown:
[data->listener setFocusClickPending:[event buttonNumber]];
break;
case NSEventTypeLeftMouseUp:
case NSEventTypeRightMouseUp:
case NSEventTypeOtherMouseUp:
[data->listener clearFocusClickPending:[event buttonNumber]];
break;
default:
break;
}
break;
}
}
}
void
Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
{
@@ -363,6 +391,21 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
case NSEventTypeOtherMouseDragged:
break;
case NSEventTypeLeftMouseDown:
case NSEventTypeLeftMouseUp:
case NSEventTypeRightMouseDown:
case NSEventTypeRightMouseUp:
case NSEventTypeOtherMouseDown:
case NSEventTypeOtherMouseUp:
if ([event window]) {
NSRect windowRect = [[[event window] contentView] frame];
if (!NSMouseInRect([event locationInWindow], windowRect, NO)) {
Cocoa_HandleTitleButtonEvent(_this, event);
return;
}
}
return;
default:
/* Ignore any other events. */
return;
+2
View File
@@ -103,10 +103,12 @@ Cocoa_CreateDevice(int devindex)
device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
device->SetWindowMouseGrab = Cocoa_SetWindowMouseGrab;
device->SetWindowKeyboardGrab = Cocoa_SetWindowKeyboardGrab;
device->DestroyWindow = Cocoa_DestroyWindow;
device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
device->SetWindowHitTest = Cocoa_SetWindowHitTest;
device->AcceptDragAndDrop = Cocoa_AcceptDragAndDrop;
device->FlashWindow = Cocoa_FlashWindow;
device->shape_driver.CreateShaper = Cocoa_CreateShaper;
device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
+7
View File
@@ -48,6 +48,7 @@ typedef enum
BOOL inFullscreenTransition;
PendingWindowOperation pendingWindowOperation;
BOOL isMoving;
int focusClickPending;
int pendingWindowWarpX, pendingWindowWarpY;
BOOL isDragAreaRunning;
}
@@ -62,8 +63,12 @@ typedef enum
-(void) close;
-(BOOL) isMoving;
-(BOOL) isMovingOrFocusClickPending;
-(void) setFocusClickPending:(int) button;
-(void) clearFocusClickPending:(int) button;
-(void) setPendingMoveX:(int)x Y:(int)y;
-(void) windowDidFinishMoving;
-(void) onMovingOrFocusClickPendingStateCleared;
/* Window delegate functionality */
-(BOOL) windowShouldClose:(id) sender;
@@ -117,6 +122,7 @@ struct SDL_WindowData
NSMutableArray *nscontexts;
SDL_bool created;
SDL_bool inWindowFullscreenTransition;
NSInteger flash_request;
Cocoa_WindowListener *listener;
struct SDL_VideoData *videodata;
#if SDL_VIDEO_OPENGL_EGL
@@ -151,6 +157,7 @@ extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info);
extern int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
extern void Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
extern int Cocoa_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
#endif /* SDL_cocoawindow_h_ */
+72 -3
View File
@@ -508,6 +508,26 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
return isMoving;
}
- (BOOL)isMovingOrFocusClickPending
{
return isMoving || (focusClickPending != 0);
}
-(void) setFocusClickPending:(int) button
{
focusClickPending |= (1 << button);
}
-(void) clearFocusClickPending:(int) button
{
if ((focusClickPending & (1 << button)) != 0) {
focusClickPending &= ~(1 << button);
if (focusClickPending == 0) {
[self onMovingOrFocusClickPendingStateCleared];
}
}
}
-(void) setPendingMoveX:(int)x Y:(int)y
{
pendingWindowWarpX = x;
@@ -516,15 +536,36 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
- (void)windowDidFinishMoving
{
if ([self isMoving]) {
if (isMoving) {
isMoving = NO;
[self onMovingOrFocusClickPendingStateCleared];
}
}
- (void)onMovingOrFocusClickPendingStateCleared
{
if (![self isMovingOrFocusClickPending]) {
SDL_Mouse *mouse = SDL_GetMouse();
if (pendingWindowWarpX != INT_MAX && pendingWindowWarpY != INT_MAX) {
mouse->WarpMouseGlobal(pendingWindowWarpX, pendingWindowWarpY);
pendingWindowWarpX = pendingWindowWarpY = INT_MAX;
}
if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) {
/* Move the cursor to the nearest point in the window */
{
int x, y;
CGPoint cgpoint;
SDL_GetMouseState(&x, &y);
cgpoint.x = _data->window->x + x;
cgpoint.y = _data->window->y + y;
Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y);
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
}
mouse->SetRelativeMouseMode(SDL_TRUE);
}
}
@@ -641,7 +682,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
/* This needs to be done before restoring the relative mouse mode. */
SDL_SetKeyboardFocus(window);
if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMoving]) {
if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMovingOrFocusClickPending]) {
mouse->SetRelativeMouseMode(SDL_TRUE);
}
@@ -1970,7 +2011,7 @@ Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
/* Move the cursor to the nearest point in the window */
if (grabbed && data && ![data->listener isMoving]) {
if (grabbed && data && ![data->listener isMovingOrFocusClickPending]) {
int x, y;
CGPoint cgpoint;
@@ -2116,6 +2157,34 @@ Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
}
}
int
Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
{ @autoreleasepool
{
/* Note that this is app-wide and not window-specific! */
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if (data->flash_request) {
[NSApp cancelUserAttentionRequest:data->flash_request];
data->flash_request = 0;
}
switch (operation) {
case SDL_FLASH_CANCEL:
/* Canceled above */
break;
case SDL_FLASH_BRIEFLY:
data->flash_request = [NSApp requestUserAttention:NSInformationalRequest];
break;
case SDL_FLASH_UNTIL_FOCUSED:
data->flash_request = [NSApp requestUserAttention:NSCriticalRequest];
break;
default:
return SDL_Unsupported();
}
return 0;
}}
int
Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
{
+1 -1
View File
@@ -116,6 +116,7 @@ DUMMY_VideoInit(_THIS)
SDL_DisplayMode mode;
/* Use a fake 32-bpp desktop mode */
SDL_zero(mode);
mode.format = SDL_PIXELFORMAT_RGB888;
mode.w = 1024;
mode.h = 768;
@@ -125,7 +126,6 @@ DUMMY_VideoInit(_THIS)
return -1;
}
SDL_zero(mode);
SDL_AddDisplayMode(&_this->displays[0], &mode);
/* We're done! */
+91 -78
View File
@@ -290,6 +290,7 @@ KMSDRM_CreateDevice(int devindex)
device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval;
device->GL_SwapWindow = KMSDRM_GLES_SwapWindow;
device->GL_DeleteContext = KMSDRM_GLES_DeleteContext;
device->GL_DefaultProfileConfig = KMSDRM_GLES_DefaultProfileConfig;
#if SDL_VIDEO_VULKAN
device->Vulkan_LoadLibrary = KMSDRM_Vulkan_LoadLibrary;
@@ -537,8 +538,10 @@ void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resource
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
SDL_DisplayData *dispdata = NULL;
SDL_VideoDisplay display = {0};
SDL_DisplayModeData *modedata = NULL;
drmModeEncoder *encoder = NULL;
drmModeCrtc *crtc = NULL;
int mode_index;
int i, j;
int ret = 0;
@@ -626,6 +629,23 @@ void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resource
goto cleanup;
}
/* Find the index of the mode attached to this CRTC */
mode_index = -1;
for (i = 0; i < connector->count_modes; i++) {
drmModeModeInfo *mode = &connector->modes[i];
if (!SDL_memcmp(mode, &crtc->mode, sizeof(crtc->mode))) {
mode_index = i;
break;
}
}
if (mode_index == -1) {
ret = SDL_SetError("Failed to find index of mode attached to the CRTC.");
goto cleanup;
}
/*********************************************/
/* Create an SDL Display for this connector. */
/*********************************************/
@@ -638,9 +658,8 @@ void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resource
which is the mode currently setup on the CRTC
we found for the active connector. */
dispdata->mode = crtc->mode;
/* Save the original mode for restoration on quit. */
dispdata->original_mode = dispdata->mode;
dispdata->original_mode = crtc->mode;
dispdata->fullscreen_mode = crtc->mode;
if (dispdata->mode.hdisplay == 0 || dispdata->mode.vdisplay == 0 ) {
ret = SDL_SetError("Couldn't get a valid connector videomode.");
@@ -657,11 +676,21 @@ void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resource
/* Setup the display.
There's no problem with it being still incomplete. */
modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData));
if (!modedata) {
ret = SDL_OutOfMemory();
goto cleanup;
}
modedata->mode_index = mode_index;
display.driverdata = dispdata;
display.desktop_mode.w = dispdata->mode.hdisplay;
display.desktop_mode.h = dispdata->mode.vdisplay;
display.desktop_mode.refresh_rate = dispdata->mode.vrefresh;
display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888;
display.desktop_mode.driverdata = modedata;
display.current_mode = display.desktop_mode;
/* Add the display to the list of SDL displays. */
@@ -899,6 +928,43 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window *window)
}
}
static void
KMSDRM_GetModeToSet(SDL_Window *window, drmModeModeInfo *out_mode) {
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata;
if ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN) {
*out_mode = dispdata->fullscreen_mode;
} else {
drmModeModeInfo *mode;
mode = KMSDRM_GetClosestDisplayMode(display,
window->windowed.w, window->windowed.h, 0);
if (mode) {
*out_mode = *mode;
} else {
*out_mode = dispdata->original_mode;
}
}
}
static void
KMSDRM_DirtySurfaces(SDL_Window *window) {
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
drmModeModeInfo mode;
/* Can't recreate EGL surfaces right now, need to wait until SwapWindow
so the correct thread-local surface and context state are available */
windata->egl_surface_dirty = SDL_TRUE;
/* The app may be waiting for the resize event after calling SetWindowSize
or SetWindowFullscreen, send a fake event for now since the actual
recreation is deferred */
KMSDRM_GetModeToSet(window, &mode);
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode.hdisplay, mode.vdisplay);
}
/* This determines the size of the fb, which comes from the GBM surface
that we create here. */
int
@@ -906,7 +972,8 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
{
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata;
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata;
uint32_t surface_fmt = GBM_FORMAT_ARGB8888;
uint32_t surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
@@ -915,9 +982,7 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
int ret = 0;
/* If the current window already has surfaces, destroy them before creating other.
This is mainly for ReconfigureWindow(), where we simply call CreateSurfaces()
for regenerating a window's surfaces. */
/* If the current window already has surfaces, destroy them before creating other. */
if (windata->gs) {
KMSDRM_DestroySurfaces(_this, window);
}
@@ -928,6 +993,16 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
"GBM surface format not supported. Trying anyway.");
}
/* The KMSDRM backend doesn't always set the mode the higher-level code in
SDL_video.c expects. Hulk-smash the display's current_mode to keep the
mode that's set in sync with what SDL_video.c thinks is set */
KMSDRM_GetModeToSet(window, &dispdata->mode);
display->current_mode.w = dispdata->mode.hdisplay;
display->current_mode.h = dispdata->mode.vdisplay;
display->current_mode.refresh_rate = dispdata->mode.vrefresh;
display->current_mode.format = SDL_PIXELFORMAT_ARGB8888;
windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev,
dispdata->mode.hdisplay, dispdata->mode.vdisplay,
surface_fmt, surface_flags);
@@ -952,6 +1027,9 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
egl_context = (EGLContext)SDL_GL_GetCurrentContext();
ret = SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED,
dispdata->mode.hdisplay, dispdata->mode.vdisplay);
windata->egl_surface_dirty = SDL_FALSE;
cleanup:
@@ -1071,18 +1149,10 @@ KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
/* Take note of the new mode to be set, and leave the CRTC modeset pending
so it's done in SwapWindow. */
dispdata->mode = conn->modes[modedata->mode_index];
dispdata->fullscreen_mode = conn->modes[modedata->mode_index];
for (i = 0; i < viddata->num_windows; i++) {
SDL_Window *window = viddata->windows[i];
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
/* Can't recreate EGL surfaces right now, need to wait until SwapWindow
so the correct thread-local surface and context state are available */
windata->egl_surface_dirty = SDL_TRUE;
/* Tell app about the window resize */
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode->w, mode->h);
KMSDRM_DirtySurfaces(viddata->windows[i]);
}
return 0;
@@ -1244,14 +1314,13 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
are considered "windowed" at this point of their life.
If a window is fullscreen, SDL internals will call
KMSDRM_SetWindowFullscreen() to reconfigure it if necessary. */
mode = KMSDRM_GetClosestDisplayMode(display,
window->windowed.w, window->windowed.h, 0 );
if (mode) {
dispdata->mode = *mode;
dispdata->fullscreen_mode = *mode;
} else {
dispdata->mode = dispdata->original_mode;
dispdata->fullscreen_mode = dispdata->original_mode;
}
/* Create the window surfaces with the size we have just chosen.
@@ -1259,12 +1328,6 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
if ((ret = KMSDRM_CreateSurfaces(_this, window))) {
return (SDL_SetError("Can't window GBM/EGL surfaces on window creation."));
}
/* Tell app about the size we have determined for the window,
so SDL pre-scales to that size for us. */
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED,
dispdata->mode.hdisplay, dispdata->mode.vdisplay);
} /* NON-Vulkan block ends. */
/* Add window to the internal list of tracked windows. Note, while it may
@@ -1300,56 +1363,6 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
return ret;
}
/*****************************************************************************/
/* Re-create a window surfaces without destroying the window itself, */
/* and set a videomode on the CRTC that matches the surfaces size. */
/* To be used by SetWindowSize() and SetWindowFullscreen(). */
/*****************************************************************************/
void
KMSDRM_ReconfigureWindow( _THIS, SDL_Window * window)
{
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayData *dispdata = display->driverdata;
if ((window->flags & SDL_WINDOW_FULLSCREEN) ==
SDL_WINDOW_FULLSCREEN)
{
/* Nothing to do, honor the most recent mode requested by the user */
}
else if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) ==
SDL_WINDOW_FULLSCREEN_DESKTOP)
{
/* Update the current mode to the desktop mode. */
dispdata->mode = dispdata->original_mode;
} else {
drmModeModeInfo *mode;
/* Try to find a valid video mode matching the size of the window. */
mode = KMSDRM_GetClosestDisplayMode(display,
window->windowed.w, window->windowed.h, 0);
if (mode) {
/* If matching mode found, recreate the GBM surface with the size
of that mode and configure it on the CRTC. */
dispdata->mode = *mode;
} else {
/* If not matching mode found, recreate the GBM surfaces with the
size of the mode that was originally configured on the CRTC,
and setup that mode on the CRTC. */
dispdata->mode = dispdata->original_mode;
}
}
/* Recreate the GBM (and EGL) surfaces, and mark the CRTC mode/fb setting
as pending so it's done on SwapWindow. */
KMSDRM_CreateSurfaces(_this, window);
/* Tell app about the size we have determined for the window,
so SDL pre-scales to that size for us. */
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED,
dispdata->mode.hdisplay, dispdata->mode.vdisplay);
}
int
KMSDRM_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
{
@@ -1409,7 +1422,7 @@ KMSDRM_SetWindowSize(_THIS, SDL_Window * window)
{
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
if (!viddata->vulkan_mode) {
KMSDRM_ReconfigureWindow(_this, window);
KMSDRM_DirtySurfaces(window);
}
}
void
@@ -1418,7 +1431,7 @@ KMSDRM_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * displa
{
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
if (!viddata->vulkan_mode) {
KMSDRM_ReconfigureWindow(_this, window);
KMSDRM_DirtySurfaces(window);
}
}
void
+1 -1
View File
@@ -68,7 +68,7 @@ typedef struct SDL_DisplayData
drmModeCrtc *crtc;
drmModeModeInfo mode;
drmModeModeInfo original_mode;
drmModeModeInfo next_mode; /* New mode to be set on the CRTC. */
drmModeModeInfo fullscreen_mode;
drmModeCrtc *saved_crtc; /* CRTC to restore on quit */
+5
View File
@@ -394,6 +394,8 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
/* SDL (and DRM, if we look at drmModeModeInfo vrefresh) uses plain integer Hz for
display mode refresh rate, but Vulkan expects higher precision. */
new_mode_parameters.refreshRate = window->fullscreen_mode.refresh_rate * 1000;
SDL_zero(display_mode_create_info);
display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
display_mode_create_info.parameters = new_mode_parameters;
result = vkCreateDisplayModeKHR(gpu,
@@ -419,11 +421,14 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
image_size.width = window->w;
image_size.height = window->h;
SDL_zero(display_plane_surface_create_info);
display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
display_plane_surface_create_info.displayMode = display_mode;
/* For now, simply use the first plane. */
display_plane_surface_create_info.planeIndex = 0;
display_plane_surface_create_info.imageExtent = image_size;
display_plane_surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
display_plane_surface_create_info.alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
result = vkCreateDisplayPlaneSurfaceKHR(instance,
&display_plane_surface_create_info,
NULL,
+7 -1
View File
@@ -1562,8 +1562,14 @@ static int OS2_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi,
static void OS2_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
{
SDL_DisplayMode mode;
debug_os2("Enter");
SDL_AddDisplayMode(display, &display->current_mode);
SDL_memcpy(&mode, &display->current_mode, sizeof(SDL_DisplayMode));
mode.driverdata = (MODEDATA *) SDL_malloc(sizeof(MODEDATA));
if (!mode.driverdata) return; /* yikes.. */
SDL_memcpy(mode.driverdata, display->current_mode.driverdata, sizeof(MODEDATA));
SDL_AddDisplayMode(display, &mode);
}
static int OS2_SetDisplayMode(_THIS, SDL_VideoDisplay *display,
+1
View File
@@ -31,6 +31,7 @@ extern void SDL_QuitGCKeyboard(void);
extern void SDL_InitGCMouse(void);
extern SDL_bool SDL_HasGCMouse(void);
extern SDL_bool SDL_GCMouseRelativeMode(void);
extern void SDL_QuitGCMouse(void);
#endif /* SDL_uikitevents_h_ */
+36 -10
View File
@@ -91,9 +91,9 @@ static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0
SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode);
};
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL );
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
keyboard.handlerQueue = queue;
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL );
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
keyboard.handlerQueue = queue;
}
static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
@@ -182,10 +182,22 @@ void SDL_QuitGCKeyboard(void)
static int mice_connected = 0;
static id mouse_connect_observer = nil;
static id mouse_disconnect_observer = nil;
static bool mouse_relative_mode = SDL_FALSE;
static void UpdateMouseGrab()
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_Window *window;
for (window = _this->windows; window != NULL; window = window->next) {
SDL_UpdateWindowGrab(window);
}
}
static int SetGCMouseRelativeMode(SDL_bool enabled)
{
/* We'll always send relative motion and we can't warp, so nothing to do here */
mouse_relative_mode = enabled;
UpdateMouseGrab();
return 0;
}
@@ -222,14 +234,16 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouse, float deltaX, float deltaY)
{
SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, SDL_TRUE, (int)deltaX, -(int)deltaY);
SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, SDL_TRUE, (int)deltaX, -(int)deltaY);
};
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL );
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
mouse.handlerQueue = queue;
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL );
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
mouse.handlerQueue = queue;
++mice_connected;
UpdateMouseGrab();
}
static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
@@ -245,12 +259,14 @@ static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios
for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) {
button.pressedChangedHandler = nil;
}
UpdateMouseGrab();
}
void SDL_InitGCMouse(void)
{
@autoreleasepool {
/* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */
@autoreleasepool {
/* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */
if (@available(iOS 14.1, tvOS 14.1, *)) {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
@@ -284,6 +300,11 @@ SDL_bool SDL_HasGCMouse(void)
return (mice_connected > 0);
}
SDL_bool SDL_GCMouseRelativeMode(void)
{
return mouse_relative_mode;
}
void SDL_QuitGCMouse(void)
{
@autoreleasepool {
@@ -320,6 +341,11 @@ SDL_bool SDL_HasGCMouse(void)
return SDL_FALSE;
}
SDL_bool SDL_GCMouseRelativeMode(void)
{
return SDL_FALSE;
}
void SDL_QuitGCMouse(void)
{
}
+5 -4
View File
@@ -93,6 +93,7 @@ UIKit_CreateDevice(int devindex)
device->RaiseWindow = UIKit_RaiseWindow;
device->SetWindowBordered = UIKit_SetWindowBordered;
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
device->SetWindowMouseGrab = UIKit_SetWindowMouseGrab;
device->DestroyWindow = UIKit_DestroyWindow;
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
@@ -159,8 +160,8 @@ UIKit_VideoInit(_THIS)
return -1;
}
SDL_InitGCKeyboard();
SDL_InitGCMouse();
SDL_InitGCKeyboard();
SDL_InitGCMouse();
return 0;
}
@@ -168,8 +169,8 @@ UIKit_VideoInit(_THIS)
void
UIKit_VideoQuit(_THIS)
{
SDL_QuitGCKeyboard();
SDL_QuitGCMouse();
SDL_QuitGCKeyboard();
SDL_QuitGCMouse();
UIKit_QuitModes(_this);
}
+17 -3
View File
@@ -27,8 +27,9 @@
#include "../SDL_sysvideo.h"
#include "../../events/SDL_events_c.h"
#import "SDL_uikitviewcontroller.h"
#import "SDL_uikitmessagebox.h"
#include "SDL_uikitviewcontroller.h"
#include "SDL_uikitmessagebox.h"
#include "SDL_uikitevents.h"
#include "SDL_uikitvideo.h"
#include "SDL_uikitmodes.h"
#include "SDL_uikitwindow.h"
@@ -246,7 +247,20 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
return UIRectEdgeNone;
}
}
#endif
- (BOOL)prefersPointerLocked
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (SDL_HasGCMouse() &&
(SDL_GCMouseRelativeMode() || _this->grabbed_window == window)) {
return YES;
} else {
return NO;
}
}
#endif /* !TARGET_OS_TV */
/*
---- Keyboard related functionality below this line ----
+1
View File
@@ -33,6 +33,7 @@ extern void UIKit_HideWindow(_THIS, SDL_Window * window);
extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern void UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo * info);
+20 -6
View File
@@ -161,14 +161,14 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
@autoreleasepool {
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
SDL_Window *other;
SDL_Window *other;
/* We currently only handle a single window per display on iOS */
for (other = _this->windows; other; other = other->next) {
if (other != window && SDL_GetDisplayForWindow(other) == display) {
return SDL_SetError("Only one window allowed per display.");
}
}
for (other = _this->windows; other; other = other->next) {
if (other != window && SDL_GetDisplayForWindow(other) == display) {
return SDL_SetError("Only one window allowed per display.");
}
}
/* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
* user, so it's in standby), try to force the display to a resolution
@@ -320,6 +320,20 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
}
}
void
UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
#if !TARGET_OS_TV
@autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
if (@available(iOS 14.0, *)) {
[viewcontroller setNeedsUpdateOfPrefersPointerLocked];
}
}
#endif /* !TARGET_OS_TV */
}
void
UIKit_DestroyWindow(_THIS, SDL_Window * window)
{
+22 -2
View File
@@ -20,8 +20,7 @@
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_OPENGL_ES2
#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PIB
#include <stdlib.h>
#include <string.h>
@@ -45,6 +44,23 @@
} \
} while (0)
void
VITA_GL_KeyboardCallback(ScePigletPreSwapData *data)
{
SceCommonDialogUpdateParam commonDialogParam;
SDL_zero(commonDialogParam);
commonDialogParam.renderTarget.colorFormat = data->colorFormat;
commonDialogParam.renderTarget.surfaceType = data->surfaceType;
commonDialogParam.renderTarget.colorSurfaceData = data->colorSurfaceData;
commonDialogParam.renderTarget.depthSurfaceData = data->depthSurfaceData;
commonDialogParam.renderTarget.width = data->width;
commonDialogParam.renderTarget.height = data->height;
commonDialogParam.renderTarget.strideInPixels = data->strideInPixels;
commonDialogParam.displaySyncObject = data->displaySyncObject;
sceCommonDialogUpdate(&commonDialogParam);
}
int
VITA_GL_LoadLibrary(_THIS, const char *path)
{
@@ -79,6 +95,7 @@ VITA_GL_CreateContext(_THIS, SDL_Window * window)
EGLSurface surface;
EGLConfig config;
EGLint num_configs;
PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC preSwapCallback;
int i;
const EGLint contextAttribs[] = {
@@ -141,6 +158,9 @@ VITA_GL_CreateContext(_THIS, SDL_Window * window)
_this->gl_data->context = context;
_this->gl_data->surface = surface;
preSwapCallback = (PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC) eglGetProcAddress("eglPigletVitaSetPreSwapCallbackSCE");
preSwapCallback(VITA_GL_KeyboardCallback);
return context;
}

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