Atlas - SDL_windowshaptic.c

Home / ext / SDL / src / haptic / windows Lines: 1 | Size: 9037 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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#ifdef SDL_HAPTIC_DINPUT 24 25#include "../SDL_syshaptic.h" 26#include "../../joystick/SDL_sysjoystick.h" // For the real SDL_Joystick 27#include "../../joystick/windows/SDL_windowsjoystick_c.h" // For joystick hwdata 28#include "../../joystick/windows/SDL_xinputjoystick_c.h" // For xinput rumble 29 30#include "SDL_windowshaptic_c.h" 31#include "SDL_dinputhaptic_c.h" 32 33// Set up for C function definitions, even when using C++ 34#ifdef __cplusplus 35extern "C" { 36#endif 37 38/* 39 * Internal stuff. 40 */ 41SDL_hapticlist_item *SDL_hapticlist = NULL; 42static SDL_hapticlist_item *SDL_hapticlist_tail = NULL; 43static int numhaptics = 0; 44 45/* 46 * Initializes the haptic subsystem. 47 */ 48bool SDL_SYS_HapticInit(void) 49{ 50 JoyStick_DeviceData *device; 51 52 if (!SDL_DINPUT_HapticInit()) { 53 return false; 54 } 55 56 /* The joystick subsystem will usually be initialized before haptics, 57 * so the initial HapticMaybeAddDevice() calls from the joystick 58 * subsystem will arrive too early to create haptic devices. We will 59 * invoke those callbacks again here to pick up any joysticks that 60 * were added prior to haptics initialization. */ 61 for (device = SYS_Joystick; device; device = device->pNext) { 62 SDL_DINPUT_HapticMaybeAddDevice(&device->dxdevice); 63 } 64 65 return true; 66} 67 68bool SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item) 69{ 70 if (!SDL_hapticlist_tail) { 71 SDL_hapticlist = SDL_hapticlist_tail = item; 72 } else { 73 SDL_hapticlist_tail->next = item; 74 SDL_hapticlist_tail = item; 75 } 76 77 // Device has been added. 78 ++numhaptics; 79 80 return true; 81} 82 83bool SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item) 84{ 85 const bool result = item->haptic ? true : false; 86 if (prev) { 87 prev->next = item->next; 88 } else { 89 SDL_assert(SDL_hapticlist == item); 90 SDL_hapticlist = item->next; 91 } 92 if (item == SDL_hapticlist_tail) { 93 SDL_hapticlist_tail = prev; 94 } 95 --numhaptics; 96 // !!! TODO: Send a haptic remove event? 97 SDL_free(item); 98 return result; 99} 100 101int SDL_SYS_NumHaptics(void) 102{ 103 return numhaptics; 104} 105 106static SDL_hapticlist_item *HapticByDevIndex(int device_index) 107{ 108 SDL_hapticlist_item *item = SDL_hapticlist; 109 110 if ((device_index < 0) || (device_index >= numhaptics)) { 111 return NULL; 112 } 113 114 while (device_index > 0) { 115 SDL_assert(item != NULL); 116 --device_index; 117 item = item->next; 118 } 119 return item; 120} 121 122static SDL_hapticlist_item *HapticByInstanceID(SDL_HapticID instance_id) 123{ 124 SDL_hapticlist_item *item; 125 for (item = SDL_hapticlist; item; item = item->next) { 126 if (instance_id == item->instance_id) { 127 return item; 128 } 129 } 130 return NULL; 131} 132 133SDL_HapticID SDL_SYS_HapticInstanceID(int index) 134{ 135 SDL_hapticlist_item *item = HapticByDevIndex(index); 136 if (item) { 137 return item->instance_id; 138 } 139 return 0; 140} 141 142/* 143 * Return the name of a haptic device, does not need to be opened. 144 */ 145const char *SDL_SYS_HapticName(int index) 146{ 147 SDL_hapticlist_item *item = HapticByDevIndex(index); 148 return item->name; 149} 150 151/* 152 * Opens a haptic device for usage. 153 */ 154bool SDL_SYS_HapticOpen(SDL_Haptic *haptic) 155{ 156 SDL_hapticlist_item *item = HapticByInstanceID(haptic->instance_id); 157 return SDL_DINPUT_HapticOpen(haptic, item); 158} 159 160/* 161 * Opens a haptic device from first mouse it finds for usage. 162 */ 163int SDL_SYS_HapticMouse(void) 164{ 165#ifdef SDL_HAPTIC_DINPUT 166 SDL_hapticlist_item *item; 167 int index = 0; 168 169 // Grab the first mouse haptic device we find. 170 for (item = SDL_hapticlist; item; item = item->next) { 171 if (item->capabilities.dwDevType == DI8DEVCLASS_POINTER) { 172 return index; 173 } 174 ++index; 175 } 176#endif // SDL_HAPTIC_DINPUT 177 return -1; 178} 179 180/* 181 * Checks to see if a joystick has haptic features. 182 */ 183bool SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick) 184{ 185 if (joystick->driver != &SDL_WINDOWS_JoystickDriver) { 186 return false; 187 } 188 if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { 189 return true; 190 } 191 return false; 192} 193 194/* 195 * Checks to see if the haptic device and joystick are in reality the same. 196 */ 197bool SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) 198{ 199 if (joystick->driver != &SDL_WINDOWS_JoystickDriver) { 200 return false; 201 } 202 return SDL_DINPUT_JoystickSameHaptic(haptic, joystick); 203} 204 205/* 206 * Opens a SDL_Haptic from a SDL_Joystick. 207 */ 208bool SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) 209{ 210 SDL_assert(joystick->driver == &SDL_WINDOWS_JoystickDriver); 211 212 return SDL_DINPUT_HapticOpenFromJoystick(haptic, joystick); 213} 214 215/* 216 * Closes the haptic device. 217 */ 218void SDL_SYS_HapticClose(SDL_Haptic *haptic) 219{ 220 if (haptic->hwdata) { 221 222 // Free effects. 223 SDL_free(haptic->effects); 224 haptic->effects = NULL; 225 haptic->neffects = 0; 226 227 // Clean up 228 SDL_DINPUT_HapticClose(haptic); 229 230 // Free 231 SDL_free(haptic->hwdata); 232 haptic->hwdata = NULL; 233 } 234} 235 236/* 237 * Clean up after system specific haptic stuff 238 */ 239void SDL_SYS_HapticQuit(void) 240{ 241 SDL_hapticlist_item *item; 242 SDL_hapticlist_item *next = NULL; 243 244 for (item = SDL_hapticlist; item; item = next) { 245 /* Opened and not closed haptics are leaked, this is on purpose. 246 * Close your haptic devices after usage. */ 247 // !!! FIXME: (...is leaking on purpose a good idea?) - No, of course not. 248 next = item->next; 249 SDL_free(item->name); 250 SDL_free(item); 251 } 252 253 SDL_DINPUT_HapticQuit(); 254 255 numhaptics = 0; 256 SDL_hapticlist = NULL; 257 SDL_hapticlist_tail = NULL; 258} 259 260/* 261 * Creates a new haptic effect. 262 */ 263bool SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, 264 const SDL_HapticEffect *base) 265{ 266 bool result; 267 268 // Alloc the effect. 269 effect->hweffect = (struct haptic_hweffect *) SDL_calloc(1, sizeof(struct haptic_hweffect)); 270 if (!effect->hweffect) { 271 return false; 272 } 273 274 result = SDL_DINPUT_HapticNewEffect(haptic, effect, base); 275 if (!result) { 276 SDL_free(effect->hweffect); 277 effect->hweffect = NULL; 278 } 279 return result; 280} 281 282/* 283 * Updates an effect. 284 */ 285bool SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, const SDL_HapticEffect *data) 286{ 287 return SDL_DINPUT_HapticUpdateEffect(haptic, effect, data); 288} 289 290/* 291 * Runs an effect. 292 */ 293bool SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations) 294{ 295 return SDL_DINPUT_HapticRunEffect(haptic, effect, iterations); 296} 297 298/* 299 * Stops an effect. 300 */ 301bool SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) 302{ 303 return SDL_DINPUT_HapticStopEffect(haptic, effect); 304} 305 306/* 307 * Frees the effect. 308 */ 309void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) 310{ 311 SDL_DINPUT_HapticDestroyEffect(haptic, effect); 312 SDL_free(effect->hweffect); 313 effect->hweffect = NULL; 314} 315 316/* 317 * Gets the status of a haptic effect. 318 */ 319int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect) 320{ 321 return SDL_DINPUT_HapticGetEffectStatus(haptic, effect); 322} 323 324/* 325 * Sets the gain. 326 */ 327bool SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain) 328{ 329 return SDL_DINPUT_HapticSetGain(haptic, gain); 330} 331 332/* 333 * Sets the autocentering. 334 */ 335bool SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) 336{ 337 return SDL_DINPUT_HapticSetAutocenter(haptic, autocenter); 338} 339 340/* 341 * Pauses the device. 342 */ 343bool SDL_SYS_HapticPause(SDL_Haptic *haptic) 344{ 345 return SDL_DINPUT_HapticPause(haptic); 346} 347 348/* 349 * Pauses the device. 350 */ 351bool SDL_SYS_HapticResume(SDL_Haptic *haptic) 352{ 353 return SDL_DINPUT_HapticResume(haptic); 354} 355 356/* 357 * Stops all the playing effects on the device. 358 */ 359bool SDL_SYS_HapticStopAll(SDL_Haptic *haptic) 360{ 361 return SDL_DINPUT_HapticStopAll(haptic); 362} 363 364// Ends C function definitions when using C++ 365#ifdef __cplusplus 366} 367#endif 368 369#endif // SDL_HAPTIC_DINPUT 370
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.