add windows gamepad rumble implementation

This commit is contained in:
Nikita 2020-04-12 11:26:14 -04:00
parent e65de2941c
commit a630f36d00
6 changed files with 78 additions and 0 deletions

View File

@ -5348,6 +5348,37 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
*/
GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
/*! @brief Sets the specified gamepad's vibration effect intensity.
*
* This function sends vibration data to the specified Xbox-like gamepad.
*
* Vibration intensity is a value between 0.0 and 1.0 inclusive, where 0.0 is no
* vibration, and 1.0 is maximum vibration. It is set separately for the
* gamepad's low frequency and high frequency rumble motors.
*
* If the specified gamepad is not present or does not support the rumble
* effect, this function will return `GLFW_FALSE` but will not generate an
* error.
*
* @param[in] jid The [joystick](@ref joysticks) to vibrate.
* @param[in] slowMotorSpeed The low frequency rumble intensity.
* @param[in] fastMotorSpeed The high frequency rumble intensity.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is
* connected, or the joystick does not support the rumble effect.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_INVALID_ENUM.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref gamepad
* @sa @ref glfwUpdateGamepadMappings
* @sa @ref glfwJoystickIsGamepad
*
* @ingroup input
*/
GLFWAPI int glfwSetGamepadRumble(int jid, float slowMotorSpeed, float fastMotorSpeed);
/*! @brief Sets the clipboard to the specified string.
*
* This function sets the system clipboard to the specified, UTF-8 encoded

View File

@ -1312,6 +1312,34 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
return GLFW_TRUE;
}
GLFWAPI int glfwSetGamepadRumble(int jid, float slowMotorSpeed, float fastMotorSpeed)
{
_GLFWjoystick* js;
assert(jid >= GLFW_JOYSTICK_1);
assert(jid <= GLFW_JOYSTICK_LAST);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
return GLFW_FALSE;
}
js = _glfw.joysticks + jid;
if (!js->present)
return GLFW_FALSE;
slowMotorSpeed = slowMotorSpeed < 0.0f ? 0.0f : slowMotorSpeed;
slowMotorSpeed = slowMotorSpeed > 1.0f ? 1.0f : slowMotorSpeed;
fastMotorSpeed = fastMotorSpeed < 0.0f ? 0.0f : fastMotorSpeed;
fastMotorSpeed = fastMotorSpeed > 1.0f ? 1.0f : fastMotorSpeed;
return _glfwPlatformSetGamepadRumble(js, slowMotorSpeed, fastMotorSpeed);
}
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
{
assert(string != NULL);

View File

@ -628,6 +628,7 @@ const char* _glfwPlatformGetClipboardString(void);
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
void _glfwPlatformUpdateGamepadGUID(char* guid);
int _glfwPlatformSetGamepadRumble(_GLFWjoystick* js, float slowMotorSpeed, float fastMotorSpeed);
uint64_t _glfwPlatformGetTimerValue(void);
uint64_t _glfwPlatformGetTimerFrequency(void);

View File

@ -128,6 +128,8 @@ static GLFWbool loadLibraries(void)
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
_glfw.win32.xinput.GetState = (PFN_XInputGetState)
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
_glfw.win32.xinput.SetState = (PFN_XInputSetState)
GetProcAddress(_glfw.win32.xinput.instance, "XInputSetState");
break;
}

View File

@ -753,3 +753,16 @@ void _glfwPlatformUpdateGamepadGUID(char* guid)
}
}
int _glfwPlatformSetGamepadRumble(_GLFWjoystick* js, float slowMotorSpeed, float fastMotorSpeed)
{
if (js->win32.device)
return GLFW_FALSE;
XINPUT_VIBRATION effect;
ZeroMemory(&effect, sizeof(XINPUT_VIBRATION));
effect.wLeftMotorSpeed = (WORD)(65535.0f * slowMotorSpeed);
effect.wRightMotorSpeed = (WORD)(65535.0f * fastMotorSpeed);
return (int) (XInputSetState(js->win32.index, &effect) == ERROR_SUCCESS);
}

View File

@ -222,8 +222,10 @@ typedef DWORD (WINAPI * PFN_timeGetTime)(void);
// xinput.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
typedef DWORD (WINAPI * PFN_XInputSetState)(DWORD,XINPUT_VIBRATION*);
#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
#define XInputGetState _glfw.win32.xinput.GetState
#define XInputSetState _glfw.win32.xinput.SetState
// dinput8.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
@ -357,6 +359,7 @@ typedef struct _GLFWlibraryWin32
HINSTANCE instance;
PFN_XInputGetCapabilities GetCapabilities;
PFN_XInputGetState GetState;
PFN_XInputSetState SetState;
} xinput;
struct {