23 #ifdef SDL_HAPTIC_DINPUT
26 #include "SDL_thread.h"
27 #include "SDL_mutex.h"
31 #include "../SDL_syshaptic.h"
33 #include "../../joystick/SDL_sysjoystick.h"
34 #include "../../joystick/windows/SDL_dxjoystick_c.h"
36 #define MAX_HAPTICS 32
43 DIDEVICEINSTANCE instance;
46 DIDEVCAPS capabilities;
49 } SDL_hapticlist[MAX_HAPTICS];
57 LPDIRECTINPUTDEVICE8 device;
65 volatile int stopThread;
72 struct haptic_hweffect
75 LPDIRECTINPUTEFFECT
ref;
76 XINPUT_VIBRATION vibration;
84 static LPDIRECTINPUT8 dinput =
NULL;
91 extern HWND SDL_HelperWindow;
97 static int DI_SetError(
const char *
str,
HRESULT err);
98 static int DI_GUIDIsSame(
const GUID *
a,
const GUID *
b);
99 static int SDL_SYS_HapticOpenFromInstance(
SDL_Haptic * haptic,
100 DIDEVICEINSTANCE instance);
101 static int SDL_SYS_HapticOpenFromDevice8(
SDL_Haptic * haptic,
102 LPDIRECTINPUTDEVICE8 device8,
104 static int SDL_SYS_HapticOpenFromXInput(
SDL_Haptic * haptic,
Uint8 userid);
108 static int SDL_SYS_ToDIEFFECT(
SDL_Haptic * haptic, DIEFFECT * dest,
110 static void SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect,
int type);
112 static int SDLCALL SDL_RunXInputHaptic(
void *arg);
115 static BOOL CALLBACK EnumHapticsCallback(
const DIDEVICEINSTANCE *
117 static BOOL CALLBACK DI_EffectCallback(LPCDIEFFECTINFO pei,
LPVOID pv);
138 DI_GUIDIsSame(
const GUID *
a,
const GUID *
b)
140 return (
SDL_memcmp(a, b,
sizeof (GUID)) == 0);
154 if (dinput !=
NULL) {
159 SDL_memset(SDL_hapticlist, 0,
sizeof(SDL_hapticlist));
165 return DI_SetError(
"Coinitialize", ret);
170 ret = CoCreateInstance(&CLSID_DirectInput8,
NULL, CLSCTX_INPROC_SERVER,
171 &IID_IDirectInput8, (
LPVOID) & dinput);
174 return DI_SetError(
"CoCreateInstance", ret);
178 instance = GetModuleHandle(
NULL);
179 if (instance ==
NULL) {
181 return SDL_SetError(
"GetModuleHandle() failed with error code %d.",
187 return DI_SetError(
"Initializing DirectInput device", ret);
191 ret = IDirectInput8_EnumDevices(dinput,
195 DIEDFL_FORCEFEEDBACK |
196 DIEDFL_ATTACHEDONLY);
199 return DI_SetError(
"Enumerating DirectInput devices", ret);
211 XINPUT_CAPABILITIES caps;
216 SDL_snprintf(buf,
sizeof (buf),
"XInput Controller #%u", i+1);
233 EnumHapticsCallback(
const DIDEVICEINSTANCE * pdidInstance,
VOID *
pContext)
236 LPDIRECTINPUTDEVICE8 device;
240 sizeof(DIDEVICEINSTANCE));
243 ret = IDirectInput8_CreateDevice(dinput, &pdidInstance->guidInstance,
247 return DIENUM_CONTINUE;
251 SDL_hapticlist[
SDL_numhaptics].capabilities.dwSize =
sizeof(DIDEVCAPS);
252 ret = IDirectInputDevice8_GetCapabilities(device,
257 IDirectInputDevice8_Release(device);
258 return DIENUM_CONTINUE;
265 IDirectInputDevice8_Release(device);
272 return DIENUM_CONTINUE;
282 return SDL_hapticlist[
index].name;
289 #define EFFECT_TEST(e,s) \
290 if (DI_GUIDIsSame(&pei->guid, &(e))) \
291 haptic->supported |= (s)
293 DI_EffectCallback(LPCDIEFFECTINFO pei,
LPVOID pv)
314 return DIENUM_CONTINUE;
322 DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev,
LPVOID pvRef)
326 if ((dev->dwType & DIDFT_AXIS) && (dev->dwFlags & DIDOI_FFACTUATOR)) {
332 if (haptic->
naxes >= 3) {
337 return DIENUM_CONTINUE;
351 SDL_SYS_HapticOpenFromInstance(
SDL_Haptic * haptic, DIDEVICEINSTANCE instance)
355 LPDIRECTINPUTDEVICE8 device;
356 LPDIRECTINPUTDEVICE8 device8;
359 ret = IDirectInput8_CreateDevice(dinput, &instance.guidInstance,
362 DI_SetError(
"Creating DirectInput device", ret);
367 ret = IDirectInputDevice8_QueryInterface(device,
368 &IID_IDirectInputDevice8,
371 IDirectInputDevice8_Release(device);
373 DI_SetError(
"Querying DirectInput interface", ret);
377 ret2 = SDL_SYS_HapticOpenFromDevice8(haptic, device8,
SDL_FALSE);
379 IDirectInputDevice8_Release(device8);
390 XINPUT_VIBRATION vibration = { 0, 0 };
416 haptic->
hwdata->bXInputHaptic = 1;
417 haptic->
hwdata->userid = userid;
424 return SDL_SetError(
"Couldn't create XInput haptic mutex");
427 SDL_snprintf(threadName,
sizeof (threadName),
"SDLXInputDev%d", (
int) userid);
429 #if defined(__WIN32__) && !defined(HAVE_LIBC)
430 #undef SDL_CreateThread
440 return SDL_SetError(
"Couldn't create XInput haptic thread");
457 SDL_SYS_HapticOpenFromDevice8(
SDL_Haptic * haptic,
458 LPDIRECTINPUTDEVICE8 device8,
SDL_bool is_joystick)
471 haptic->
hwdata->device = device8;
472 haptic->
hwdata->is_joystick = is_joystick;
475 ret = IDirectInputDevice8_SetCooperativeLevel(haptic->
hwdata->device,
480 DI_SetError(
"Setting cooperative level to exclusive", ret);
485 ret = IDirectInputDevice8_SetDataFormat(haptic->
hwdata->device,
488 DI_SetError(
"Setting data format", ret);
493 ret = IDirectInputDevice8_EnumObjects(haptic->
hwdata->device,
494 DI_DeviceObjectCallback,
497 DI_SetError(
"Getting device axes", ret);
502 ret = IDirectInputDevice8_Acquire(haptic->
hwdata->device);
504 DI_SetError(
"Acquiring DirectInput device", ret);
509 ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->
hwdata->device,
512 DI_SetError(
"Resetting device", ret);
517 ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->
hwdata->device,
518 DISFFC_SETACTUATORSON);
520 DI_SetError(
"Enabling actuators", ret);
525 ret = IDirectInputDevice8_EnumEffects(haptic->
hwdata->device,
526 DI_EffectCallback, haptic,
529 DI_SetError(
"Enumerating supported effects", ret);
533 SDL_SetError(
"Haptic: Internal error on finding supported effects.");
538 dipdw.diph.dwSize =
sizeof(DIPROPDWORD);
539 dipdw.diph.dwHeaderSize =
sizeof(DIPROPHEADER);
540 dipdw.diph.dwObj = 0;
541 dipdw.diph.dwHow = DIPH_DEVICE;
542 dipdw.dwData = 10000;
543 ret = IDirectInputDevice8_SetProperty(haptic->
hwdata->device,
544 DIPROP_FFGAIN, &dipdw.diph);
548 dipdw.diph.dwObj = 0;
549 dipdw.diph.dwHow = DIPH_DEVICE;
550 dipdw.dwData = DIPROPAUTOCENTER_OFF;
551 ret = IDirectInputDevice8_SetProperty(haptic->
hwdata->device,
552 DIPROP_AUTOCENTER, &dipdw.diph);
582 IDirectInputDevice8_Unacquire(haptic->
hwdata->device);
594 if (SDL_hapticlist[haptic->
index].bXInputHaptic) {
595 return SDL_SYS_HapticOpenFromXInput(haptic, SDL_hapticlist[haptic->
index].userid);
598 return SDL_SYS_HapticOpenFromInstance(haptic, SDL_hapticlist[haptic->
index].instance);
612 if (SDL_hapticlist[i].capabilities.dwDevType == DI8DEVCLASS_POINTER ) {
629 ((hwdata->
Capabilities.dwFlags & DIDC_FORCEFEEDBACK) != 0) );
643 DIDEVICEINSTANCE hap_instance, joy_instance;
645 hap_instance.dwSize =
sizeof(DIDEVICEINSTANCE);
646 joy_instance.dwSize =
sizeof(DIDEVICEINSTANCE);
649 ret = IDirectInputDevice8_GetDeviceInfo(haptic->
hwdata->device,
660 if (DI_GUIDIsSame(&hap_instance.guidInstance, &joy_instance.guidInstance))
676 DIDEVICEINSTANCE joy_instance;
677 joy_instance.dwSize =
sizeof(DIDEVICEINSTANCE);
686 return SDL_SYS_HapticOpenFromXInput(haptic, SDL_hapticlist[haptic->
index].userid);
691 idret = IDirectInputDevice8_GetDeviceInfo(joystick->
hwdata->
InputDevice, &joy_instance);
695 if (DI_GUIDIsSame(&SDL_hapticlist[i].instance.guidInstance,
696 &joy_instance.guidInstance)) {
721 if (haptic->
hwdata->bXInputHaptic) {
722 haptic->
hwdata->stopThread = 1;
726 IDirectInputDevice8_Unacquire(haptic->
hwdata->device);
728 if (haptic->
hwdata->is_joystick == 0) {
729 IDirectInputDevice8_Release(haptic->
hwdata->device);
755 SDL_hapticlist[
i].name =
NULL;
758 if (dinput !=
NULL) {
759 IDirectInput8_Release(dinput);
774 DIGetTriggerButton(
Uint16 button)
776 DWORD dwTriggerButton;
778 dwTriggerButton = DIEB_NOTRIGGER;
781 dwTriggerButton = DIJOFS_BUTTON(button - 1);
784 return dwTriggerButton;
798 effect->dwFlags |= DIEFF_SPHERICAL;
799 effect->rglDirection =
NULL;
805 if (rglDir ==
NULL) {
809 effect->rglDirection = rglDir;
813 effect->dwFlags |= DIEFF_POLAR;
814 rglDir[0] = dir->
dir[0];
817 effect->dwFlags |= DIEFF_CARTESIAN;
818 rglDir[0] = dir->
dir[0];
820 rglDir[1] = dir->
dir[1];
822 rglDir[2] = dir->
dir[2];
825 effect->dwFlags |= DIEFF_SPHERICAL;
826 rglDir[0] = dir->
dir[0];
828 rglDir[1] = dir->
dir[1];
830 rglDir[2] = dir->
dir[2];
838 #define CONVERT(x) (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF)
843 SDL_SYS_ToDIEFFECT(
SDL_Haptic * haptic, DIEFFECT * dest,
847 DICONSTANTFORCE *constant;
848 DIPERIODIC *periodic;
851 DICUSTOMFORCE *custom;
852 DIENVELOPE *envelope;
862 dest->dwSize =
sizeof(DIEFFECT);
863 dest->dwSamplePeriod = 0;
864 dest->dwGain = 10000;
865 dest->dwFlags = DIEFF_OBJECTOFFSETS;
869 if (envelope ==
NULL) {
873 dest->lpEnvelope = envelope;
874 envelope->dwSize =
sizeof(DIENVELOPE);
877 dest->cAxes = haptic->
naxes;
878 if (dest->cAxes > 0) {
883 axes[0] = haptic->
hwdata->axes[0];
884 if (dest->cAxes > 1) {
885 axes[1] = haptic->
hwdata->axes[1];
887 if (dest->cAxes > 2) {
888 axes[2] = haptic->
hwdata->axes[2];
890 dest->rgdwAxes =
axes;
898 constant =
SDL_malloc(
sizeof(DICONSTANTFORCE));
899 if (constant ==
NULL) {
902 SDL_memset(constant, 0,
sizeof(DICONSTANTFORCE));
905 constant->lMagnitude = CONVERT(hap_constant->
level);
906 dest->cbTypeSpecificParams =
sizeof(DICONSTANTFORCE);
907 dest->lpvTypeSpecificParams = constant;
910 dest->dwDuration = hap_constant->
length * 1000;
911 dest->dwTriggerButton = DIGetTriggerButton(hap_constant->
button);
912 dest->dwTriggerRepeatInterval = hap_constant->
interval;
913 dest->dwStartDelay = hap_constant->
delay * 1000;
916 if (SDL_SYS_SetDirection(dest, &hap_constant->
direction, dest->cAxes)
925 dest->lpEnvelope =
NULL;
927 envelope->dwAttackLevel = CONVERT(hap_constant->
attack_level);
929 envelope->dwFadeLevel = CONVERT(hap_constant->
fade_level);
930 envelope->dwFadeTime = hap_constant->
fade_length * 1000;
943 if (periodic ==
NULL) {
949 periodic->dwMagnitude = CONVERT(hap_periodic->
magnitude);
950 periodic->lOffset = CONVERT(hap_periodic->
offset);
951 periodic->dwPhase = hap_periodic->
phase;
952 periodic->dwPeriod = hap_periodic->
period * 1000;
953 dest->cbTypeSpecificParams =
sizeof(DIPERIODIC);
954 dest->lpvTypeSpecificParams = periodic;
957 dest->dwDuration = hap_periodic->
length * 1000;
958 dest->dwTriggerButton = DIGetTriggerButton(hap_periodic->
button);
959 dest->dwTriggerRepeatInterval = hap_periodic->
interval;
960 dest->dwStartDelay = hap_periodic->
delay * 1000;
963 if (SDL_SYS_SetDirection(dest, &hap_periodic->
direction, dest->cAxes)
972 dest->lpEnvelope =
NULL;
974 envelope->dwAttackLevel = CONVERT(hap_periodic->
attack_level);
976 envelope->dwFadeLevel = CONVERT(hap_periodic->
fade_level);
977 envelope->dwFadeTime = hap_periodic->
fade_length * 1000;
987 condition =
SDL_malloc(
sizeof(DICONDITION) * dest->cAxes);
988 if (condition ==
NULL) {
991 SDL_memset(condition, 0,
sizeof(DICONDITION));
994 for (i = 0; i < (
int) dest->cAxes; i++) {
995 condition[
i].lOffset = CONVERT(hap_condition->
center[i]);
996 condition[
i].lPositiveCoefficient =
998 condition[
i].lNegativeCoefficient =
1000 condition[
i].dwPositiveSaturation =
1002 condition[
i].dwNegativeSaturation =
1003 CONVERT(hap_condition->
left_sat[i]);
1004 condition[
i].lDeadBand = CONVERT(hap_condition->
deadband[i]);
1006 dest->cbTypeSpecificParams =
sizeof(DICONDITION) * dest->cAxes;
1007 dest->lpvTypeSpecificParams = condition;
1010 dest->dwDuration = hap_condition->
length * 1000;
1011 dest->dwTriggerButton = DIGetTriggerButton(hap_condition->
button);
1012 dest->dwTriggerRepeatInterval = hap_condition->
interval;
1013 dest->dwStartDelay = hap_condition->
delay * 1000;
1016 if (SDL_SYS_SetDirection(dest, &hap_condition->
direction, dest->cAxes)
1023 dest->lpEnvelope =
NULL;
1028 hap_ramp = &src->
ramp;
1036 ramp->lStart = CONVERT(hap_ramp->
start);
1037 ramp->lEnd = CONVERT(hap_ramp->
end);
1038 dest->cbTypeSpecificParams =
sizeof(DIRAMPFORCE);
1039 dest->lpvTypeSpecificParams = ramp;
1042 dest->dwDuration = hap_ramp->
length * 1000;
1043 dest->dwTriggerButton = DIGetTriggerButton(hap_ramp->
button);
1044 dest->dwTriggerRepeatInterval = hap_ramp->
interval;
1045 dest->dwStartDelay = hap_ramp->
delay * 1000;
1048 if (SDL_SYS_SetDirection(dest, &hap_ramp->
direction, dest->cAxes) < 0) {
1055 dest->lpEnvelope =
NULL;
1057 envelope->dwAttackLevel = CONVERT(hap_ramp->
attack_level);
1059 envelope->dwFadeLevel = CONVERT(hap_ramp->
fade_level);
1060 envelope->dwFadeTime = hap_ramp->
fade_length * 1000;
1066 hap_custom = &src->
custom;
1068 if (custom ==
NULL) {
1071 SDL_memset(custom, 0,
sizeof(DICUSTOMFORCE));
1074 custom->cChannels = hap_custom->
channels;
1075 custom->dwSamplePeriod = hap_custom->
period * 1000;
1076 custom->cSamples = hap_custom->
samples;
1077 custom->rglForceData =
1078 SDL_malloc(
sizeof(LONG) * custom->cSamples * custom->cChannels);
1080 custom->rglForceData[
i] = CONVERT(hap_custom->
data[i]);
1082 dest->cbTypeSpecificParams =
sizeof(DICUSTOMFORCE);
1083 dest->lpvTypeSpecificParams = custom;
1086 dest->dwDuration = hap_custom->
length * 1000;
1087 dest->dwTriggerButton = DIGetTriggerButton(hap_custom->
button);
1088 dest->dwTriggerRepeatInterval = hap_custom->
interval;
1089 dest->dwStartDelay = hap_custom->
delay * 1000;
1092 if (SDL_SYS_SetDirection(dest, &hap_custom->
direction, dest->cAxes) <
1101 dest->lpEnvelope =
NULL;
1103 envelope->dwAttackLevel = CONVERT(hap_custom->
attack_level);
1105 envelope->dwFadeLevel = CONVERT(hap_custom->
fade_level);
1106 envelope->dwFadeTime = hap_custom->
fade_length * 1000;
1124 SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect,
int type)
1126 DICUSTOMFORCE *custom;
1129 effect->lpEnvelope =
NULL;
1131 effect->rgdwAxes =
NULL;
1132 if (effect->lpvTypeSpecificParams !=
NULL) {
1134 custom = (DICUSTOMFORCE *) effect->lpvTypeSpecificParams;
1136 custom->rglForceData =
NULL;
1138 SDL_free(effect->lpvTypeSpecificParams);
1139 effect->lpvTypeSpecificParams =
NULL;
1142 effect->rglDirection =
NULL;
1152 switch (effect->
type) {
1154 return &GUID_ConstantForce;
1157 return &GUID_RampForce;
1167 return &GUID_Triangle;
1170 return &GUID_SawtoothUp;
1173 return &GUID_SawtoothDown;
1176 return &GUID_Spring;
1179 return &GUID_Damper;
1182 return &GUID_Inertia;
1185 return &GUID_Friction;
1189 return &GUID_CustomForce;
1206 REFGUID type = SDL_SYS_HapticEffectType(base);
1208 if ((type ==
NULL) && (!haptic->
hwdata->bXInputHaptic)) {
1213 effect->
hweffect = (
struct haptic_hweffect *)
1222 if (haptic->
hwdata->bXInputHaptic) {
1228 if (SDL_SYS_ToDIEFFECT(haptic, &effect->
hweffect->effect, base) < 0) {
1229 goto err_effectdone;
1233 ret = IDirectInputDevice8_CreateEffect(haptic->
hwdata->device, type,
1237 DI_SetError(
"Unable to create effect", ret);
1238 goto err_effectdone;
1244 SDL_SYS_HapticFreeDIEFFECT(&effect->
hweffect->effect, base->
type);
1264 if (haptic->
hwdata->bXInputHaptic) {
1265 XINPUT_VIBRATION *vib = &effect->
hweffect->vibration;
1270 if (haptic->
hwdata->stopTicks) {
1279 if (SDL_SYS_ToDIEFFECT(haptic, &temp, data) < 0) {
1285 flags = DIEP_DIRECTION |
1289 DIEP_TRIGGERBUTTON |
1290 DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS;
1294 IDirectInputEffect_SetParameters(effect->
hweffect->ref, &temp, flags);
1296 DI_SetError(
"Unable to update effect", ret);
1301 SDL_SYS_HapticFreeDIEFFECT(&effect->
hweffect->effect, data->
type);
1307 SDL_SYS_HapticFreeDIEFFECT(&temp, data->
type);
1322 if (haptic->
hwdata->bXInputHaptic) {
1323 XINPUT_VIBRATION *vib = &effect->
hweffect->vibration;
1341 ret = IDirectInputEffect_Start(effect->
hweffect->ref, iter, 0);
1343 return DI_SetError(
"Running the effect", ret);
1358 if (haptic->
hwdata->bXInputHaptic) {
1359 XINPUT_VIBRATION vibration = { 0, 0 };
1361 haptic->
hwdata->stopTicks = 0;
1366 ret = IDirectInputEffect_Stop(effect->
hweffect->ref);
1368 return DI_SetError(
"Unable to stop effect", ret);
1383 if (haptic->
hwdata->bXInputHaptic) {
1386 ret = IDirectInputEffect_Unload(effect->
hweffect->ref);
1388 DI_SetError(
"Removing effect from the device", ret);
1390 SDL_SYS_HapticFreeDIEFFECT(&effect->
hweffect->effect,
1408 ret = IDirectInputEffect_GetEffectStatus(effect->
hweffect->ref, &status);
1410 return DI_SetError(
"Getting effect status", ret);
1429 dipdw.diph.dwSize =
sizeof(DIPROPDWORD);
1430 dipdw.diph.dwHeaderSize =
sizeof(DIPROPHEADER);
1431 dipdw.diph.dwObj = 0;
1432 dipdw.diph.dwHow = DIPH_DEVICE;
1433 dipdw.dwData = gain * 100;
1436 ret = IDirectInputDevice8_SetProperty(haptic->
hwdata->device,
1437 DIPROP_FFGAIN, &dipdw.diph);
1439 return DI_SetError(
"Setting gain", ret);
1456 dipdw.diph.dwSize =
sizeof(DIPROPDWORD);
1457 dipdw.diph.dwHeaderSize =
sizeof(DIPROPHEADER);
1458 dipdw.diph.dwObj = 0;
1459 dipdw.diph.dwHow = DIPH_DEVICE;
1460 dipdw.dwData = (autocenter == 0) ? DIPROPAUTOCENTER_OFF :
1461 DIPROPAUTOCENTER_ON;
1464 ret = IDirectInputDevice8_SetProperty(haptic->
hwdata->device,
1465 DIPROP_AUTOCENTER, &dipdw.diph);
1467 return DI_SetError(
"Setting autocenter", ret);
1483 ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->
hwdata->device,
1486 return DI_SetError(
"Pausing the device", ret);
1502 ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->
hwdata->device,
1505 return DI_SetError(
"Pausing the device", ret);
1520 if (haptic->
hwdata->bXInputHaptic) {
1521 XINPUT_VIBRATION vibration = { 0, 0 };
1523 haptic->
hwdata->stopTicks = 0;
1529 ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->
hwdata->device,
1532 return DI_SetError(
"Stopping the device", ret);
1554 SDL_RunXInputHaptic(
void *arg)
1556 struct haptic_hwdata *hwdata = (
struct haptic_hwdata *) arg;
1558 while (!hwdata->stopThread) {
1562 if ((hwdata->stopTicks) && (hwdata->stopTicks <
SDL_GetTicks())) {
1563 XINPUT_VIBRATION vibration = { 0, 0 };
1564 hwdata->stopTicks = 0;
int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
struct haptic_hwdata * hwdata
#define DIRECTINPUT_VERSION
Structure that represents a haptic direction.
struct haptic_effect * effects
#define SDL_HAPTIC_SPHERICAL
Uses spherical coordinates for the direction.
LPDIRECTINPUTDEVICE8 InputDevice
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
#define SDL_HAPTIC_AUTOCENTER
Device can set autocenter.
A structure containing a template for a Periodic effect.
DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt,...)
#define SDL_HAPTIC_GAIN
Device can set global gain.
typedef HRESULT(WINAPI *LPD3DXIMTSIGNALCALLBACK)(CONST D3DXVECTOR2 *uv
#define SDL_HAPTIC_CUSTOM
Custom effect is supported.
DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex *mutex)
#define SDL_HAPTIC_TRIANGLE
Triangle wave effect supported.
SDL_HapticDirection direction
int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
int SDL_SYS_HapticMouse(void)
int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
#define SDL_HAPTIC_INERTIA
Inertia effect supported - uses axes acceleration.
DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void)
DECLSPEC void SDLCALL SDL_free(void *mem)
int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
GLboolean GLboolean GLboolean GLboolean a
const char * SDL_SYS_HapticName(int index)
A structure containing a template for a Condition effect.
EGLImageKHR EGLint * name
DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len)
The SDL Haptic subsystem allows you to control haptic (force feedback) devices.
int SDL_SYS_HapticUnpause(SDL_Haptic *haptic)
#define XINPUT_CAPS_FFB_SUPPORTED
#define SDL_HAPTIC_SINE
Sine wave effect supported.
#define XINPUTGETCAPABILITIES
#define SDL_XINPUT_MAX_DEVICES
int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex *mutex)
struct joystick_hwdata * hwdata
A structure containing a template for a Constant effect.
#define SDL_HINT_XINPUT_ENABLED
A variable that lets you disable the detection and use of Xinput gamepad devices. ...
#define SDL_HAPTIC_INFINITY
Used to play a device an infinite number of times.
#define SDL_HAPTIC_CARTESIAN
Uses cartesian coordinates for the direction.
uint32_t Uint32
An unsigned 32-bit integer type.
DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread *thread, int *status)
SDL_HapticCondition condition
DECLSPEC Uint32 SDLCALL SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
The generic template for any haptic effect.
#define SDL_HAPTIC_CONSTANT
Constant effect supported.
int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
void WIN_UnloadXInputDLL(void)
HRESULT WIN_CoInitialize(void)
DECLSPEC char *SDLCALL SDL_strdup(const char *str)
#define SDL_HAPTIC_POLAR
Uses polar coordinates for the direction.
DECLSPEC void SDLCALL SDL_Delay(Uint32 ms)
Wait a specified number of milliseconds before returning.
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
#define WIN_StringToUTF8(S)
SDL_HapticConstant constant
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
#define SDL_HAPTIC_PAUSE
Device can be paused.
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data)
int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
SDL_HapticDirection direction
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
A structure containing a template for a Ramp effect.
DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data)
void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
#define SDL_assert(condition)
static SDL_Thread * thread
#define SDL_OutOfMemory()
void WIN_CoUninitialize(void)
#define SDL_arraysize(array)
struct SDL_mutex SDL_mutex
int SDL_SYS_HapticInit(void)
void SDL_SYS_HapticQuit(void)
struct haptic_hweffect * hweffect
int WIN_LoadXInputDLL(void)
#define SDL_HAPTIC_STATUS
Device can be queried for effect status.
void SDL_SYS_HapticClose(SDL_Haptic *haptic)
int SDL_SYS_HapticPause(SDL_Haptic *haptic)
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
SDL_HapticDirection direction
SDL_HapticLeftRight leftright
GLenum GLuint GLsizei const GLchar * buf
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
#define SDL_HAPTIC_RAMP
Ramp effect supported.
uint8_t Uint8
An unsigned 8-bit integer type.
#define SDL_HAPTIC_SPRING
Spring effect supported - uses axes position.
DECLSPEC int SDLCALL SDL_atoi(const char *str)
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
GLdouble GLdouble GLdouble b
A structure containing a template for the SDL_HAPTIC_CUSTOM effect.
int SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
uint16_t Uint16
An unsigned 16-bit integer type.
#define SDL_HAPTIC_SAWTOOTHUP
Sawtoothup wave effect supported.
DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex *mutex)
int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain)
#define SDL_HAPTIC_LEFTRIGHT
Left/Right effect supported.
int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
SDL_HapticPeriodic periodic
#define SDL_HAPTIC_FRICTION
Friction effect supported - uses axes movement.
typedef VOID(WINAPI *PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)(HGLRC dstCtx
#define SDL_HAPTIC_SAWTOOTHDOWN
Sawtoothdown wave effect supported.
SDL_HapticDirection direction
SDL_HapticDirection direction
int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base)
#define SDL_HAPTIC_DAMPER
Damper effect supported - uses axes velocity.
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC