summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/SDL2/src/haptic/windows/SDL_windowshaptic.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/SDL2/src/haptic/windows/SDL_windowshaptic.c')
-rw-r--r--3rdparty/SDL2/src/haptic/windows/SDL_windowshaptic.c449
1 files changed, 449 insertions, 0 deletions
diff --git a/3rdparty/SDL2/src/haptic/windows/SDL_windowshaptic.c b/3rdparty/SDL2/src/haptic/windows/SDL_windowshaptic.c
new file mode 100644
index 00000000000..0c038fb1b97
--- /dev/null
+++ b/3rdparty/SDL2/src/haptic/windows/SDL_windowshaptic.c
@@ -0,0 +1,449 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2016 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"
+
+#if SDL_HAPTIC_DINPUT || SDL_HAPTIC_XINPUT
+
+#include "SDL_assert.h"
+#include "SDL_thread.h"
+#include "SDL_mutex.h"
+#include "SDL_timer.h"
+#include "SDL_hints.h"
+#include "SDL_haptic.h"
+#include "../SDL_syshaptic.h"
+#include "SDL_joystick.h"
+#include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
+#include "../../joystick/windows/SDL_windowsjoystick_c.h" /* For joystick hwdata */
+#include "../../joystick/windows/SDL_xinputjoystick_c.h" /* For xinput rumble */
+
+#include "SDL_windowshaptic_c.h"
+#include "SDL_dinputhaptic_c.h"
+#include "SDL_xinputhaptic_c.h"
+
+
+/*
+ * Internal stuff.
+ */
+SDL_hapticlist_item *SDL_hapticlist = NULL;
+static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
+static int numhaptics = 0;
+
+
+/*
+ * Initializes the haptic subsystem.
+ */
+int
+SDL_SYS_HapticInit(void)
+{
+ if (SDL_DINPUT_HapticInit() < 0) {
+ return -1;
+ }
+ if (SDL_XINPUT_HapticInit() < 0) {
+ return -1;
+ }
+ return numhaptics;
+}
+
+int
+SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item)
+{
+ if (SDL_hapticlist_tail == NULL) {
+ SDL_hapticlist = SDL_hapticlist_tail = item;
+ } else {
+ SDL_hapticlist_tail->next = item;
+ SDL_hapticlist_tail = item;
+ }
+
+ /* Device has been added. */
+ ++numhaptics;
+
+ return numhaptics;
+}
+
+int
+SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item)
+{
+ const int retval = item->haptic ? item->haptic->index : -1;
+ if (prev != NULL) {
+ prev->next = item->next;
+ } else {
+ SDL_assert(SDL_hapticlist == item);
+ SDL_hapticlist = item->next;
+ }
+ if (item == SDL_hapticlist_tail) {
+ SDL_hapticlist_tail = prev;
+ }
+ --numhaptics;
+ /* !!! TODO: Send a haptic remove event? */
+ SDL_free(item);
+ return retval;
+}
+
+int
+SDL_SYS_NumHaptics()
+{
+ return numhaptics;
+}
+
+static SDL_hapticlist_item *
+HapticByDevIndex(int device_index)
+{
+ SDL_hapticlist_item *item = SDL_hapticlist;
+
+ if ((device_index < 0) || (device_index >= numhaptics)) {
+ return NULL;
+ }
+
+ while (device_index > 0) {
+ SDL_assert(item != NULL);
+ --device_index;
+ item = item->next;
+ }
+ return item;
+}
+
+/*
+ * Return the name of a haptic device, does not need to be opened.
+ */
+const char *
+SDL_SYS_HapticName(int index)
+{
+ SDL_hapticlist_item *item = HapticByDevIndex(index);
+ return item->name;
+}
+
+/*
+ * Opens a haptic device for usage.
+ */
+int
+SDL_SYS_HapticOpen(SDL_Haptic * haptic)
+{
+ SDL_hapticlist_item *item = HapticByDevIndex(haptic->index);
+ if (item->bXInputHaptic) {
+ return SDL_XINPUT_HapticOpen(haptic, item);
+ } else {
+ return SDL_DINPUT_HapticOpen(haptic, item);
+ }
+}
+
+
+/*
+ * Opens a haptic device from first mouse it finds for usage.
+ */
+int
+SDL_SYS_HapticMouse(void)
+{
+#if SDL_HAPTIC_DINPUT
+ SDL_hapticlist_item *item;
+ int index = 0;
+
+ /* Grab the first mouse haptic device we find. */
+ for (item = SDL_hapticlist; item != NULL; item = item->next) {
+ if (item->capabilities.dwDevType == DI8DEVCLASS_POINTER ) {
+ return index;
+ }
+ ++index;
+ }
+#endif /* SDL_HAPTIC_DINPUT */
+ return -1;
+}
+
+
+/*
+ * Checks to see if a joystick has haptic features.
+ */
+int
+SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
+{
+ const struct joystick_hwdata *hwdata = joystick->hwdata;
+#if SDL_HAPTIC_XINPUT
+ if (hwdata->bXInputHaptic) {
+ return 1;
+ }
+#endif
+#if SDL_HAPTIC_DINPUT
+ if (hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Checks to see if the haptic device and joystick are in reality the same.
+ */
+int
+SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
+{
+ if (joystick->hwdata->bXInputHaptic != haptic->hwdata->bXInputHaptic) {
+ return 0; /* one is XInput, one is not; not the same device. */
+ } else if (joystick->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_JoystickSameHaptic(haptic, joystick);
+ } else {
+ return SDL_DINPUT_JoystickSameHaptic(haptic, joystick);
+ }
+}
+
+/*
+ * Opens a SDL_Haptic from a SDL_Joystick.
+ */
+int
+SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
+{
+ if (joystick->hwdata->bXInputDevice) {
+ return SDL_XINPUT_HapticOpenFromJoystick(haptic, joystick);
+ } else {
+ return SDL_DINPUT_HapticOpenFromJoystick(haptic, joystick);
+ }
+}
+
+/*
+ * Closes the haptic device.
+ */
+void
+SDL_SYS_HapticClose(SDL_Haptic * haptic)
+{
+ if (haptic->hwdata) {
+
+ /* Free effects. */
+ SDL_free(haptic->effects);
+ haptic->effects = NULL;
+ haptic->neffects = 0;
+
+ /* Clean up */
+ if (haptic->hwdata->bXInputHaptic) {
+ SDL_XINPUT_HapticClose(haptic);
+ } else {
+ SDL_DINPUT_HapticClose(haptic);
+ }
+
+ /* Free */
+ SDL_free(haptic->hwdata);
+ haptic->hwdata = NULL;
+ }
+}
+
+/*
+ * Clean up after system specific haptic stuff
+ */
+void
+SDL_SYS_HapticQuit(void)
+{
+ SDL_hapticlist_item *item;
+ SDL_hapticlist_item *next = NULL;
+ SDL_Haptic *hapticitem = NULL;
+
+ extern SDL_Haptic *SDL_haptics;
+ for (hapticitem = SDL_haptics; hapticitem; hapticitem = hapticitem->next) {
+ if ((hapticitem->hwdata->bXInputHaptic) && (hapticitem->hwdata->thread)) {
+ /* we _have_ to stop the thread before we free the XInput DLL! */
+ hapticitem->hwdata->stopThread = 1;
+ SDL_WaitThread(hapticitem->hwdata->thread, NULL);
+ hapticitem->hwdata->thread = NULL;
+ }
+ }
+
+ for (item = SDL_hapticlist; item; item = next) {
+ /* Opened and not closed haptics are leaked, this is on purpose.
+ * Close your haptic devices after usage. */
+ /* !!! FIXME: (...is leaking on purpose a good idea?) - No, of course not. */
+ next = item->next;
+ SDL_free(item->name);
+ SDL_free(item);
+ }
+
+ SDL_XINPUT_HapticQuit();
+ SDL_DINPUT_HapticQuit();
+
+ numhaptics = 0;
+ SDL_hapticlist = NULL;
+ SDL_hapticlist_tail = NULL;
+}
+
+/*
+ * Creates a new haptic effect.
+ */
+int
+SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
+ SDL_HapticEffect * base)
+{
+ int result;
+
+ /* Alloc the effect. */
+ effect->hweffect = (struct haptic_hweffect *)
+ SDL_malloc(sizeof(struct haptic_hweffect));
+ if (effect->hweffect == NULL) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+ SDL_zerop(effect->hweffect);
+
+ if (haptic->hwdata->bXInputHaptic) {
+ result = SDL_XINPUT_HapticNewEffect(haptic, effect, base);
+ } else {
+ result = SDL_DINPUT_HapticNewEffect(haptic, effect, base);
+ }
+ if (result < 0) {
+ SDL_free(effect->hweffect);
+ effect->hweffect = NULL;
+ }
+ return result;
+}
+
+/*
+ * Updates an effect.
+ */
+int
+SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
+ struct haptic_effect *effect,
+ SDL_HapticEffect * data)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticUpdateEffect(haptic, effect, data);
+ } else {
+ return SDL_DINPUT_HapticUpdateEffect(haptic, effect, data);
+ }
+}
+
+/*
+ * Runs an effect.
+ */
+int
+SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
+ Uint32 iterations)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticRunEffect(haptic, effect, iterations);
+ } else {
+ return SDL_DINPUT_HapticRunEffect(haptic, effect, iterations);
+ }
+}
+
+/*
+ * Stops an effect.
+ */
+int
+SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticStopEffect(haptic, effect);
+ } else {
+ return SDL_DINPUT_HapticStopEffect(haptic, effect);
+ }
+}
+
+/*
+ * Frees the effect.
+ */
+void
+SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ SDL_XINPUT_HapticDestroyEffect(haptic, effect);
+ } else {
+ SDL_DINPUT_HapticDestroyEffect(haptic, effect);
+ }
+ SDL_free(effect->hweffect);
+ effect->hweffect = NULL;
+}
+
+/*
+ * Gets the status of a haptic effect.
+ */
+int
+SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
+ struct haptic_effect *effect)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticGetEffectStatus(haptic, effect);
+ } else {
+ return SDL_DINPUT_HapticGetEffectStatus(haptic, effect);
+ }
+}
+
+/*
+ * Sets the gain.
+ */
+int
+SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticSetGain(haptic, gain);
+ } else {
+ return SDL_DINPUT_HapticSetGain(haptic, gain);
+ }
+}
+
+/*
+ * Sets the autocentering.
+ */
+int
+SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticSetAutocenter(haptic, autocenter);
+ } else {
+ return SDL_DINPUT_HapticSetAutocenter(haptic, autocenter);
+ }
+}
+
+/*
+ * Pauses the device.
+ */
+int
+SDL_SYS_HapticPause(SDL_Haptic * haptic)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticPause(haptic);
+ } else {
+ return SDL_DINPUT_HapticPause(haptic);
+ }
+}
+
+/*
+ * Pauses the device.
+ */
+int
+SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticUnpause(haptic);
+ } else {
+ return SDL_DINPUT_HapticUnpause(haptic);
+ }
+}
+
+/*
+ * Stops all the playing effects on the device.
+ */
+int
+SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
+{
+ if (haptic->hwdata->bXInputHaptic) {
+ return SDL_XINPUT_HapticStopAll(haptic);
+ } else {
+ return SDL_DINPUT_HapticStopAll(haptic);
+ }
+}
+
+#endif /* SDL_HAPTIC_DINPUT || SDL_HAPTIC_XINPUT */
+
+/* vi: set ts=4 sw=4 expandtab: */