Skip to content

Commit

Permalink
XInput vibrate support
Browse files Browse the repository at this point in the history
  • Loading branch information
jarveson authored and Nekotekina committed May 4, 2017
1 parent 6bb32e4 commit b9ebf59
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
29 changes: 25 additions & 4 deletions rpcs3/XInputPadHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace {
}
}

XInputPadHandler::XInputPadHandler() : active(false), thread(nullptr), library(nullptr), xinputGetState(nullptr), xinputEnable(nullptr)
XInputPadHandler::XInputPadHandler() : active(false), thread(nullptr), library(nullptr), xinputGetState(nullptr), xinputEnable(nullptr), xinputSetState(nullptr)
{
}

Expand All @@ -45,8 +45,10 @@ void XInputPadHandler::Init(const u32 max_connect)
{
xinputGetState = reinterpret_cast<PFN_XINPUTGETSTATE>(GetProcAddress(library, "XInputGetState"));
}

xinputSetState = reinterpret_cast<PFN_XINPUTSETSTATE>(GetProcAddress(library, "XInputSetState"));

if (xinputEnable && xinputGetState)
if (xinputEnable && xinputGetState && xinputSetState)
{
break;
}
Expand All @@ -68,7 +70,7 @@ void XInputPadHandler::Init(const u32 max_connect)
m_pads.emplace_back(
CELL_PAD_STATUS_DISCONNECTED,
CELL_PAD_SETTING_PRESS_OFF | CELL_PAD_SETTING_SENSOR_OFF,
CELL_PAD_CAPABILITY_PS3_CONFORMITY | CELL_PAD_CAPABILITY_PRESS_MODE,
CELL_PAD_CAPABILITY_PS3_CONFORMITY | CELL_PAD_CAPABILITY_PRESS_MODE | CELL_PAD_CAPABILITY_ACTUATOR,
CELL_PAD_DEV_TYPE_STANDARD
);
auto & pad = m_pads.back();
Expand Down Expand Up @@ -96,13 +98,24 @@ void XInputPadHandler::Init(const u32 max_connect)
pad.m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y, 0, 0);
pad.m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X, 0, 0);
pad.m_sticks.emplace_back(CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y, 0, 0);

pad.m_vibrateMotors.emplace_back(true, 0);
pad.m_vibrateMotors.emplace_back(false, 0);
}

active = true;
thread = CreateThread(NULL, 0, &XInputPadHandler::ThreadProcProxy, this, 0, NULL);
}
}

void XInputPadHandler::SetRumble(const u32 pad, u8 largeMotor, bool smallMotor) {
if (pad > m_pads.size())
return;

m_pads[pad].m_vibrateMotors[0].m_value = largeMotor;
m_pads[pad].m_vibrateMotors[1].m_value = smallMotor ? 255 : 0;
}

void XInputPadHandler::Close()
{
if (library)
Expand Down Expand Up @@ -172,12 +185,20 @@ DWORD XInputPadHandler::ThreadProcedure()
pad.m_sticks[1].m_value = 255 - ConvertAxis(state.Gamepad.sThumbLY);
pad.m_sticks[2].m_value = ConvertAxis(state.Gamepad.sThumbRX);
pad.m_sticks[3].m_value = 255 - ConvertAxis(state.Gamepad.sThumbRY);

XINPUT_VIBRATION vibrate;

vibrate.wLeftMotorSpeed = pad.m_vibrateMotors[0].m_value * 257;
vibrate.wRightMotorSpeed = pad.m_vibrateMotors[1].m_value * 257;

(*xinputSetState)(i, &vibrate);

break;
}
}

Sleep((online > 0) ? THREAD_SLEEP : THREAD_SLEEP_INACTIVE);
m_info.now_connect = online;
Sleep((online > 0) ? THREAD_SLEEP : THREAD_SLEEP_INACTIVE);
}

return 0;
Expand Down
3 changes: 3 additions & 0 deletions rpcs3/XInputPadHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ class XInputPadHandler final : public PadHandlerBase
~XInputPadHandler();

void Init(const u32 max_connect) override;
void SetRumble(const u32 pad, u8 largeMotor, bool smallMotor) override;
void Close();

private:
typedef void (WINAPI * PFN_XINPUTENABLE)(BOOL);
typedef DWORD (WINAPI * PFN_XINPUTGETSTATE)(DWORD, XINPUT_STATE *);
typedef DWORD (WINAPI * PFN_XINPUTSETSTATE)(DWORD, XINPUT_VIBRATION *);

private:
DWORD ThreadProcedure();
Expand All @@ -25,6 +27,7 @@ class XInputPadHandler final : public PadHandlerBase
HANDLE thread;
HMODULE library;
PFN_XINPUTGETSTATE xinputGetState;
PFN_XINPUTSETSTATE xinputSetState;
PFN_XINPUTENABLE xinputEnable;

};

0 comments on commit b9ebf59

Please sign in to comment.