mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 23:24:41 +00:00
Updates SDL to version 2.0.4, which makes it compatible with VS2015.
This commit is contained in:
parent
7b52fed504
commit
b63ef177f4
924 changed files with 79241 additions and 39934 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
|
@ -343,7 +343,7 @@ SDL_HapticClose(SDL_Haptic * haptic)
|
|||
}
|
||||
|
||||
/* Check if it's still in use */
|
||||
if (--haptic->ref_count < 0) {
|
||||
if (--haptic->ref_count > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -845,3 +845,4 @@ SDL_HapticRumbleStop(SDL_Haptic * haptic)
|
|||
return SDL_HapticStopEffect(haptic, haptic->rumble_id);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
|
@ -21,15 +21,12 @@
|
|||
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
#ifndef _SDL_syshaptic_h
|
||||
#define _SDL_syshaptic_h
|
||||
|
||||
#include "SDL_haptic.h"
|
||||
|
||||
|
||||
/*
|
||||
* Number of haptic devices on the system.
|
||||
*/
|
||||
extern Uint8 SDL_numhaptics;
|
||||
|
||||
|
||||
struct haptic_effect
|
||||
{
|
||||
SDL_HapticEffect effect; /* The current event */
|
||||
|
|
@ -206,5 +203,6 @@ extern int SDL_SYS_HapticUnpause(SDL_Haptic * haptic);
|
|||
*/
|
||||
extern int SDL_SYS_HapticStopAll(SDL_Haptic * haptic);
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
#endif /* _SDL_syshaptic_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
#ifdef SDL_HAPTIC_IOKIT
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_haptic.h"
|
||||
#include "../SDL_syshaptic.h"
|
||||
#include "SDL_joystick.h"
|
||||
|
|
@ -91,14 +92,14 @@ static int numhaptics = -1;
|
|||
* Like strerror but for force feedback errors.
|
||||
*/
|
||||
static const char *
|
||||
FFStrError(HRESULT err)
|
||||
FFStrError(unsigned int err)
|
||||
{
|
||||
switch (err) {
|
||||
case FFERR_DEVICEFULL:
|
||||
return "device full";
|
||||
/* This should be valid, but for some reason isn't defined... */
|
||||
/* case FFERR_DEVICENOTREG:
|
||||
return "device not registered"; */
|
||||
/* This should be valid, but for some reason isn't defined... */
|
||||
/* case FFERR_DEVICENOTREG:
|
||||
return "device not registered"; */
|
||||
case FFERR_DEVICEPAUSED:
|
||||
return "device paused";
|
||||
case FFERR_DEVICERELEASED:
|
||||
|
|
@ -257,21 +258,18 @@ MacHaptic_MaybeAddDevice( io_object_t device )
|
|||
kCFAllocatorDefault,
|
||||
kNilOptions);
|
||||
if ((result == KERN_SUCCESS) && hidProperties) {
|
||||
refCF =
|
||||
CFDictionaryGetValue(hidProperties,
|
||||
CFSTR(kIOHIDPrimaryUsagePageKey));
|
||||
refCF = CFDictionaryGetValue(hidProperties,
|
||||
CFSTR(kIOHIDPrimaryUsagePageKey));
|
||||
if (refCF) {
|
||||
if (!CFNumberGetValue(refCF, kCFNumberLongType,
|
||||
&item->usagePage))
|
||||
SDL_SetError
|
||||
("Haptic: Recieving device's usage page.");
|
||||
refCF =
|
||||
CFDictionaryGetValue(hidProperties,
|
||||
CFSTR(kIOHIDPrimaryUsageKey));
|
||||
if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usagePage)) {
|
||||
SDL_SetError("Haptic: Receiving device's usage page.");
|
||||
}
|
||||
refCF = CFDictionaryGetValue(hidProperties,
|
||||
CFSTR(kIOHIDPrimaryUsageKey));
|
||||
if (refCF) {
|
||||
if (!CFNumberGetValue(refCF, kCFNumberLongType,
|
||||
&item->usage))
|
||||
SDL_SetError("Haptic: Recieving device's usage.");
|
||||
if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usage)) {
|
||||
SDL_SetError("Haptic: Receiving device's usage.");
|
||||
}
|
||||
}
|
||||
}
|
||||
CFRelease(hidProperties);
|
||||
|
|
@ -377,24 +375,21 @@ HIDGetDeviceProduct(io_service_t dev, char *name)
|
|||
|
||||
|
||||
/* Get product name */
|
||||
refCF =
|
||||
CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
|
||||
if (!refCF)
|
||||
refCF =
|
||||
CFDictionaryGetValue(usbProperties,
|
||||
CFSTR("USB Product Name"));
|
||||
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
|
||||
if (!refCF) {
|
||||
refCF = CFDictionaryGetValue(usbProperties,
|
||||
CFSTR("USB Product Name"));
|
||||
}
|
||||
if (refCF) {
|
||||
if (!CFStringGetCString(refCF, name, 256,
|
||||
CFStringGetSystemEncoding())) {
|
||||
return SDL_SetError
|
||||
("Haptic: CFStringGetCString error retrieving pDevice->product.");
|
||||
return SDL_SetError("Haptic: CFStringGetCString error retrieving pDevice->product.");
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(usbProperties);
|
||||
} else {
|
||||
return SDL_SetError
|
||||
("Haptic: IORegistryEntryCreateCFProperties failed to create usbProperties.");
|
||||
return SDL_SetError("Haptic: IORegistryEntryCreateCFProperties failed to create usbProperties.");
|
||||
}
|
||||
|
||||
/* Release stuff. */
|
||||
|
|
@ -457,9 +452,9 @@ GetSupportedFeatures(SDL_Haptic * haptic)
|
|||
/* Check if supports gain. */
|
||||
ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_FFGAIN,
|
||||
&val, sizeof(val));
|
||||
if (ret == FF_OK)
|
||||
if (ret == FF_OK) {
|
||||
supported |= SDL_HAPTIC_GAIN;
|
||||
else if (ret != FFERR_UNSUPPORTED) {
|
||||
} else if (ret != FFERR_UNSUPPORTED) {
|
||||
return SDL_SetError("Haptic: Unable to get if device supports gain: %s.",
|
||||
FFStrError(ret));
|
||||
}
|
||||
|
|
@ -467,9 +462,9 @@ GetSupportedFeatures(SDL_Haptic * haptic)
|
|||
/* Checks if supports autocenter. */
|
||||
ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_AUTOCENTER,
|
||||
&val, sizeof(val));
|
||||
if (ret == FF_OK)
|
||||
if (ret == FF_OK) {
|
||||
supported |= SDL_HAPTIC_AUTOCENTER;
|
||||
else if (ret != FFERR_UNSUPPORTED) {
|
||||
} else if (ret != FFERR_UNSUPPORTED) {
|
||||
return SDL_SetError
|
||||
("Haptic: Unable to get if device supports autocenter: %s.",
|
||||
FFStrError(ret));
|
||||
|
|
@ -485,7 +480,7 @@ GetSupportedFeatures(SDL_Haptic * haptic)
|
|||
supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE;
|
||||
|
||||
haptic->supported = supported;
|
||||
return 0;;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -556,7 +551,7 @@ SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service)
|
|||
FFReleaseDevice(haptic->hwdata->device);
|
||||
creat_err:
|
||||
if (haptic->hwdata != NULL) {
|
||||
free(haptic->hwdata);
|
||||
SDL_free(haptic->hwdata);
|
||||
haptic->hwdata = NULL;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -604,8 +599,9 @@ SDL_SYS_HapticMouse(void)
|
|||
int
|
||||
SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
|
||||
{
|
||||
if (joystick->hwdata->ffservice != 0)
|
||||
if (joystick->hwdata->ffservice != 0) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -617,8 +613,9 @@ int
|
|||
SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
||||
{
|
||||
if (IOObjectIsEqualTo((io_object_t) ((size_t)haptic->hwdata->device),
|
||||
joystick->hwdata->ffservice))
|
||||
joystick->hwdata->ffservice)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -686,7 +683,10 @@ SDL_SYS_HapticQuit(void)
|
|||
IOObjectRelease(item->dev);
|
||||
SDL_free(item);
|
||||
}
|
||||
|
||||
numhaptics = -1;
|
||||
SDL_hapticlist = NULL;
|
||||
SDL_hapticlist_tail = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -739,18 +739,22 @@ SDL_SYS_SetDirection(FFEFFECT * effect, SDL_HapticDirection * dir, int naxes)
|
|||
case SDL_HAPTIC_CARTESIAN:
|
||||
effect->dwFlags |= FFEFF_CARTESIAN;
|
||||
rglDir[0] = dir->dir[0];
|
||||
if (naxes > 1)
|
||||
if (naxes > 1) {
|
||||
rglDir[1] = dir->dir[1];
|
||||
if (naxes > 2)
|
||||
}
|
||||
if (naxes > 2) {
|
||||
rglDir[2] = dir->dir[2];
|
||||
}
|
||||
return 0;
|
||||
case SDL_HAPTIC_SPHERICAL:
|
||||
effect->dwFlags |= FFEFF_SPHERICAL;
|
||||
rglDir[0] = dir->dir[0];
|
||||
if (naxes > 1)
|
||||
if (naxes > 1) {
|
||||
rglDir[1] = dir->dir[1];
|
||||
if (naxes > 2)
|
||||
}
|
||||
if (naxes > 2) {
|
||||
rglDir[2] = dir->dir[2];
|
||||
}
|
||||
return 0;
|
||||
|
||||
default:
|
||||
|
|
@ -767,22 +771,21 @@ SDL_SYS_SetDirection(FFEFFECT * effect, SDL_HapticDirection * dir, int naxes)
|
|||
* Creates the FFEFFECT from a SDL_HapticEffect.
|
||||
*/
|
||||
static int
|
||||
SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest,
|
||||
SDL_HapticEffect * src)
|
||||
SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src)
|
||||
{
|
||||
int i;
|
||||
FFCONSTANTFORCE *constant;
|
||||
FFPERIODIC *periodic;
|
||||
FFCONDITION *condition; /* Actually an array of conditions - one per axis. */
|
||||
FFRAMPFORCE *ramp;
|
||||
FFCUSTOMFORCE *custom;
|
||||
FFENVELOPE *envelope;
|
||||
SDL_HapticConstant *hap_constant;
|
||||
SDL_HapticPeriodic *hap_periodic;
|
||||
SDL_HapticCondition *hap_condition;
|
||||
SDL_HapticRamp *hap_ramp;
|
||||
SDL_HapticCustom *hap_custom;
|
||||
DWORD *axes;
|
||||
FFCONSTANTFORCE *constant = NULL;
|
||||
FFPERIODIC *periodic = NULL;
|
||||
FFCONDITION *condition = NULL; /* Actually an array of conditions - one per axis. */
|
||||
FFRAMPFORCE *ramp = NULL;
|
||||
FFCUSTOMFORCE *custom = NULL;
|
||||
FFENVELOPE *envelope = NULL;
|
||||
SDL_HapticConstant *hap_constant = NULL;
|
||||
SDL_HapticPeriodic *hap_periodic = NULL;
|
||||
SDL_HapticCondition *hap_condition = NULL;
|
||||
SDL_HapticRamp *hap_ramp = NULL;
|
||||
SDL_HapticCustom *hap_custom = NULL;
|
||||
DWORD *axes = NULL;
|
||||
|
||||
/* Set global stuff. */
|
||||
SDL_memset(dest, 0, sizeof(FFEFFECT));
|
||||
|
|
@ -873,9 +876,10 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest,
|
|||
SDL_memset(periodic, 0, sizeof(FFPERIODIC));
|
||||
|
||||
/* Specifics */
|
||||
periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
|
||||
periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude));
|
||||
periodic->lOffset = CONVERT(hap_periodic->offset);
|
||||
periodic->dwPhase = hap_periodic->phase;
|
||||
periodic->dwPhase =
|
||||
(hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000;
|
||||
periodic->dwPeriod = hap_periodic->period * 1000;
|
||||
dest->cbTypeSpecificParams = sizeof(FFPERIODIC);
|
||||
dest->lpvTypeSpecificParams = periodic;
|
||||
|
|
@ -911,25 +915,28 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest,
|
|||
case SDL_HAPTIC_INERTIA:
|
||||
case SDL_HAPTIC_FRICTION:
|
||||
hap_condition = &src->condition;
|
||||
condition = SDL_malloc(sizeof(FFCONDITION) * dest->cAxes);
|
||||
if (condition == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(condition, 0, sizeof(FFCONDITION));
|
||||
if (dest->cAxes > 0) {
|
||||
condition = SDL_malloc(sizeof(FFCONDITION) * dest->cAxes);
|
||||
if (condition == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(condition, 0, sizeof(FFCONDITION));
|
||||
|
||||
/* Specifics */
|
||||
for (i = 0; i < dest->cAxes; i++) {
|
||||
condition[i].lOffset = CONVERT(hap_condition->center[i]);
|
||||
condition[i].lPositiveCoefficient =
|
||||
CONVERT(hap_condition->right_coeff[i]);
|
||||
condition[i].lNegativeCoefficient =
|
||||
CONVERT(hap_condition->left_coeff[i]);
|
||||
condition[i].dwPositiveSaturation =
|
||||
CCONVERT(hap_condition->right_sat[i]);
|
||||
condition[i].dwNegativeSaturation =
|
||||
CCONVERT(hap_condition->left_sat[i]);
|
||||
condition[i].lDeadBand = CCONVERT(hap_condition->deadband[i]);
|
||||
/* Specifics */
|
||||
for (i = 0; i < dest->cAxes; i++) {
|
||||
condition[i].lOffset = CONVERT(hap_condition->center[i]);
|
||||
condition[i].lPositiveCoefficient =
|
||||
CONVERT(hap_condition->right_coeff[i]);
|
||||
condition[i].lNegativeCoefficient =
|
||||
CONVERT(hap_condition->left_coeff[i]);
|
||||
condition[i].dwPositiveSaturation =
|
||||
CCONVERT(hap_condition->right_sat[i] / 2);
|
||||
condition[i].dwNegativeSaturation =
|
||||
CCONVERT(hap_condition->left_sat[i] / 2);
|
||||
condition[i].lDeadBand = CCONVERT(hap_condition->deadband[i] / 2);
|
||||
}
|
||||
}
|
||||
|
||||
dest->cbTypeSpecificParams = sizeof(FFCONDITION) * dest->cAxes;
|
||||
dest->lpvTypeSpecificParams = condition;
|
||||
|
||||
|
|
@ -1269,8 +1276,7 @@ SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
|
|||
{
|
||||
HRESULT ret;
|
||||
|
||||
ret =
|
||||
FFDeviceReleaseEffect(haptic->hwdata->device, effect->hweffect->ref);
|
||||
ret = FFDeviceReleaseEffect(haptic->hwdata->device, effect->hweffect->ref);
|
||||
if (ret != FF_OK) {
|
||||
SDL_SetError("Haptic: Error removing the effect from the device: %s.",
|
||||
FFStrError(ret));
|
||||
|
|
@ -1299,8 +1305,9 @@ SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (status == 0)
|
||||
if (status == 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE; /* Assume it's playing or emulated. */
|
||||
}
|
||||
|
||||
|
|
@ -1315,9 +1322,8 @@ SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
|
|||
Uint32 val;
|
||||
|
||||
val = gain * 100; /* Mac OS X uses 0 to 10,000 */
|
||||
ret =
|
||||
FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
|
||||
FFPROP_FFGAIN, &val);
|
||||
ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
|
||||
FFPROP_FFGAIN, &val);
|
||||
if (ret != FF_OK) {
|
||||
return SDL_SetError("Haptic: Error setting gain: %s.", FFStrError(ret));
|
||||
}
|
||||
|
|
@ -1336,10 +1342,11 @@ SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
|
|||
Uint32 val;
|
||||
|
||||
/* Mac OS X only has 0 (off) and 1 (on) */
|
||||
if (autocenter == 0)
|
||||
if (autocenter == 0) {
|
||||
val = 0;
|
||||
else
|
||||
} else {
|
||||
val = 1;
|
||||
}
|
||||
|
||||
ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
|
||||
FFPROP_AUTOCENTER, &val);
|
||||
|
|
@ -1405,5 +1412,6 @@ SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* SDL_HAPTIC_IOKIT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
|
@ -182,3 +182,5 @@ SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
|
|||
}
|
||||
|
||||
#endif /* SDL_HAPTIC_DUMMY || SDL_HAPTIC_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
|
@ -59,6 +59,7 @@ typedef struct SDL_hapticlist_item
|
|||
{
|
||||
char *fname; /* Dev path name (like /dev/input/event1) */
|
||||
SDL_Haptic *haptic; /* Associated haptic. */
|
||||
dev_t dev_num;
|
||||
struct SDL_hapticlist_item *next;
|
||||
} SDL_hapticlist_item;
|
||||
|
||||
|
|
@ -236,15 +237,11 @@ void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const
|
|||
static int
|
||||
MaybeAddDevice(const char *path)
|
||||
{
|
||||
dev_t dev_nums[MAX_HAPTICS];
|
||||
struct stat sb;
|
||||
int fd;
|
||||
int k;
|
||||
int duplicate;
|
||||
int success;
|
||||
SDL_hapticlist_item *item;
|
||||
|
||||
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -255,15 +252,11 @@ MaybeAddDevice(const char *path)
|
|||
}
|
||||
|
||||
/* check for duplicates */
|
||||
duplicate = 0;
|
||||
for (k = 0; (k < numhaptics) && !duplicate; ++k) {
|
||||
if (sb.st_rdev == dev_nums[k]) {
|
||||
duplicate = 1;
|
||||
for (item = SDL_hapticlist; item != NULL; item = item->next) {
|
||||
if (item->dev_num == sb.st_rdev) {
|
||||
return -1; /* duplicate. */
|
||||
}
|
||||
}
|
||||
if (duplicate) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* try to open */
|
||||
fd = open(path, O_RDWR, 0);
|
||||
|
|
@ -288,12 +281,13 @@ MaybeAddDevice(const char *path)
|
|||
}
|
||||
|
||||
item->fname = SDL_strdup(path);
|
||||
if ( (item->fname == NULL) ) {
|
||||
SDL_free(item->fname);
|
||||
if (item->fname == NULL) {
|
||||
SDL_free(item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
item->dev_num = sb.st_rdev;
|
||||
|
||||
/* TODO: should we add instance IDs? */
|
||||
if (SDL_hapticlist_tail == NULL) {
|
||||
SDL_hapticlist = SDL_hapticlist_tail = item;
|
||||
|
|
@ -302,8 +296,6 @@ MaybeAddDevice(const char *path)
|
|||
SDL_hapticlist_tail = item;
|
||||
}
|
||||
|
||||
dev_nums[numhaptics] = sb.st_rdev;
|
||||
|
||||
++numhaptics;
|
||||
|
||||
/* !!! TODO: Send a haptic add event? */
|
||||
|
|
@ -391,8 +383,8 @@ SDL_SYS_HapticName(int index)
|
|||
/* No name found, return device character device */
|
||||
name = item->fname;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
|
@ -441,7 +433,7 @@ SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd)
|
|||
open_err:
|
||||
close(fd);
|
||||
if (haptic->hwdata != NULL) {
|
||||
free(haptic->hwdata);
|
||||
SDL_free(haptic->hwdata);
|
||||
haptic->hwdata = NULL;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -473,7 +465,7 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic)
|
|||
}
|
||||
|
||||
/* Set the fname. */
|
||||
haptic->hwdata->fname = item->fname;
|
||||
haptic->hwdata->fname = SDL_strdup( item->fname );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -547,15 +539,15 @@ SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
|||
int ret;
|
||||
SDL_hapticlist_item *item;
|
||||
|
||||
|
||||
/* Find the joystick in the haptic list. */
|
||||
for (item = SDL_hapticlist; item; item = item->next) {
|
||||
if (SDL_strcmp(item->fname, joystick->hwdata->fname) == 0) {
|
||||
haptic->index = device_index;
|
||||
break;
|
||||
}
|
||||
++device_index;
|
||||
}
|
||||
haptic->index = device_index;
|
||||
|
||||
if (device_index >= MAX_HAPTICS) {
|
||||
return SDL_SetError("Haptic: Joystick doesn't have Haptic capabilities");
|
||||
}
|
||||
|
|
@ -570,7 +562,8 @@ SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
|||
return -1;
|
||||
}
|
||||
|
||||
haptic->hwdata->fname = item->fname;
|
||||
haptic->hwdata->fname = SDL_strdup( joystick->hwdata->fname );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -592,6 +585,7 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic)
|
|||
close(haptic->hwdata->fd);
|
||||
|
||||
/* Free */
|
||||
SDL_free(haptic->hwdata->fname);
|
||||
SDL_free(haptic->hwdata);
|
||||
haptic->hwdata = NULL;
|
||||
}
|
||||
|
|
@ -624,6 +618,8 @@ SDL_SYS_HapticQuit(void)
|
|||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
numhaptics = 0;
|
||||
SDL_hapticlist = NULL;
|
||||
SDL_hapticlist_tail = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -650,15 +646,14 @@ SDL_SYS_ToButton(Uint16 button)
|
|||
|
||||
|
||||
/*
|
||||
* Returns the ff_effect usable direction from a SDL_HapticDirection.
|
||||
* Initializes the ff_effect usable direction from a SDL_HapticDirection.
|
||||
*/
|
||||
static Uint16
|
||||
SDL_SYS_ToDirection(SDL_HapticDirection * dir)
|
||||
static int
|
||||
SDL_SYS_ToDirection(Uint16 *dest, SDL_HapticDirection * src)
|
||||
{
|
||||
Uint32 tmp;
|
||||
float f; /* Ideally we'd use fixed point math instead of floats... */
|
||||
|
||||
switch (dir->type) {
|
||||
switch (src->type) {
|
||||
case SDL_HAPTIC_POLAR:
|
||||
/* Linux directions start from south.
|
||||
(and range from 0 to 0xFFFF)
|
||||
|
|
@ -668,25 +663,34 @@ SDL_SYS_ToDirection(SDL_HapticDirection * dir)
|
|||
90 deg -> 0x4000 (left)
|
||||
180 deg -> 0x8000 (up)
|
||||
270 deg -> 0xC000 (right)
|
||||
The force pulls into the direction specified by Linux directions,
|
||||
i.e. the opposite convention of SDL directions.
|
||||
*/
|
||||
tmp = (((18000 + dir->dir[0]) % 36000) * 0xFFFF) / 36000; /* convert to range [0,0xFFFF] */
|
||||
return (Uint16) tmp;
|
||||
tmp = ((src->dir[0] % 36000) * 0x8000) / 18000; /* convert to range [0,0xFFFF] */
|
||||
*dest = (Uint16) tmp;
|
||||
break;
|
||||
|
||||
case SDL_HAPTIC_SPHERICAL:
|
||||
case SDL_HAPTIC_SPHERICAL:
|
||||
/*
|
||||
We convert to polar, because that's the only supported direction on Linux.
|
||||
The first value of a spherical direction is practically the same as a
|
||||
Polar direction, except that we have to add 90 degrees. It is the angle
|
||||
from EAST {1,0} towards SOUTH {0,1}.
|
||||
--> add 9000
|
||||
--> finally add 18000 and convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR.
|
||||
--> finally convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR.
|
||||
*/
|
||||
tmp = ((dir->dir[0]) + 9000) % 36000; /* Convert to polars */
|
||||
tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000; /* convert to range [0,0xFFFF] */
|
||||
return (Uint16) tmp;
|
||||
tmp = ((src->dir[0]) + 9000) % 36000; /* Convert to polars */
|
||||
tmp = (tmp * 0x8000) / 18000; /* convert to range [0,0xFFFF] */
|
||||
*dest = (Uint16) tmp;
|
||||
break;
|
||||
|
||||
case SDL_HAPTIC_CARTESIAN:
|
||||
f = atan2(dir->dir[1], dir->dir[0]);
|
||||
if (!src->dir[1])
|
||||
*dest = (src->dir[0] >= 0 ? 0x4000 : 0xC000);
|
||||
else if (!src->dir[0])
|
||||
*dest = (src->dir[1] >= 0 ? 0x8000 : 0);
|
||||
else {
|
||||
float f = atan2(src->dir[1], src->dir[0]); /* Ideally we'd use fixed point math instead of floats... */
|
||||
/*
|
||||
atan2 takes the parameters: Y-axis-value and X-axis-value (in that order)
|
||||
- Y-axis-value is the second coordinate (from center to SOUTH)
|
||||
|
|
@ -695,14 +699,16 @@ SDL_SYS_ToDirection(SDL_HapticDirection * dir)
|
|||
have the first spherical value. Therefore we proceed as in case
|
||||
SDL_HAPTIC_SPHERICAL and add another 9000 to get the polar value.
|
||||
--> add 45000 in total
|
||||
--> finally add 18000 and convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR.
|
||||
--> finally convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR.
|
||||
*/
|
||||
tmp = (((int) (f * 18000. / M_PI)) + 45000) % 36000;
|
||||
tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000; /* convert to range [0,0xFFFF] */
|
||||
return (Uint16) tmp;
|
||||
tmp = (((Sint32) (f * 18000. / M_PI)) + 45000) % 36000;
|
||||
tmp = (tmp * 0x8000) / 18000; /* convert to range [0,0xFFFF] */
|
||||
*dest = (Uint16) tmp;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return (Uint16) SDL_SetError("Haptic: Unsupported direction type.");
|
||||
return SDL_SetError("Haptic: Unsupported direction type.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -717,7 +723,6 @@ SDL_SYS_ToDirection(SDL_HapticDirection * dir)
|
|||
static int
|
||||
SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
|
||||
{
|
||||
Uint32 tmp;
|
||||
SDL_HapticConstant *constant;
|
||||
SDL_HapticPeriodic *periodic;
|
||||
SDL_HapticCondition *condition;
|
||||
|
|
@ -733,8 +738,7 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
|
|||
|
||||
/* Header */
|
||||
dest->type = FF_CONSTANT;
|
||||
dest->direction = SDL_SYS_ToDirection(&constant->direction);
|
||||
if (dest->direction == (Uint16) - 1)
|
||||
if (SDL_SYS_ToDirection(&dest->direction, &constant->direction) == -1)
|
||||
return -1;
|
||||
|
||||
/* Replay */
|
||||
|
|
@ -769,8 +773,7 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
|
|||
|
||||
/* Header */
|
||||
dest->type = FF_PERIODIC;
|
||||
dest->direction = SDL_SYS_ToDirection(&periodic->direction);
|
||||
if (dest->direction == (Uint16) - 1)
|
||||
if (SDL_SYS_ToDirection(&dest->direction, &periodic->direction) == -1)
|
||||
return -1;
|
||||
|
||||
/* Replay */
|
||||
|
|
@ -797,9 +800,8 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
|
|||
dest->u.periodic.period = CLAMP(periodic->period);
|
||||
dest->u.periodic.magnitude = periodic->magnitude;
|
||||
dest->u.periodic.offset = periodic->offset;
|
||||
/* Phase is calculated based of offset from period and then clamped. */
|
||||
tmp = ((periodic->phase % 36000) * dest->u.periodic.period) / 36000;
|
||||
dest->u.periodic.phase = CLAMP(tmp);
|
||||
/* Linux phase is defined in interval "[0x0000, 0x10000[", corresponds with "[0deg, 360deg[" phase shift. */
|
||||
dest->u.periodic.phase = ((Uint32)periodic->phase * 0x10000U) / 36000;
|
||||
|
||||
/* Envelope */
|
||||
dest->u.periodic.envelope.attack_length =
|
||||
|
|
@ -839,20 +841,18 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
|
|||
|
||||
/* Condition */
|
||||
/* X axis */
|
||||
dest->u.condition[0].right_saturation =
|
||||
CLAMP(condition->right_sat[0]);
|
||||
dest->u.condition[0].left_saturation = CLAMP(condition->left_sat[0]);
|
||||
dest->u.condition[0].right_saturation = condition->right_sat[0];
|
||||
dest->u.condition[0].left_saturation = condition->left_sat[0];
|
||||
dest->u.condition[0].right_coeff = condition->right_coeff[0];
|
||||
dest->u.condition[0].left_coeff = condition->left_coeff[0];
|
||||
dest->u.condition[0].deadband = CLAMP(condition->deadband[0]);
|
||||
dest->u.condition[0].deadband = condition->deadband[0];
|
||||
dest->u.condition[0].center = condition->center[0];
|
||||
/* Y axis */
|
||||
dest->u.condition[1].right_saturation =
|
||||
CLAMP(condition->right_sat[1]);
|
||||
dest->u.condition[1].left_saturation = CLAMP(condition->left_sat[1]);
|
||||
dest->u.condition[1].right_saturation = condition->right_sat[1];
|
||||
dest->u.condition[1].left_saturation = condition->left_sat[1];
|
||||
dest->u.condition[1].right_coeff = condition->right_coeff[1];
|
||||
dest->u.condition[1].left_coeff = condition->left_coeff[1];
|
||||
dest->u.condition[1].deadband = CLAMP(condition->deadband[1]);
|
||||
dest->u.condition[1].deadband = condition->deadband[1];
|
||||
dest->u.condition[1].center = condition->center[1];
|
||||
|
||||
/*
|
||||
|
|
@ -866,8 +866,7 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
|
|||
|
||||
/* Header */
|
||||
dest->type = FF_RAMP;
|
||||
dest->direction = SDL_SYS_ToDirection(&ramp->direction);
|
||||
if (dest->direction == (Uint16) - 1)
|
||||
if (SDL_SYS_ToDirection(&dest->direction, &ramp->direction) == -1)
|
||||
return -1;
|
||||
|
||||
/* Replay */
|
||||
|
|
@ -954,7 +953,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
|
|||
return 0;
|
||||
|
||||
new_effect_err:
|
||||
free(effect->hweffect);
|
||||
SDL_free(effect->hweffect);
|
||||
effect->hweffect = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1158,5 +1157,6 @@ SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* SDL_HAPTIC_LINUX */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
47
Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic_c.h
Normal file
47
Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic_c.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
#include "SDL_haptic.h"
|
||||
#include "SDL_windowshaptic_c.h"
|
||||
|
||||
|
||||
extern int SDL_DINPUT_HapticInit(void);
|
||||
extern int SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||
extern int SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||
extern int SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item);
|
||||
extern int SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick);
|
||||
extern int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick);
|
||||
extern void SDL_DINPUT_HapticClose(SDL_Haptic * haptic);
|
||||
extern void SDL_DINPUT_HapticQuit(void);
|
||||
extern int SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base);
|
||||
extern int SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data);
|
||||
extern int SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations);
|
||||
extern int SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect);
|
||||
extern void SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect);
|
||||
extern int SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect);
|
||||
extern int SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain);
|
||||
extern int SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter);
|
||||
extern int SDL_DINPUT_HapticPause(SDL_Haptic * haptic);
|
||||
extern int SDL_DINPUT_HapticUnpause(SDL_Haptic * haptic);
|
||||
extern int SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic);
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 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.
|
||||
*/
|
||||
|
||||
extern int DirectInputHaptic_MaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||
extern int DirectInputHaptic_MaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||
extern int XInputHaptic_MaybeAddDevice(const DWORD dwUserid);
|
||||
extern int XInputHaptic_MaybeRemoveDevice(const DWORD dwUserid);
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
449
Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c
Normal file
449
Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c
Normal file
|
|
@ -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: */
|
||||
88
Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h
Normal file
88
Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
#ifndef _SDL_windowshaptic_c_h
|
||||
#define _SDL_windowshaptic_c_h
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_syshaptic.h"
|
||||
#include "../../core/windows/SDL_directx.h"
|
||||
#include "../../core/windows/SDL_xinput.h"
|
||||
|
||||
/*
|
||||
* Haptic system hardware data.
|
||||
*/
|
||||
struct haptic_hwdata
|
||||
{
|
||||
#if SDL_HAPTIC_DINPUT
|
||||
LPDIRECTINPUTDEVICE8 device;
|
||||
#endif
|
||||
DWORD axes[3]; /* Axes to use. */
|
||||
SDL_bool is_joystick; /* Device is loaded as joystick. */
|
||||
Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
|
||||
Uint8 userid; /* XInput userid index for this joystick */
|
||||
SDL_Thread *thread;
|
||||
SDL_mutex *mutex;
|
||||
volatile Uint32 stopTicks;
|
||||
volatile int stopThread;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Haptic system effect data.
|
||||
*/
|
||||
struct haptic_hweffect
|
||||
{
|
||||
#if SDL_HAPTIC_DINPUT
|
||||
DIEFFECT effect;
|
||||
LPDIRECTINPUTEFFECT ref;
|
||||
#endif
|
||||
#if SDL_HAPTIC_XINPUT
|
||||
XINPUT_VIBRATION vibration;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* List of available haptic devices.
|
||||
*/
|
||||
typedef struct SDL_hapticlist_item
|
||||
{
|
||||
char *name;
|
||||
SDL_Haptic *haptic;
|
||||
#if SDL_HAPTIC_DINPUT
|
||||
DIDEVICEINSTANCE instance;
|
||||
DIDEVCAPS capabilities;
|
||||
#endif
|
||||
SDL_bool bXInputHaptic; /* Supports force feedback via XInput. */
|
||||
Uint8 userid; /* XInput userid index for this joystick */
|
||||
struct SDL_hapticlist_item *next;
|
||||
} SDL_hapticlist_item;
|
||||
|
||||
extern SDL_hapticlist_item *SDL_hapticlist;
|
||||
|
||||
extern int SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item);
|
||||
extern int SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item);
|
||||
|
||||
#endif /* _SDL_windowshaptic_c_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
495
Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c
Normal file
495
Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c
Normal file
|
|
@ -0,0 +1,495 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_haptic.h"
|
||||
#include "../SDL_syshaptic.h"
|
||||
|
||||
#if SDL_HAPTIC_XINPUT
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_windowshaptic_c.h"
|
||||
#include "SDL_xinputhaptic_c.h"
|
||||
#include "../../core/windows/SDL_xinput.h"
|
||||
#include "../../joystick/windows/SDL_windowsjoystick_c.h"
|
||||
|
||||
/*
|
||||
* Internal stuff.
|
||||
*/
|
||||
static SDL_bool loaded_xinput = SDL_FALSE;
|
||||
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticInit(void)
|
||||
{
|
||||
const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED);
|
||||
if (!env || SDL_atoi(env)) {
|
||||
loaded_xinput = (WIN_LoadXInputDLL() == 0);
|
||||
}
|
||||
|
||||
if (loaded_xinput) {
|
||||
DWORD i;
|
||||
for (i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||
SDL_XINPUT_MaybeAddDevice(i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid)
|
||||
{
|
||||
const Uint8 userid = (Uint8)dwUserid;
|
||||
SDL_hapticlist_item *item;
|
||||
XINPUT_VIBRATION state;
|
||||
|
||||
if ((!loaded_xinput) || (dwUserid >= XUSER_MAX_COUNT)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make sure we don't already have it */
|
||||
for (item = SDL_hapticlist; item; item = item->next) {
|
||||
if (item->bXInputHaptic && item->userid == userid) {
|
||||
return -1; /* Already added */
|
||||
}
|
||||
}
|
||||
|
||||
SDL_zero(state);
|
||||
if (XINPUTSETSTATE(dwUserid, &state) != ERROR_SUCCESS) {
|
||||
return -1; /* no force feedback on this device. */
|
||||
}
|
||||
|
||||
item = (SDL_hapticlist_item *)SDL_malloc(sizeof(SDL_hapticlist_item));
|
||||
if (item == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
SDL_zerop(item);
|
||||
|
||||
/* !!! FIXME: I'm not bothering to query for a real name right now (can we even?) */
|
||||
{
|
||||
char buf[64];
|
||||
SDL_snprintf(buf, sizeof(buf), "XInput Controller #%u", (unsigned int)(userid + 1));
|
||||
item->name = SDL_strdup(buf);
|
||||
}
|
||||
|
||||
if (!item->name) {
|
||||
SDL_free(item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy the instance over, useful for creating devices. */
|
||||
item->bXInputHaptic = SDL_TRUE;
|
||||
item->userid = userid;
|
||||
|
||||
return SDL_SYS_AddHapticDevice(item);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid)
|
||||
{
|
||||
const Uint8 userid = (Uint8)dwUserid;
|
||||
SDL_hapticlist_item *item;
|
||||
SDL_hapticlist_item *prev = NULL;
|
||||
|
||||
if ((!loaded_xinput) || (dwUserid >= XUSER_MAX_COUNT)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (item = SDL_hapticlist; item != NULL; item = item->next) {
|
||||
if (item->bXInputHaptic && item->userid == userid) {
|
||||
/* found it, remove it. */
|
||||
return SDL_SYS_RemoveHapticDevice(prev, item);
|
||||
}
|
||||
prev = item;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* !!! FIXME: this is a hack, remove this later. */
|
||||
/* Since XInput doesn't offer a way to vibrate for X time, we hook into
|
||||
* SDL_PumpEvents() to check if it's time to stop vibrating with some
|
||||
* frequency.
|
||||
* In practice, this works for 99% of use cases. But in an ideal world,
|
||||
* we do this in a separate thread so that:
|
||||
* - we aren't bound to when the app chooses to pump the event queue.
|
||||
* - we aren't adding more polling to the event queue
|
||||
* - we can emulate all the haptic effects correctly (start on a delay,
|
||||
* mix multiple effects, etc).
|
||||
*
|
||||
* Mostly, this is here to get rumbling to work, and all the other features
|
||||
* are absent in the XInput path for now. :(
|
||||
*/
|
||||
static int SDLCALL
|
||||
SDL_RunXInputHaptic(void *arg)
|
||||
{
|
||||
struct haptic_hwdata *hwdata = (struct haptic_hwdata *) arg;
|
||||
|
||||
while (!hwdata->stopThread) {
|
||||
SDL_Delay(50);
|
||||
SDL_LockMutex(hwdata->mutex);
|
||||
/* If we're currently running and need to stop... */
|
||||
if (hwdata->stopTicks) {
|
||||
if ((hwdata->stopTicks != SDL_HAPTIC_INFINITY) && SDL_TICKS_PASSED(SDL_GetTicks(), hwdata->stopTicks)) {
|
||||
XINPUT_VIBRATION vibration = { 0, 0 };
|
||||
hwdata->stopTicks = 0;
|
||||
XINPUTSETSTATE(hwdata->userid, &vibration);
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(hwdata->mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid)
|
||||
{
|
||||
char threadName[32];
|
||||
XINPUT_VIBRATION vibration = { 0, 0 }; /* stop any current vibration */
|
||||
XINPUTSETSTATE(userid, &vibration);
|
||||
|
||||
haptic->supported = SDL_HAPTIC_LEFTRIGHT;
|
||||
|
||||
haptic->neffects = 1;
|
||||
haptic->nplaying = 1;
|
||||
|
||||
/* Prepare effects memory. */
|
||||
haptic->effects = (struct haptic_effect *)
|
||||
SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
|
||||
if (haptic->effects == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
/* Clear the memory */
|
||||
SDL_memset(haptic->effects, 0,
|
||||
sizeof(struct haptic_effect) * haptic->neffects);
|
||||
|
||||
haptic->hwdata = (struct haptic_hwdata *) SDL_malloc(sizeof(*haptic->hwdata));
|
||||
if (haptic->hwdata == NULL) {
|
||||
SDL_free(haptic->effects);
|
||||
haptic->effects = NULL;
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
|
||||
|
||||
haptic->hwdata->bXInputHaptic = 1;
|
||||
haptic->hwdata->userid = userid;
|
||||
|
||||
haptic->hwdata->mutex = SDL_CreateMutex();
|
||||
if (haptic->hwdata->mutex == NULL) {
|
||||
SDL_free(haptic->effects);
|
||||
SDL_free(haptic->hwdata);
|
||||
haptic->effects = NULL;
|
||||
return SDL_SetError("Couldn't create XInput haptic mutex");
|
||||
}
|
||||
|
||||
SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%d", (int)userid);
|
||||
|
||||
#if defined(__WIN32__) && !defined(HAVE_LIBC) /* !!! FIXME: this is nasty. */
|
||||
#undef SDL_CreateThread
|
||||
#if SDL_DYNAMIC_API
|
||||
haptic->hwdata->thread = SDL_CreateThread_REAL(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
|
||||
#else
|
||||
haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
|
||||
#endif
|
||||
#else
|
||||
haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata);
|
||||
#endif
|
||||
if (haptic->hwdata->thread == NULL) {
|
||||
SDL_DestroyMutex(haptic->hwdata->mutex);
|
||||
SDL_free(haptic->effects);
|
||||
SDL_free(haptic->hwdata);
|
||||
haptic->effects = NULL;
|
||||
return SDL_SetError("Couldn't create XInput haptic thread");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
|
||||
{
|
||||
return SDL_XINPUT_HapticOpenFromUserIndex(haptic, item->userid);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
||||
{
|
||||
return (haptic->hwdata->userid == joystick->hwdata->userid);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
||||
{
|
||||
SDL_hapticlist_item *item;
|
||||
int index = 0;
|
||||
|
||||
/* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
|
||||
for (item = SDL_hapticlist; item != NULL; item = item->next) {
|
||||
if (item->bXInputHaptic && item->userid == joystick->hwdata->userid) {
|
||||
haptic->index = index;
|
||||
return SDL_XINPUT_HapticOpenFromUserIndex(haptic, joystick->hwdata->userid);
|
||||
}
|
||||
++index;
|
||||
}
|
||||
|
||||
SDL_SetError("Couldn't find joystick in haptic device list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_XINPUT_HapticClose(SDL_Haptic * haptic)
|
||||
{
|
||||
haptic->hwdata->stopThread = 1;
|
||||
SDL_WaitThread(haptic->hwdata->thread, NULL);
|
||||
SDL_DestroyMutex(haptic->hwdata->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_XINPUT_HapticQuit(void)
|
||||
{
|
||||
if (loaded_xinput) {
|
||||
WIN_UnloadXInputDLL();
|
||||
loaded_xinput = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base)
|
||||
{
|
||||
SDL_assert(base->type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */
|
||||
return SDL_XINPUT_HapticUpdateEffect(haptic, effect, base);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data)
|
||||
{
|
||||
XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
|
||||
SDL_assert(data->type == SDL_HAPTIC_LEFTRIGHT);
|
||||
vib->wLeftMotorSpeed = data->leftright.large_magnitude;
|
||||
vib->wRightMotorSpeed = data->leftright.small_magnitude;
|
||||
SDL_LockMutex(haptic->hwdata->mutex);
|
||||
if (haptic->hwdata->stopTicks) { /* running right now? Update it. */
|
||||
XINPUTSETSTATE(haptic->hwdata->userid, vib);
|
||||
}
|
||||
SDL_UnlockMutex(haptic->hwdata->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations)
|
||||
{
|
||||
XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
|
||||
SDL_assert(effect->effect.type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */
|
||||
SDL_LockMutex(haptic->hwdata->mutex);
|
||||
if (effect->effect.leftright.length == SDL_HAPTIC_INFINITY || iterations == SDL_HAPTIC_INFINITY) {
|
||||
haptic->hwdata->stopTicks = SDL_HAPTIC_INFINITY;
|
||||
} else if ((!effect->effect.leftright.length) || (!iterations)) {
|
||||
/* do nothing. Effect runs for zero milliseconds. */
|
||||
} else {
|
||||
haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.leftright.length * iterations);
|
||||
if ((haptic->hwdata->stopTicks == SDL_HAPTIC_INFINITY) || (haptic->hwdata->stopTicks == 0)) {
|
||||
haptic->hwdata->stopTicks = 1; /* fix edge cases. */
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(haptic->hwdata->mutex);
|
||||
return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
|
||||
{
|
||||
XINPUT_VIBRATION vibration = { 0, 0 };
|
||||
SDL_LockMutex(haptic->hwdata->mutex);
|
||||
haptic->hwdata->stopTicks = 0;
|
||||
SDL_UnlockMutex(haptic->hwdata->mutex);
|
||||
return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_XINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
|
||||
{
|
||||
SDL_XINPUT_HapticStopEffect(haptic, effect);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticSetGain(SDL_Haptic * haptic, int gain)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticPause(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticUnpause(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic)
|
||||
{
|
||||
XINPUT_VIBRATION vibration = { 0, 0 };
|
||||
SDL_LockMutex(haptic->hwdata->mutex);
|
||||
haptic->hwdata->stopTicks = 0;
|
||||
SDL_UnlockMutex(haptic->hwdata->mutex);
|
||||
return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
#else /* !SDL_HAPTIC_XINPUT */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
typedef struct SDL_hapticlist_item SDL_hapticlist_item;
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
void
|
||||
SDL_XINPUT_HapticClose(SDL_Haptic * haptic)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SDL_XINPUT_HapticQuit(void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
void
|
||||
SDL_XINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticSetGain(SDL_Haptic * haptic, int gain)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticPause(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticUnpause(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
#endif /* SDL_HAPTIC_XINPUT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
47
Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic_c.h
Normal file
47
Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic_c.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
#include "SDL_haptic.h"
|
||||
#include "SDL_windowshaptic_c.h"
|
||||
|
||||
|
||||
extern int SDL_XINPUT_HapticInit(void);
|
||||
extern int SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid);
|
||||
extern int SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid);
|
||||
extern int SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item);
|
||||
extern int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick);
|
||||
extern int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick);
|
||||
extern void SDL_XINPUT_HapticClose(SDL_Haptic * haptic);
|
||||
extern void SDL_XINPUT_HapticQuit(void);
|
||||
extern int SDL_XINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base);
|
||||
extern int SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data);
|
||||
extern int SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations);
|
||||
extern int SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect);
|
||||
extern void SDL_XINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect);
|
||||
extern int SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect);
|
||||
extern int SDL_XINPUT_HapticSetGain(SDL_Haptic * haptic, int gain);
|
||||
extern int SDL_XINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter);
|
||||
extern int SDL_XINPUT_HapticPause(SDL_Haptic * haptic);
|
||||
extern int SDL_XINPUT_HapticUnpause(SDL_Haptic * haptic);
|
||||
extern int SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic);
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
Loading…
Add table
Add a link
Reference in a new issue