mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-02-20 19:40:39 +00:00
Merge pull request #310 from pinumbernumber/master
Add rumble support to XInput driver
This commit is contained in:
commit
54d0fabbd7
@ -65,6 +65,12 @@ typedef struct
|
|||||||
XINPUT_GAMEPAD Gamepad;
|
XINPUT_GAMEPAD Gamepad;
|
||||||
} XINPUT_STATE;
|
} XINPUT_STATE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t wLeftMotorSpeed;
|
||||||
|
uint16_t wRightMotorSpeed;
|
||||||
|
} XINPUT_VIBRATION;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Guide constant is not officially documented
|
// Guide constant is not officially documented
|
||||||
@ -93,6 +99,9 @@ static HINSTANCE g_winxinput_dll;
|
|||||||
typedef uint32_t (__stdcall *XInputGetStateEx_t)(uint32_t, XINPUT_STATE*);
|
typedef uint32_t (__stdcall *XInputGetStateEx_t)(uint32_t, XINPUT_STATE*);
|
||||||
static XInputGetStateEx_t g_XInputGetStateEx;
|
static XInputGetStateEx_t g_XInputGetStateEx;
|
||||||
|
|
||||||
|
typedef uint32_t (__stdcall *XInputSetState_t)(uint32_t, XINPUT_VIBRATION*);
|
||||||
|
static XInputSetState_t g_XInputSetState;
|
||||||
|
|
||||||
// Guide button may or may not be available
|
// Guide button may or may not be available
|
||||||
static bool g_winxinput_guide_button_supported;
|
static bool g_winxinput_guide_button_supported;
|
||||||
|
|
||||||
@ -102,6 +111,8 @@ typedef struct
|
|||||||
bool connected;
|
bool connected;
|
||||||
} winxinput_joypad_state;
|
} winxinput_joypad_state;
|
||||||
|
|
||||||
|
static XINPUT_VIBRATION g_xinput_rumble_states[4];
|
||||||
|
|
||||||
static winxinput_joypad_state g_winxinput_states[4];
|
static winxinput_joypad_state g_winxinput_states[4];
|
||||||
|
|
||||||
static inline int pad_index_to_xplayer_index(unsigned pad)
|
static inline int pad_index_to_xplayer_index(unsigned pad)
|
||||||
@ -174,12 +185,21 @@ static bool winxinput_joypad_init(void)
|
|||||||
g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState");
|
g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState");
|
||||||
if (!g_XInputGetStateEx)
|
if (!g_XInputGetStateEx)
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to init XInput: xinput1_3.dll is invalid or corrupt.\n");
|
RARCH_ERR("Failed to init XInput: DLL is invalid or corrupt.\n");
|
||||||
|
FreeLibrary(g_winxinput_dll);
|
||||||
return false; // DLL was loaded but did not contain the correct function.
|
return false; // DLL was loaded but did not contain the correct function.
|
||||||
}
|
}
|
||||||
RARCH_WARN("XInput: No guide button support.\n");
|
RARCH_WARN("XInput: No guide button support.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_XInputSetState = (XInputSetState_t) GetProcAddress(g_winxinput_dll, "XInputSetState");
|
||||||
|
if (!g_XInputSetState)
|
||||||
|
{
|
||||||
|
RARCH_ERR("Failed to init XInput: DLL is invalid or corrupt.\n");
|
||||||
|
FreeLibrary(g_winxinput_dll);
|
||||||
|
return false; // DLL was loaded but did not contain the correct function.
|
||||||
|
}
|
||||||
|
|
||||||
// Zero out the states
|
// Zero out the states
|
||||||
for (unsigned i = 0; i < 4; ++i)
|
for (unsigned i = 0; i < 4; ++i)
|
||||||
memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state));
|
memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state));
|
||||||
@ -364,6 +384,27 @@ static void winxinput_joypad_poll(void)
|
|||||||
dinput_joypad.poll();
|
dinput_joypad.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool winxinput_joypad_rumble(unsigned pad, enum retro_rumble_effect effect, uint16_t strength)
|
||||||
|
{
|
||||||
|
int xplayer = pad_index_to_xplayer_index(pad);
|
||||||
|
if (xplayer == -1)
|
||||||
|
{
|
||||||
|
if (dinput_joypad.set_rumble)
|
||||||
|
return dinput_joypad.set_rumble(pad, effect, strength);.
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Consider the low frequency (left) motor the "strong" one.
|
||||||
|
if (effect == RETRO_RUMBLE_STRONG)
|
||||||
|
g_xinput_rumble_states[xplayer].wLeftMotorSpeed = strength;
|
||||||
|
else if (effect == RETRO_RUMBLE_WEAK)
|
||||||
|
g_xinput_rumble_states[xplayer].wRightMotorSpeed = strength;
|
||||||
|
|
||||||
|
return g_XInputSetState(xplayer, &g_xinput_rumble_states[xplayer]) == ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
const rarch_joypad_driver_t winxinput_joypad = {
|
const rarch_joypad_driver_t winxinput_joypad = {
|
||||||
winxinput_joypad_init,
|
winxinput_joypad_init,
|
||||||
winxinput_joypad_query_pad,
|
winxinput_joypad_query_pad,
|
||||||
@ -371,7 +412,7 @@ const rarch_joypad_driver_t winxinput_joypad = {
|
|||||||
winxinput_joypad_button,
|
winxinput_joypad_button,
|
||||||
winxinput_joypad_axis,
|
winxinput_joypad_axis,
|
||||||
winxinput_joypad_poll,
|
winxinput_joypad_poll,
|
||||||
NULL, // FIXME: Add rumble.
|
winxinput_joypad_rumble,
|
||||||
winxinput_joypad_name,
|
winxinput_joypad_name,
|
||||||
"winxinput",
|
"winxinput",
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user