SDL  2.0
SDL_windowsjoystick.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT
24 
25 /* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de
26  * A. Formiga's WINMM driver.
27  *
28  * Hats and sliders are completely untested; the app I'm writing this for mostly
29  * doesn't use them and I don't own any joysticks with them.
30  *
31  * We don't bother to use event notification here. It doesn't seem to work
32  * with polled devices, and it's fine to call IDirectInputDevice8_GetDeviceData and
33  * let it return 0 events. */
34 
35 #include "SDL_error.h"
36 #include "SDL_assert.h"
37 #include "SDL_events.h"
38 #include "SDL_timer.h"
39 #include "SDL_mutex.h"
40 #include "SDL_joystick.h"
41 #include "../SDL_sysjoystick.h"
42 #include "../../thread/SDL_systhread.h"
43 #include "../../core/windows/SDL_windows.h"
44 #if !defined(__WINRT__)
45 #include <dbt.h>
46 #endif
47 
48 #define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
49 #include "SDL_windowsjoystick_c.h"
50 #include "SDL_dinputjoystick_c.h"
51 #include "SDL_xinputjoystick_c.h"
52 
53 #include "../../haptic/windows/SDL_dinputhaptic_c.h" /* For haptic hot plugging */
54 #include "../../haptic/windows/SDL_xinputhaptic_c.h" /* For haptic hot plugging */
55 
56 
57 #ifndef DEVICE_NOTIFY_WINDOW_HANDLE
58 #define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
59 #endif
60 
61 /* local variables */
62 static SDL_bool s_bDeviceAdded = SDL_FALSE;
63 static SDL_bool s_bDeviceRemoved = SDL_FALSE;
64 static SDL_cond *s_condJoystickThread = NULL;
65 static SDL_mutex *s_mutexJoyStickEnum = NULL;
66 static SDL_Thread *s_threadJoystick = NULL;
67 static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
68 
69 JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
70 
71 static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
72 
73 #ifdef __WINRT__
74 
75 typedef struct
76 {
77  int unused;
78 } SDL_DeviceNotificationData;
79 
80 static void
81 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
82 {
83 }
84 
85 static int
86 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
87 {
88  return 0;
89 }
90 
91 static SDL_bool
92 SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex)
93 {
94  return SDL_FALSE;
95 }
96 
97 #else /* !__WINRT__ */
98 
99 typedef struct
100 {
101  HRESULT coinitialized;
102  WNDCLASSEX wincl;
103  HWND messageWindow;
104  HDEVNOTIFY hNotify;
105 } SDL_DeviceNotificationData;
106 
107 #define IDT_SDL_DEVICE_CHANGE_TIMER_1 1200
108 #define IDT_SDL_DEVICE_CHANGE_TIMER_2 1201
109 
110 /* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal */
111 static LRESULT CALLBACK
112 SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
113 {
114  switch (message) {
115  case WM_DEVICECHANGE:
116  switch (wParam) {
117  case DBT_DEVICEARRIVAL:
118  case DBT_DEVICEREMOVECOMPLETE:
119  if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
120  /* notify 300ms and 2 seconds later to ensure all APIs have updated status */
121  SetTimer(hwnd, IDT_SDL_DEVICE_CHANGE_TIMER_1, 300, NULL);
122  SetTimer(hwnd, IDT_SDL_DEVICE_CHANGE_TIMER_2, 2000, NULL);
123  }
124  break;
125  }
126  return 0;
127  case WM_TIMER:
128  KillTimer(hwnd, wParam);
129  s_bWindowsDeviceChanged = SDL_TRUE;
130  return 0;
131  }
132 
133  return DefWindowProc (hwnd, message, wParam, lParam);
134 }
135 
136 static void
137 SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
138 {
139  if (data->hNotify)
140  UnregisterDeviceNotification(data->hNotify);
141 
142  if (data->messageWindow)
143  DestroyWindow(data->messageWindow);
144 
145  UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance);
146 
147  if (data->coinitialized == S_OK) {
149  }
150 }
151 
152 static int
153 SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
154 {
155  DEV_BROADCAST_DEVICEINTERFACE dbh;
156  GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
157 
158  SDL_zerop(data);
159 
160  data->coinitialized = WIN_CoInitialize();
161 
162  data->wincl.hInstance = GetModuleHandle(NULL);
163  data->wincl.lpszClassName = L"Message";
164  data->wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc; /* This function is called by windows */
165  data->wincl.cbSize = sizeof (WNDCLASSEX);
166 
167  if (!RegisterClassEx(&data->wincl)) {
168  WIN_SetError("Failed to create register class for joystick autodetect");
169  SDL_CleanupDeviceNotification(data);
170  return -1;
171  }
172 
173  data->messageWindow = (HWND)CreateWindowEx(0, L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
174  if (!data->messageWindow) {
175  WIN_SetError("Failed to create message window for joystick autodetect");
176  SDL_CleanupDeviceNotification(data);
177  return -1;
178  }
179 
180  SDL_zero(dbh);
181  dbh.dbcc_size = sizeof(dbh);
182  dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
183  dbh.dbcc_classguid = GUID_DEVINTERFACE_HID;
184 
185  data->hNotify = RegisterDeviceNotification(data->messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE);
186  if (!data->hNotify) {
187  WIN_SetError("Failed to create notify device for joystick autodetect");
188  SDL_CleanupDeviceNotification(data);
189  return -1;
190  }
191  return 0;
192 }
193 
194 static SDL_bool
195 SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex)
196 {
197  MSG msg;
198  int lastret = 1;
199 
200  if (!data->messageWindow) {
201  return SDL_FALSE; /* device notifications require a window */
202  }
203 
205  while (lastret > 0 && s_bWindowsDeviceChanged == SDL_FALSE) {
206  lastret = GetMessage(&msg, NULL, 0, 0); /* WM_QUIT causes return value of 0 */
207  if (lastret > 0) {
208  TranslateMessage(&msg);
209  DispatchMessage(&msg);
210  }
211  }
213  return (lastret != -1) ? SDL_TRUE : SDL_FALSE;
214 }
215 
216 #endif /* __WINRT__ */
217 
218 /* Function/thread to scan the system for joysticks. */
219 static int
220 SDL_JoystickThread(void *_data)
221 {
222  SDL_DeviceNotificationData notification_data;
223 
224 #if SDL_JOYSTICK_XINPUT
225  SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT];
226  SDL_zeroa(bOpenedXInputDevices);
227 #endif
228 
229  if (SDL_CreateDeviceNotification(&notification_data) < 0) {
230  return -1;
231  }
232 
233  SDL_LockMutex(s_mutexJoyStickEnum);
234  while (s_bJoystickThreadQuit == SDL_FALSE) {
235  SDL_bool bXInputChanged = SDL_FALSE;
236 
237  if (SDL_WaitForDeviceNotification(&notification_data, s_mutexJoyStickEnum) == SDL_FALSE) {
238 #if SDL_JOYSTICK_XINPUT
239  /* WM_DEVICECHANGE not working, poll for new XINPUT controllers */
240  SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 1000);
241  if (SDL_XINPUT_Enabled() && XINPUTGETCAPABILITIES) {
242  /* scan for any change in XInput devices */
243  Uint8 userId;
244  for (userId = 0; userId < XUSER_MAX_COUNT; userId++) {
245  XINPUT_CAPABILITIES capabilities;
246  const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
247  const SDL_bool available = (result == ERROR_SUCCESS);
248  if (bOpenedXInputDevices[userId] != available) {
249  bXInputChanged = SDL_TRUE;
250  bOpenedXInputDevices[userId] = available;
251  }
252  }
253  }
254 #else
255  /* WM_DEVICECHANGE not working, no XINPUT, no point in keeping thread alive */
256  break;
257 #endif /* SDL_JOYSTICK_XINPUT */
258  }
259 
260  if (s_bWindowsDeviceChanged || bXInputChanged) {
261  s_bDeviceRemoved = SDL_TRUE;
262  s_bDeviceAdded = SDL_TRUE;
263  s_bWindowsDeviceChanged = SDL_FALSE;
264  }
265  }
266  SDL_UnlockMutex(s_mutexJoyStickEnum);
267 
268  SDL_CleanupDeviceNotification(&notification_data);
269 
270  return 1;
271 }
272 
274 {
275  device->send_add_event = SDL_TRUE;
276  device->nInstanceID = SDL_GetNextJoystickInstanceID();
277  device->pNext = SYS_Joystick;
279 
280  s_bDeviceAdded = SDL_TRUE;
281 }
282 
283 static void WINDOWS_JoystickDetect(void);
284 static void WINDOWS_JoystickQuit(void);
285 
286 /* Function to scan the system for joysticks.
287  * Joystick 0 should be the system default joystick.
288  * It should return 0, or -1 on an unrecoverable fatal error.
289  */
290 static int
291 WINDOWS_JoystickInit(void)
292 {
293  if (SDL_DINPUT_JoystickInit() < 0) {
294  WINDOWS_JoystickQuit();
295  return -1;
296  }
297 
298  if (SDL_XINPUT_JoystickInit() < 0) {
299  WINDOWS_JoystickQuit();
300  return -1;
301  }
302 
303  s_mutexJoyStickEnum = SDL_CreateMutex();
304  s_condJoystickThread = SDL_CreateCond();
305  s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */
306 
307  WINDOWS_JoystickDetect();
308 
309  if (!s_threadJoystick) {
310  /* spin up the thread to detect hotplug of devices */
311  s_bJoystickThreadQuit = SDL_FALSE;
312  s_threadJoystick = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL);
313  }
314  return 0;
315 }
316 
317 /* return the number of joysticks that are connected right now */
318 static int
319 WINDOWS_JoystickGetCount(void)
320 {
321  int nJoysticks = 0;
323  while (device) {
324  nJoysticks++;
325  device = device->pNext;
326  }
327 
328  return nJoysticks;
329 }
330 
331 /* detect any new joysticks being inserted into the system */
332 static void
333 WINDOWS_JoystickDetect(void)
334 {
335  JoyStick_DeviceData *pCurList = NULL;
336 
337  /* only enum the devices if the joystick thread told us something changed */
338  if (!s_bDeviceAdded && !s_bDeviceRemoved) {
339  return; /* thread hasn't signaled, nothing to do right now. */
340  }
341 
342  SDL_LockMutex(s_mutexJoyStickEnum);
343 
344  s_bDeviceAdded = SDL_FALSE;
345  s_bDeviceRemoved = SDL_FALSE;
346 
347  pCurList = SYS_Joystick;
348  SYS_Joystick = NULL;
349 
350  /* Look for DirectInput joysticks, wheels, head trackers, gamepads, etc.. */
351  SDL_DINPUT_JoystickDetect(&pCurList);
352 
353  /* Look for XInput devices. Do this last, so they're first in the final list. */
354  SDL_XINPUT_JoystickDetect(&pCurList);
355 
356  SDL_UnlockMutex(s_mutexJoyStickEnum);
357 
358  while (pCurList) {
359  JoyStick_DeviceData *pListNext = NULL;
360 
361  if (pCurList->bXInputDevice) {
363  } else {
365  }
366 
368 
369  pListNext = pCurList->pNext;
370  SDL_free(pCurList->joystickname);
371  SDL_free(pCurList);
372  pCurList = pListNext;
373  }
374 
375  if (s_bDeviceAdded) {
376  JoyStick_DeviceData *pNewJoystick;
377  int device_index = 0;
378  s_bDeviceAdded = SDL_FALSE;
379  pNewJoystick = SYS_Joystick;
380  while (pNewJoystick) {
381  if (pNewJoystick->send_add_event) {
382  if (pNewJoystick->bXInputDevice) {
384  } else {
385  SDL_DINPUT_MaybeAddDevice(&pNewJoystick->dxdevice);
386  }
387 
388  SDL_PrivateJoystickAdded(pNewJoystick->nInstanceID);
389 
390  pNewJoystick->send_add_event = SDL_FALSE;
391  }
392  device_index++;
393  pNewJoystick = pNewJoystick->pNext;
394  }
395  }
396 }
397 
398 /* Function to get the device-dependent name of a joystick */
399 static const char *
400 WINDOWS_JoystickGetDeviceName(int device_index)
401 {
403 
404  for (; device_index > 0; device_index--)
405  device = device->pNext;
406 
407  return device->joystickname;
408 }
409 
410 static int
411 WINDOWS_JoystickGetDevicePlayerIndex(int device_index)
412 {
414  int index;
415 
416  for (index = device_index; index > 0; index--)
417  device = device->pNext;
418 
419  return device->bXInputDevice ? (int)device->XInputUserId : -1;
420 }
421 
422 static void
423 WINDOWS_JoystickSetDevicePlayerIndex(int device_index, int player_index)
424 {
425 }
426 
427 /* return the stable device guid for this device index */
428 static SDL_JoystickGUID
429 WINDOWS_JoystickGetDeviceGUID(int device_index)
430 {
432  int index;
433 
434  for (index = device_index; index > 0; index--)
435  device = device->pNext;
436 
437  return device->guid;
438 }
439 
440 /* Function to perform the mapping between current device instance and this joysticks instance id */
441 static SDL_JoystickID
442 WINDOWS_JoystickGetDeviceInstanceID(int device_index)
443 {
445  int index;
446 
447  for (index = device_index; index > 0; index--)
448  device = device->pNext;
449 
450  return device->nInstanceID;
451 }
452 
453 /* Function to open a joystick for use.
454  The joystick to open is specified by the device index.
455  This should fill the nbuttons and naxes fields of the joystick structure.
456  It returns 0, or -1 if there is an error.
457  */
458 static int
459 WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
460 {
461  JoyStick_DeviceData *joystickdevice = SYS_Joystick;
462 
463  for (; device_index > 0; device_index--)
464  joystickdevice = joystickdevice->pNext;
465 
466  /* allocate memory for system specific hardware data */
467  joystick->instance_id = joystickdevice->nInstanceID;
468  joystick->hwdata =
469  (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
470  if (joystick->hwdata == NULL) {
471  return SDL_OutOfMemory();
472  }
473  SDL_zerop(joystick->hwdata);
474  joystick->hwdata->guid = joystickdevice->guid;
475 
476  if (joystickdevice->bXInputDevice) {
477  return SDL_XINPUT_JoystickOpen(joystick, joystickdevice);
478  } else {
479  return SDL_DINPUT_JoystickOpen(joystick, joystickdevice);
480  }
481 }
482 
483 static int
484 WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
485 {
486  if (joystick->hwdata->bXInputDevice) {
487  return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble);
488  } else {
489  return SDL_DINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble);
490  }
491 }
492 
493 static void
494 WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
495 {
496  if (!joystick->hwdata) {
497  return;
498  }
499 
500  if (joystick->hwdata->bXInputDevice) {
501  SDL_XINPUT_JoystickUpdate(joystick);
502  } else {
503  SDL_DINPUT_JoystickUpdate(joystick);
504  }
505 }
506 
507 /* Function to close a joystick after use */
508 static void
509 WINDOWS_JoystickClose(SDL_Joystick * joystick)
510 {
511  if (joystick->hwdata->bXInputDevice) {
512  SDL_XINPUT_JoystickClose(joystick);
513  } else {
514  SDL_DINPUT_JoystickClose(joystick);
515  }
516 
517  SDL_free(joystick->hwdata);
518 }
519 
520 /* Function to perform any system-specific joystick related cleanup */
521 static void
522 WINDOWS_JoystickQuit(void)
523 {
525 
526  while (device) {
527  JoyStick_DeviceData *device_next = device->pNext;
528  SDL_free(device->joystickname);
529  SDL_free(device);
530  device = device_next;
531  }
532  SYS_Joystick = NULL;
533 
534  if (s_threadJoystick) {
535  SDL_LockMutex(s_mutexJoyStickEnum);
536  s_bJoystickThreadQuit = SDL_TRUE;
537  SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */
538  SDL_UnlockMutex(s_mutexJoyStickEnum);
539 #ifndef __WINRT__
540  PostThreadMessage(SDL_GetThreadID(s_threadJoystick), WM_QUIT, 0, 0);
541 #endif
542  SDL_WaitThread(s_threadJoystick, NULL); /* wait for it to bugger off */
543 
544  SDL_DestroyMutex(s_mutexJoyStickEnum);
545  SDL_DestroyCond(s_condJoystickThread);
546  s_condJoystickThread= NULL;
547  s_mutexJoyStickEnum = NULL;
548  s_threadJoystick = NULL;
549  }
550 
553 
554  s_bDeviceAdded = SDL_FALSE;
555  s_bDeviceRemoved = SDL_FALSE;
556 }
557 
558 SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
559 {
560  WINDOWS_JoystickInit,
561  WINDOWS_JoystickGetCount,
562  WINDOWS_JoystickDetect,
563  WINDOWS_JoystickGetDeviceName,
564  WINDOWS_JoystickGetDevicePlayerIndex,
565  WINDOWS_JoystickSetDevicePlayerIndex,
566  WINDOWS_JoystickGetDeviceGUID,
567  WINDOWS_JoystickGetDeviceInstanceID,
568  WINDOWS_JoystickOpen,
569  WINDOWS_JoystickRumble,
570  WINDOWS_JoystickUpdate,
571  WINDOWS_JoystickClose,
572  WINDOWS_JoystickQuit,
573 };
574 
575 #endif /* SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT */
576 
577 /* vi: set ts=4 sw=4 expandtab: */
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:418
SYS_Joystick
JoyStick_DeviceData * SYS_Joystick
JoyStick_DeviceData::dxdevice
DIDEVICEINSTANCE dxdevice
Definition: SDL_windowsjoystick_c.h:39
SDL_XINPUT_JoystickQuit
void SDL_XINPUT_JoystickQuit(void)
Definition: SDL_xinputjoystick.c:571
SDL_XINPUT_Enabled
SDL_bool SDL_XINPUT_Enabled(void)
Definition: SDL_xinputjoystick.c:532
SDL_events.h
SDL_XINPUT_JoystickInit
int SDL_XINPUT_JoystickInit(void)
Definition: SDL_xinputjoystick.c:538
SDL_LockMutex
#define SDL_LockMutex
Definition: SDL_dynapi_overrides.h:260
NULL
#define NULL
Definition: begin_code.h:167
SDL_timer.h
message
GLuint GLsizei const GLchar * message
Definition: SDL_opengl_glext.h:2486
SDL_joystick.h
SDL_error.h
SDL_zerop
#define SDL_zerop(x)
Definition: SDL_stdinc.h:419
SDL_mutex
Definition: SDL_sysmutex.c:29
WINDOWS_AddJoystickDevice
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
mutex
static SDL_mutex * mutex
Definition: testlock.c:23
JoyStick_DeviceData::guid
SDL_JoystickGUID guid
Definition: SDL_windowsjoystick_c.h:32
SDL_PrivateJoystickAdded
void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:921
SDL_CreateMutex
#define SDL_CreateMutex
Definition: SDL_dynapi_overrides.h:259
SDL_XINPUT_JoystickRumble
int SDL_XINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
Definition: SDL_xinputjoystick.c:555
JoyStick_DeviceData
Definition: SDL_windowsjoystick_c.h:30
SDL_DestroyCond
#define SDL_DestroyCond
Definition: SDL_dynapi_overrides.h:272
unused
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF base if bpp PF set rept prefetch_distance PF set OFFSET endr endif endm macro preload_leading_step2 base if bpp ifc DST PF PF else if bpp lsl PF PF lsl PF PF lsl PF PF PF else PF lsl PF lsl PF lsl PF endif SIZE macro preload_middle scratch_holds_offset if bpp if else PF PF endif endif endif endm macro preload_trailing base if bpp if bpp *pix_per_block PF PF lsl PF PF PF PF PF else PF lsl PF lsl PF PF PF PF PF base if bpp if narrow_case &&bpp<=dst_w_bpp) PF bic, WK0, base, #31 PF pld,[WK0] PF add, WK1, base, X, LSL #bpp_shift PF sub, WK1, WK1, #1 PF bic, WK1, WK1, #31 PF cmp, WK1, WK0 PF beq, 90f PF pld,[WK1]90:.else PF bic, WK0, base, #31 PF pld,[WK0] PF add, WK1, base, X, lsl #bpp_shift PF sub, WK1, WK1, #1 PF bic, WK1, WK1, #31 PF cmp, WK1, WK0 PF beq, 92f91:PF add, WK0, WK0, #32 PF cmp, WK0, WK1 PF pld,[WK0] PF bne, 91b92:.endif .endif.endm.macro conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, 0 .if decrementx sub &cond X, X, #8 *numbytes/dst_w_bpp .endif process_tail cond, numbytes, firstreg .if !((flags) &FLAG_PROCESS_DOES_STORE) pixst cond, numbytes, firstreg, DST .endif.endm.macro conditional_process1 cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx .if(flags) &FLAG_BRANCH_OVER .ifc cond, mi bpl 100f .endif .ifc cond, cs bcc 100f .endif .ifc cond, ne beq 100f .endif conditional_process1_helper, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx100:.else conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx .endif.endm.macro conditional_process2 test, cond1, cond2, process_head, process_tail, numbytes1, numbytes2, firstreg1, firstreg2, unaligned_src, unaligned_mask, decrementx .if(flags) &(FLAG_DST_READWRITE|FLAG_BRANCH_OVER|FLAG_PROCESS_CORRUPTS_PSR|FLAG_PROCESS_DOES_STORE) test conditional_process1 cond1, process_head, process_tail, numbytes1, firstreg1, unaligned_src, unaligned_mask, decrementx .if(flags) &FLAG_PROCESS_CORRUPTS_PSR test .endif conditional_process1 cond2, process_head, process_tail, numbytes2, firstreg2, unaligned_src, unaligned_mask, decrementx .else test process_head cond1, numbytes1, firstreg1, unaligned_src, unaligned_mask, 0 process_head cond2, numbytes2, firstreg2, unaligned_src, unaligned_mask, 0 .if decrementx sub &cond1 X, X, #8 *numbytes1/dst_w_bpp sub &cond2 X, X, #8 *numbytes2/dst_w_bpp .endif process_tail cond1, numbytes1, firstreg1 process_tail cond2, numbytes2, firstreg2 pixst cond1, numbytes1, firstreg1, DST pixst cond2, numbytes2, firstreg2, DST .endif.endm.macro test_bits_1_0_ptr .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 movs SCRATCH, X, lsl #32-1 .else movs SCRATCH, WK0, lsl #32-1 .endif.endm.macro test_bits_3_2_ptr .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 movs SCRATCH, X, lsl #32-3 .else movs SCRATCH, WK0, lsl #32-3 .endif.endm.macro leading_15bytes process_head, process_tail .set DECREMENT_X, 1 .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 .set DECREMENT_X, 0 sub X, X, WK0, lsr #dst_bpp_shift str X,[sp, #LINE_SAVED_REG_COUNT *4] mov X, WK0 .endif .if dst_w_bpp==8 conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, DECREMENT_X .elseif dst_w_bpp==16 test_bits_1_0_ptr conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, DECREMENT_X .endif conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, DECREMENT_X .if(flags) &FLAG_PROCESS_CORRUPTS_WK0 ldr X,[sp, #LINE_SAVED_REG_COUNT *4] .endif.endm.macro test_bits_3_2_pix movs SCRATCH, X, lsl #dst_bpp_shift+32-3.endm.macro test_bits_1_0_pix .if dst_w_bpp==8 movs SCRATCH, X, lsl #dst_bpp_shift+32-1 .else movs SCRATCH, X, lsr #1 .endif.endm.macro trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask conditional_process2 test_bits_3_2_pix, cs, mi, process_head, process_tail, 8, 4, 0, 2, unaligned_src, unaligned_mask, 0 .if dst_w_bpp==16 test_bits_1_0_pix conditional_process1 cs, process_head, process_tail, 2, 0, unaligned_src, unaligned_mask, 0 .elseif dst_w_bpp==8 conditional_process2 test_bits_1_0_pix, cs, mi, process_head, process_tail, 2, 1, 0, 1, unaligned_src, unaligned_mask, 0 .endif.endm.macro wide_case_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, dst_alignment110:.set SUBBLOCK, 0 .rept pix_per_block *dst_w_bpp/128 process_head, 16, 0, unaligned_src, unaligned_mask, 1 .if(src_bpp > 0) &&(mask_bpp==0) &&((flags) &FLAG_PROCESS_PRESERVES_SCRATCH) preload_middle src_bpp, SRC, 1 .elseif(src_bpp==0) &&(mask_bpp > 0) &&((flags) &FLAG_PROCESS_PRESERVES_SCRATCH) preload_middle mask_bpp, MASK, 1 .else preload_middle src_bpp, SRC, 0 preload_middle mask_bpp, MASK, 0 .endif .if(dst_r_bpp > 0) &&((SUBBLOCK % 2)==0) &&(((flags) &FLAG_NO_PRELOAD_DST)==0) PF pld,[DST, #32 *prefetch_distance - dst_alignment] .endif process_tail, 16, 0 .if !((flags) &FLAG_PROCESS_DOES_STORE) pixst, 16, 0, DST .endif .set SUBBLOCK, SUBBLOCK+1 .endr subs X, X, #pix_per_block bhs 110b.endm.macro wide_case_inner_loop_and_trailing_pixels process_head, process_tail, process_inner_loop, exit_label, unaligned_src, unaligned_mask .if dst_r_bpp > tst bne process_inner_loop DST_PRELOAD_BIAS endif preload_trailing SRC preload_trailing MASK DST endif add medium_case_inner_loop_and_trailing_pixels unaligned_mask endm macro medium_case_inner_loop_and_trailing_pixels unused
Definition: pixman-arm-simd-asm.h:487
SDL_DINPUT_MaybeRemoveDevice
int SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance)
Definition: SDL_dinputhaptic.c:1205
SDL_GetNextJoystickInstanceID
SDL_JoystickID SDL_GetNextJoystickInstanceID()
Definition: SDL_joystick.c:250
SDL_DINPUT_JoystickInit
int SDL_DINPUT_JoystickInit(void)
Definition: SDL_dinputjoystick.c:1237
index
GLuint index
Definition: SDL_opengl_glext.h:663
SDL_Thread
Definition: SDL_thread_c.h:54
SDL_zeroa
#define SDL_zeroa(x)
Definition: SDL_stdinc.h:420
SDL_cond
Definition: SDL_syscond.c:31
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
JoyStick_DeviceData::bXInputDevice
SDL_bool bXInputDevice
Definition: SDL_windowsjoystick_c.h:36
SDL_DINPUT_JoystickClose
void SDL_DINPUT_JoystickClose(SDL_Joystick *joystick)
Definition: SDL_dinputjoystick.c:1265
SDL_PrivateJoystickRemoved
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
Definition: SDL_joystick.c:987
SDL_JoystickID
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81
SDL_windowsjoystick_c.h
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_CreateThreadInternal
SDL_Thread * SDL_CreateThreadInternal(int(*fn)(void *), const char *name, const size_t stacksize, void *data)
Definition: SDL_thread.c:435
WIN_CoUninitialize
void WIN_CoUninitialize(void)
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
JoyStick_DeviceData::nInstanceID
SDL_JoystickID nInstanceID
Definition: SDL_windowsjoystick_c.h:35
SDL_mutex.h
JoyStick_DeviceData::XInputUserId
Uint8 XInputUserId
Definition: SDL_windowsjoystick_c.h:38
SDL_CondWaitTimeout
#define SDL_CondWaitTimeout
Definition: SDL_dynapi_overrides.h:276
SDL_dinputjoystick_c.h
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_assert.h
SDL_CondBroadcast
#define SDL_CondBroadcast
Definition: SDL_dynapi_overrides.h:274
SDL_DINPUT_JoystickUpdate
void SDL_DINPUT_JoystickUpdate(SDL_Joystick *joystick)
Definition: SDL_dinputjoystick.c:1260
SDL_WINDOWS_JoystickDriver
SDL_JoystickDriver SDL_WINDOWS_JoystickDriver
SDL_XINPUT_JoystickDetect
void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
Definition: SDL_xinputjoystick.c:544
SDL_GetThreadID
#define SDL_GetThreadID
Definition: SDL_dynapi_overrides.h:476
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_XINPUT_JoystickUpdate
void SDL_XINPUT_JoystickUpdate(SDL_Joystick *joystick)
Definition: SDL_xinputjoystick.c:561
SDL_CreateCond
#define SDL_CreateCond
Definition: SDL_dynapi_overrides.h:271
WIN_CoInitialize
HRESULT WIN_CoInitialize(void)
available
static int available()
Definition: video.c:356
SDL_DINPUT_JoystickQuit
void SDL_DINPUT_JoystickQuit(void)
Definition: SDL_dinputjoystick.c:1270
SDL_DINPUT_JoystickRumble
int SDL_DINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
Definition: SDL_dinputjoystick.c:1254
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_xinputjoystick_c.h
S_OK
#define S_OK
Definition: SDL_directx.h:47
WIN_SetError
int WIN_SetError(const char *prefix)
SDL_DestroyMutex
#define SDL_DestroyMutex
Definition: SDL_dynapi_overrides.h:263
JoyStick_DeviceData::joystickname
char * joystickname
Definition: SDL_windowsjoystick_c.h:33
SDL_DINPUT_JoystickOpen
int SDL_DINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice)
Definition: SDL_dinputjoystick.c:1248
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_DINPUT_MaybeAddDevice
int SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance)
Definition: SDL_dinputhaptic.c:1199
SDL_XINPUT_MaybeRemoveDevice
int SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid)
Definition: SDL_xinputhaptic.c:387
SDL_XINPUT_JoystickOpen
int SDL_XINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice)
Definition: SDL_xinputjoystick.c:549
SDL_UnlockMutex
#define SDL_UnlockMutex
Definition: SDL_dynapi_overrides.h:262
JoyStick_DeviceData::send_add_event
Uint8 send_add_event
Definition: SDL_windowsjoystick_c.h:34
SDL_XINPUT_MaybeAddDevice
int SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid)
Definition: SDL_xinputhaptic.c:381
device
static SDL_AudioDeviceID device
Definition: loopwave.c:37
SDL_JoystickGUID
Definition: SDL_joystick.h:70
SDL_XINPUT_JoystickClose
void SDL_XINPUT_JoystickClose(SDL_Joystick *joystick)
Definition: SDL_xinputjoystick.c:566
JoyStick_DeviceData::pNext
struct JoyStick_DeviceData * pNext
Definition: SDL_windowsjoystick_c.h:41
SDL_WaitThread
#define SDL_WaitThread
Definition: SDL_dynapi_overrides.h:478
SDL_DINPUT_JoystickDetect
void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
Definition: SDL_dinputjoystick.c:1243
joystick_hwdata
Definition: SDL_sysjoystick_c.h:46
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179