early-access version 1988
This commit is contained in:
Vendored
+3
-3
@@ -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
@@ -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;
|
||||
|
||||
Vendored
+32
-12
@@ -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(¤t_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(¤t_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(¤t_audio.impl);
|
||||
}
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
|
||||
+197
-28
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Vendored
+3
-4
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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" );
|
||||
}
|
||||
|
||||
Vendored
+4
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
Vendored
+19
-4
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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(¬ify_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: */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
+12
-11
@@ -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
@@ -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,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);
|
||||
|
||||
Vendored
+4
-4
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Vendored
+2
-2
@@ -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;
|
||||
|
||||
Vendored
+2
-2
@@ -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
@@ -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);
|
||||
|
||||
/* * * */
|
||||
/*
|
||||
|
||||
Vendored
+64
-15
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 ----
|
||||
|
||||
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user