early-access version 1617

This commit is contained in:
pineappleEA
2021-04-20 21:40:33 +02:00
parent 242b6f6b49
commit f46563104f
510 changed files with 141726 additions and 62846 deletions

View File

@@ -33,8 +33,8 @@
* let it return 0 events. */
#include "SDL_error.h"
#include "SDL_assert.h"
#include "SDL_events.h"
#include "SDL_hints.h"
#include "SDL_timer.h"
#include "SDL_mutex.h"
#include "SDL_joystick.h"
@@ -49,6 +49,7 @@
#include "SDL_windowsjoystick_c.h"
#include "SDL_dinputjoystick_c.h"
#include "SDL_xinputjoystick_c.h"
#include "SDL_rawinputjoystick_c.h"
#include "../../haptic/windows/SDL_dinputhaptic_c.h" /* For haptic hot plugging */
#include "../../haptic/windows/SDL_xinputhaptic_c.h" /* For haptic hot plugging */
@@ -59,17 +60,15 @@
#endif
/* local variables */
static SDL_bool s_bDeviceAdded = SDL_FALSE;
static SDL_bool s_bDeviceRemoved = SDL_FALSE;
static SDL_bool s_bJoystickThread = SDL_FALSE;
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
static SDL_cond *s_condJoystickThread = NULL;
static SDL_mutex *s_mutexJoyStickEnum = NULL;
static SDL_Thread *s_threadJoystick = NULL;
static SDL_Thread *s_joystickThread = NULL;
static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
#ifdef __WINRT__
typedef struct
@@ -109,9 +108,9 @@ typedef struct
/* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal */
static LRESULT CALLBACK
SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
SDL_PrivateJoystickDetectProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (message) {
switch (msg) {
case WM_DEVICECHANGE:
switch (wParam) {
case DBT_DEVICEARRIVAL:
@@ -125,17 +124,29 @@ SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
}
return 0;
case WM_TIMER:
KillTimer(hwnd, wParam);
s_bWindowsDeviceChanged = SDL_TRUE;
return 0;
if (wParam == IDT_SDL_DEVICE_CHANGE_TIMER_1 ||
wParam == IDT_SDL_DEVICE_CHANGE_TIMER_2) {
KillTimer(hwnd, wParam);
s_bWindowsDeviceChanged = SDL_TRUE;
return 0;
}
break;
}
return DefWindowProc (hwnd, message, wParam, lParam);
#if SDL_JOYSTICK_RAWINPUT
return CallWindowProc(RAWINPUT_WindowProc, hwnd, msg, wParam, lParam);
#else
return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
#endif
}
static void
SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
{
#if SDL_JOYSTICK_RAWINPUT
RAWINPUT_UnregisterNotifications();
#endif
if (data->hNotify)
UnregisterDeviceNotification(data->hNotify);
@@ -188,6 +199,10 @@ SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
SDL_CleanupDeviceNotification(data);
return -1;
}
#if SDL_JOYSTICK_RAWINPUT
RAWINPUT_RegisterNotifications(data->messageWindow);
#endif
return 0;
}
@@ -215,26 +230,24 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex
#endif /* __WINRT__ */
static SDL_DeviceNotificationData s_notification_data;
/* Function/thread to scan the system for joysticks. */
static int
SDL_JoystickThread(void *_data)
{
SDL_DeviceNotificationData notification_data;
#if SDL_JOYSTICK_XINPUT
SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT];
SDL_zeroa(bOpenedXInputDevices);
#endif
if (SDL_CreateDeviceNotification(&notification_data) < 0) {
if (SDL_CreateDeviceNotification(&s_notification_data) < 0) {
return -1;
}
SDL_LockMutex(s_mutexJoyStickEnum);
while (s_bJoystickThreadQuit == SDL_FALSE) {
SDL_bool bXInputChanged = SDL_FALSE;
if (SDL_WaitForDeviceNotification(&notification_data, s_mutexJoyStickEnum) == SDL_FALSE) {
if (SDL_WaitForDeviceNotification(&s_notification_data, s_mutexJoyStickEnum) == SDL_FALSE) {
#if SDL_JOYSTICK_XINPUT
/* WM_DEVICECHANGE not working, poll for new XINPUT controllers */
SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 1000);
@@ -246,7 +259,7 @@ SDL_JoystickThread(void *_data)
const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
const SDL_bool available = (result == ERROR_SUCCESS);
if (bOpenedXInputDevices[userId] != available) {
bXInputChanged = SDL_TRUE;
s_bWindowsDeviceChanged = SDL_TRUE;
bOpenedXInputDevices[userId] = available;
}
}
@@ -256,28 +269,67 @@ SDL_JoystickThread(void *_data)
break;
#endif /* SDL_JOYSTICK_XINPUT */
}
if (s_bWindowsDeviceChanged || bXInputChanged) {
s_bDeviceRemoved = SDL_TRUE;
s_bDeviceAdded = SDL_TRUE;
s_bWindowsDeviceChanged = SDL_FALSE;
}
}
SDL_UnlockMutex(s_mutexJoyStickEnum);
SDL_CleanupDeviceNotification(&notification_data);
SDL_CleanupDeviceNotification(&s_notification_data);
return 1;
}
/* spin up the thread to detect hotplug of devices */
static int
SDL_StartJoystickThread(void)
{
s_mutexJoyStickEnum = SDL_CreateMutex();
if (!s_mutexJoyStickEnum) {
return -1;
}
s_condJoystickThread = SDL_CreateCond();
if (!s_condJoystickThread) {
return -1;
}
s_bJoystickThreadQuit = SDL_FALSE;
s_joystickThread = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL);
if (!s_joystickThread) {
return -1;
}
return 0;
}
static void
SDL_StopJoystickThread(void)
{
if (!s_joystickThread) {
return;
}
SDL_LockMutex(s_mutexJoyStickEnum);
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);
s_condJoystickThread = NULL;
SDL_DestroyMutex(s_mutexJoyStickEnum);
s_mutexJoyStickEnum = NULL;
s_joystickThread = NULL;
}
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
{
device->send_add_event = SDL_TRUE;
device->nInstanceID = SDL_GetNextJoystickInstanceID();
device->pNext = SYS_Joystick;
SYS_Joystick = device;
s_bDeviceAdded = SDL_TRUE;
}
static void WINDOWS_JoystickDetect(void);
@@ -300,16 +352,19 @@ WINDOWS_JoystickInit(void)
return -1;
}
s_mutexJoyStickEnum = SDL_CreateMutex();
s_condJoystickThread = SDL_CreateCond();
s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */
s_bWindowsDeviceChanged = SDL_TRUE; /* force a scan of the system for joysticks this first time */
WINDOWS_JoystickDetect();
if (!s_threadJoystick) {
/* spin up the thread to detect hotplug of devices */
s_bJoystickThreadQuit = SDL_FALSE;
s_threadJoystick = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL);
s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE);
if (s_bJoystickThread) {
if (SDL_StartJoystickThread() < 0) {
return -1;
}
} else {
if (SDL_CreateDeviceNotification(&s_notification_data) < 0) {
return -1;
}
}
return 0;
}
@@ -332,17 +387,19 @@ WINDOWS_JoystickGetCount(void)
static void
WINDOWS_JoystickDetect(void)
{
int device_index = 0;
JoyStick_DeviceData *pCurList = NULL;
/* only enum the devices if the joystick thread told us something changed */
if (!s_bDeviceAdded && !s_bDeviceRemoved) {
if (!s_bWindowsDeviceChanged) {
return; /* thread hasn't signaled, nothing to do right now. */
}
SDL_LockMutex(s_mutexJoyStickEnum);
if (s_mutexJoyStickEnum) {
SDL_LockMutex(s_mutexJoyStickEnum);
}
s_bDeviceAdded = SDL_FALSE;
s_bDeviceRemoved = SDL_FALSE;
s_bWindowsDeviceChanged = SDL_FALSE;
pCurList = SYS_Joystick;
SYS_Joystick = NULL;
@@ -353,15 +410,21 @@ WINDOWS_JoystickDetect(void)
/* Look for XInput devices. Do this last, so they're first in the final list. */
SDL_XINPUT_JoystickDetect(&pCurList);
SDL_UnlockMutex(s_mutexJoyStickEnum);
if (s_mutexJoyStickEnum) {
SDL_UnlockMutex(s_mutexJoyStickEnum);
}
while (pCurList) {
JoyStick_DeviceData *pListNext = NULL;
if (pCurList->bXInputDevice) {
#if SDL_HAPTIC_XINPUT
SDL_XINPUT_MaybeRemoveDevice(pCurList->XInputUserId);
#endif
} else {
#if SDL_HAPTIC_DINPUT
SDL_DINPUT_MaybeRemoveDevice(&pCurList->dxdevice);
#endif
}
SDL_PrivateJoystickRemoved(pCurList->nInstanceID);
@@ -372,25 +435,21 @@ WINDOWS_JoystickDetect(void)
pCurList = pListNext;
}
if (s_bDeviceAdded) {
JoyStick_DeviceData *pNewJoystick;
int device_index = 0;
s_bDeviceAdded = SDL_FALSE;
pNewJoystick = SYS_Joystick;
while (pNewJoystick) {
if (pNewJoystick->send_add_event) {
if (pNewJoystick->bXInputDevice) {
SDL_XINPUT_MaybeAddDevice(pNewJoystick->XInputUserId);
} else {
SDL_DINPUT_MaybeAddDevice(&pNewJoystick->dxdevice);
}
SDL_PrivateJoystickAdded(pNewJoystick->nInstanceID);
pNewJoystick->send_add_event = SDL_FALSE;
for (device_index = 0, pCurList = SYS_Joystick; pCurList; ++device_index, pCurList = pCurList->pNext) {
if (pCurList->send_add_event) {
if (pCurList->bXInputDevice) {
#if SDL_HAPTIC_XINPUT
SDL_XINPUT_MaybeAddDevice(pCurList->XInputUserId);
#endif
} else {
#if SDL_HAPTIC_DINPUT
SDL_DINPUT_MaybeAddDevice(&pCurList->dxdevice);
#endif
}
device_index++;
pNewJoystick = pNewJoystick->pNext;
SDL_PrivateJoystickAdded(pCurList->nInstanceID);
pCurList->send_add_event = SDL_FALSE;
}
}
}
@@ -400,8 +459,9 @@ static const char *
WINDOWS_JoystickGetDeviceName(int device_index)
{
JoyStick_DeviceData *device = SYS_Joystick;
int index;
for (; device_index > 0; device_index--)
for (index = device_index; index > 0; index--)
device = device->pNext;
return device->joystickname;
@@ -458,25 +518,26 @@ WINDOWS_JoystickGetDeviceInstanceID(int device_index)
static int
WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
{
JoyStick_DeviceData *joystickdevice = SYS_Joystick;
JoyStick_DeviceData *device = SYS_Joystick;
int index;
for (; device_index > 0; device_index--)
joystickdevice = joystickdevice->pNext;
for (index = device_index; index > 0; index--)
device = device->pNext;
/* allocate memory for system specific hardware data */
joystick->instance_id = joystickdevice->nInstanceID;
joystick->instance_id = device->nInstanceID;
joystick->hwdata =
(struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
if (joystick->hwdata == NULL) {
return SDL_OutOfMemory();
}
SDL_zerop(joystick->hwdata);
joystick->hwdata->guid = joystickdevice->guid;
joystick->hwdata->guid = device->guid;
if (joystickdevice->bXInputDevice) {
return SDL_XINPUT_JoystickOpen(joystick, joystickdevice);
if (device->bXInputDevice) {
return SDL_XINPUT_JoystickOpen(joystick, device);
} else {
return SDL_DINPUT_JoystickOpen(joystick, joystickdevice);
return SDL_DINPUT_JoystickOpen(joystick, device);
}
}
@@ -490,6 +551,30 @@ WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
}
}
static int
WINDOWS_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}
static SDL_bool
WINDOWS_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int
WINDOWS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static int
WINDOWS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
return SDL_Unsupported();
}
static void
WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
{
@@ -531,28 +616,22 @@ WINDOWS_JoystickQuit(void)
}
SYS_Joystick = NULL;
if (s_threadJoystick) {
SDL_LockMutex(s_mutexJoyStickEnum);
s_bJoystickThreadQuit = SDL_TRUE;
SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */
SDL_UnlockMutex(s_mutexJoyStickEnum);
#ifndef __WINRT__
PostThreadMessage(SDL_GetThreadID(s_threadJoystick), WM_QUIT, 0, 0);
#endif
SDL_WaitThread(s_threadJoystick, NULL); /* wait for it to bugger off */
SDL_DestroyMutex(s_mutexJoyStickEnum);
SDL_DestroyCond(s_condJoystickThread);
s_condJoystickThread= NULL;
s_mutexJoyStickEnum = NULL;
s_threadJoystick = NULL;
if (s_bJoystickThread) {
SDL_StopJoystickThread();
} else {
SDL_CleanupDeviceNotification(&s_notification_data);
}
SDL_DINPUT_JoystickQuit();
SDL_XINPUT_JoystickQuit();
s_bDeviceAdded = SDL_FALSE;
s_bDeviceRemoved = SDL_FALSE;
s_bWindowsDeviceChanged = SDL_FALSE;
}
static SDL_bool
WINDOWS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{
return SDL_FALSE;
}
SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
@@ -567,9 +646,14 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
WINDOWS_JoystickGetDeviceInstanceID,
WINDOWS_JoystickOpen,
WINDOWS_JoystickRumble,
WINDOWS_JoystickRumbleTriggers,
WINDOWS_JoystickHasLED,
WINDOWS_JoystickSetLED,
WINDOWS_JoystickSetSensorsEnabled,
WINDOWS_JoystickUpdate,
WINDOWS_JoystickClose,
WINDOWS_JoystickQuit,
WINDOWS_JoystickGetGamepadMapping
};
#endif /* SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT */