diff --git a/Source/Core/InputCommon/Src/XInput.cpp b/Source/Core/InputCommon/Src/XInput.cpp index 267bf4e714..3ba09c3aa2 100644 --- a/Source/Core/InputCommon/Src/XInput.cpp +++ b/Source/Core/InputCommon/Src/XInput.cpp @@ -97,17 +97,17 @@ int GetXI(int Controller, int Button) { // Update the internal status DWORD dwResult; - dwResult = XInputGetState( Controller, &g_Controllers[Controller].state ); + dwResult = XInputGetState(Controller, &g_Controllers[Controller].state); - if( dwResult != ERROR_SUCCESS ) return -1; + if (dwResult != ERROR_SUCCESS) return -1; - switch(Button) + switch (Button) { case InputCommon::XI_TRIGGER_L: - return g_Controllers[0].state.Gamepad.bLeftTrigger; + return g_Controllers[Controller].state.Gamepad.bLeftTrigger; case InputCommon::XI_TRIGGER_R: - return g_Controllers[0].state.Gamepad.bRightTrigger; + return g_Controllers[Controller].state.Gamepad.bRightTrigger; default: return 0; diff --git a/Source/Plugins/Plugin_GCpad/GCPad.cpp b/Source/Plugins/Plugin_GCpad/GCPad.cpp index ba52f6a51a..3ab5608310 100644 --- a/Source/Plugins/Plugin_GCpad/GCPad.cpp +++ b/Source/Plugins/Plugin_GCpad/GCPad.cpp @@ -23,6 +23,10 @@ #include "ConfigBox.h" #endif +#ifdef _WIN32 +#include "XInput.h" +#endif + // Declare config window so that we can write debugging info to it from functions in this file #if defined(HAVE_WX) && HAVE_WX GCPadConfigDialog* m_ConfigFrame = NULL; @@ -457,7 +461,15 @@ bool Search_Devices(std::vector &_joyinfo, int &_N { if (_NumPads > GCMapping[i].ID) if(joyinfo.at(GCMapping[i].ID).Good) + { GCMapping[i].joy = joyinfo.at(GCMapping[i].ID).joy; +#ifdef _WIN32 + XINPUT_STATE xstate; + DWORD xresult = XInputGetState(GCMapping[i].ID, &xstate); + if (xresult == ERROR_SUCCESS) + GCMapping[i].TriggerType = InputCommon::CTL_TRIGGER_XINPUT; +#endif + } } return Success; diff --git a/Source/Plugins/Plugin_GCpad/Rumble.cpp b/Source/Plugins/Plugin_GCpad/Rumble.cpp index e7863134fe..4118f4b5d5 100644 --- a/Source/Plugins/Plugin_GCpad/Rumble.cpp +++ b/Source/Plugins/Plugin_GCpad/Rumble.cpp @@ -18,6 +18,10 @@ #include "GCpad.h" +#ifdef _WIN32 +#include "XInput.h" +#endif + #ifdef RUMBLE_HACK @@ -35,57 +39,63 @@ BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContex BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext); void SetDeviceForcesXY(int pad, int nXYForce); HRESULT InitRumble(HWND hWnd); +void Rumble_DInput(int _ID, unsigned int _Strength); +void Rumble_XInput(int _ID, unsigned int _Strength); + LPDIRECTINPUT8 g_Rumble; // DInput Rumble object RUMBLE pRumble[4]; // 4 GC Rumble Pads -////////////////////// -// Use PAD rumble -// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ - -void Pad_Use_Rumble(u8 _numPAD) -{ - if (!g_Rumble) - { - // GetForegroundWindow() always sends the good HWND - if (FAILED(InitRumble(GetForegroundWindow()))) - PanicAlert("Could not initialize Rumble!"); - } else - { - // Acquire gamepad - if (pRumble[_numPAD].g_pDevice != NULL) - pRumble[_numPAD].g_pDevice->Acquire(); - } -} - -//////////////////////////////////////////////////// -// Set PAD rumble. Explanation: Stop = 0, Rumble = 1 -// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) { if (GCMapping[_numPAD].ID >= NumPads || !GCMapping[_numPAD].Rumble) return; - Pad_Use_Rumble(_numPAD); - - int Strenght = 0; - + unsigned int Strength = 0; if (_uType == 1 && _uStrength > 2) { - // it looks like _uStrength is equal to 3 everytime anyway... - Strenght = 1000 * GCMapping[_numPAD].RumbleStrength; - Strenght = Strenght > 10000 ? 10000 : Strenght; + Strength = 1000 * GCMapping[_numPAD].RumbleStrength; + Strength = Strength > 10000 ? 10000 : Strength; } - else - Strenght = 0; - SetDeviceForcesXY(_numPAD, Strenght); + if (GCMapping[_numPAD].TriggerType == InputCommon::CTL_TRIGGER_XINPUT) + Rumble_XInput(GCMapping[_numPAD].ID, Strength); + else + Rumble_DInput(GCMapping[_numPAD].ID, Strength); } -// Rumble stuff :D! -// ---------------- -// +//////////////////////////////////////////////////// +// Set rumble with XInput. +void Rumble_XInput(int _ID, unsigned int _Strength) +{ +#ifdef _WIN32 + XINPUT_VIBRATION vib; + vib.wLeftMotorSpeed = _Strength; + vib.wRightMotorSpeed = _Strength; + XInputSetState(_ID, &vib); +#endif +} + +//////////////////////////////////////////////////// +// Set rumble with DInput.ŻŻŻŻŻŻŻŻŻŻŻŻ +void Rumble_DInput(int _ID, unsigned int _Strength) +{ + if (!g_Rumble) + { + // GetForegroundWindow() always sends the good HWND + if (FAILED(InitRumble(GetForegroundWindow()))) + PanicAlert("Could not initialize Rumble!"); + } + else + { + // Acquire gamepad + if (pRumble[_ID].g_pDevice != NULL) + pRumble[_ID].g_pDevice->Acquire(); + } + + SetDeviceForcesXY(_ID, _Strength); +} HRESULT InitRumble(HWND hWnd) { @@ -238,8 +248,7 @@ BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContex { // a DInput device is created even if rumble is disabled on startup // this way, you can toggle the rumble setting while in game - //if (GCMapping[i].enabled) // && GCMapping[i].rumble - pRumble[i].g_pDevice = pDevice; // everything looks good, save the DInput device + pRumble[i].g_pDevice = pDevice; // everything looks good, save the DInput device } } @@ -257,13 +266,27 @@ BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pCont void PAD_RumbleClose() { - // It may look weird, but we don't free anything here, it was the cause of crashes - // on stop, and the DLL isn't unloaded anyway, so the pointers stay - // We just stop the rumble in case it's still playing an effect. - for (int i=0; i<4; i++) + for (int i = 0; i < 4; i++) { - if (pRumble[i].g_pDevice && pRumble[i].g_pEffect) - pRumble[i].g_pEffect->Stop(); + if (GCMapping[i].ID < NumPads) + if (GCMapping[i].TriggerType == InputCommon::CTL_TRIGGER_XINPUT) + { +#ifdef _WIN32 + // Kill Xpad rumble + XINPUT_VIBRATION vib; + vib.wLeftMotorSpeed = 0; + vib.wRightMotorSpeed = 0; + XInputSetState(GCMapping[i].ID, &vib); +#endif + } + else + { + // It may look weird, but we don't free anything here, it was the cause of crashes + // on stop, and the DLL isn't unloaded anyway, so the pointers stay + // We just stop the rumble in case it's still playing an effect. + if (pRumble[GCMapping[i].ID].g_pDevice && pRumble[GCMapping[i].ID].g_pEffect) + pRumble[GCMapping[i].ID].g_pEffect->Stop(); + } } } diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp index 6ab569e635..23629ec90b 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp @@ -35,6 +35,10 @@ #include "Encryption.h" // for extension encryption #include "Config.h" // for g_Config +#ifdef _WIN32 +#include "XInput.h" +#endif + extern SWiimoteInitialize g_WiimoteInitialize; namespace WiiMoteEmu @@ -87,9 +91,16 @@ bool Search_Devices(std::vector &_joyinfo, int &_N { if (_NumPads > WiiMapping[i].ID) if(_joyinfo.at(WiiMapping[i].ID).Good) + { WiiMapping[i].joy = _joyinfo.at(WiiMapping[i].ID).joy; +#ifdef _WIN32 + XINPUT_STATE xstate; + DWORD xresult = XInputGetState(WiiMapping[i].ID, &xstate); + if (xresult == ERROR_SUCCESS) + WiiMapping[i].TriggerType = InputCommon::CTL_TRIGGER_XINPUT; +#endif + } } - return WasGotten; } diff --git a/Source/Plugins/Plugin_Wiimote/Src/Rumble.cpp b/Source/Plugins/Plugin_Wiimote/Src/Rumble.cpp index eb55ac8201..f3604526ae 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/Rumble.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/Rumble.cpp @@ -20,6 +20,10 @@ #include "../../../Core/InputCommon/Src/SDL.h" // Core #include "EmuDefinitions.h" +#ifdef _WIN32 +#include "XInput.h" +#endif + namespace WiiMoteEmu { @@ -57,58 +61,67 @@ BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContex BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext); void SetDeviceForcesXY(int pad, int nXYForce); HRESULT InitRumble(HWND hWnd); +void Rumble_DInput(int _ID, unsigned int _Strength); +void Rumble_XInput(int _ID, unsigned int _Strength); + LPDIRECTINPUT8 g_Rumble; // DInput Rumble object RUMBLE pRumble[MAX_WIIMOTES]; -////////////////////// -// Use PAD rumble -// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -void Pad_Use_Rumble(u8 _numPAD) + +//////////////////////////////////////////////////// +// Set PAD rumble. Explanation: Stop = 0, Rumble = 1 +void PAD_Rumble(u8 _numPAD, unsigned int _uType) +{ + if (WiiMapping[_numPAD].ID >= NumPads || !WiiMapping[_numPAD].Rumble) + return; + + unsigned int Strength = 0; + if (_uType == 1) + { + Strength = 1000 * (WiiMapping[_numPAD].RumbleStrength); + Strength = Strength > 10000 ? 10000 : Strength; + } + + if (WiiMapping[_numPAD].TriggerType == InputCommon::CTL_TRIGGER_XINPUT) + Rumble_XInput(WiiMapping[_numPAD].ID, Strength); + else + Rumble_DInput(WiiMapping[_numPAD].ID, Strength); +} + +//////////////////////////////////////////////////// +// Set rumble with XInput. +void Rumble_XInput(int _ID, unsigned int _Strength) +{ +#ifdef _WIN32 + XINPUT_VIBRATION vib; + vib.wLeftMotorSpeed = _Strength; + vib.wRightMotorSpeed = _Strength; + XInputSetState(_ID, &vib); +#endif +} + +//////////////////////////////////////////////////// +// Set rumble with DInput.ŻŻŻŻŻŻŻŻŻŻŻŻ +void Rumble_DInput(int _ID, unsigned int _Strength) { if (!g_Rumble) { // GetForegroundWindow() always sends the good HWND if (FAILED(InitRumble(GetForegroundWindow()))) PanicAlert("Could not initialize Rumble!"); - } else - { - // Acquire gamepad - if (pRumble[_numPAD].g_pDevice != NULL) - pRumble[_numPAD].g_pDevice->Acquire(); - } -} - -//////////////////////////////////////////////////// -// Set PAD rumble. Explanation: Stop = 0, Rumble = 1 -// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ - -void PAD_Rumble(u8 _numPAD, unsigned int _uType) -{ - if (WiiMapping[_numPAD].ID >= NumPads || !WiiMapping[_numPAD].Rumble) - return; - - Pad_Use_Rumble(_numPAD); - - int Strenght = 0; - - if (_uType == 1) - { - // it looks like _uStrength is equal to 3 everytime anyway... - Strenght = 1000 * (WiiMapping[_numPAD].RumbleStrength); - Strenght = Strenght > 10000 ? 10000 : Strenght; } else - Strenght = 0; + { + // Acquire gamepad + if (pRumble[_ID].g_pDevice != NULL) + pRumble[_ID].g_pDevice->Acquire(); + } - SetDeviceForcesXY(_numPAD, Strenght); + SetDeviceForcesXY(_ID, _Strength); } -// Rumble stuff :D! -// ---------------- -// - HRESULT InitRumble(HWND hWnd) { DIPROPDWORD dipdw; @@ -279,13 +292,27 @@ BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pCont void PAD_RumbleClose() { - // It may look weird, but we don't free anything here, it was the cause of crashes - // on stop, and the DLL isn't unloaded anyway, so the pointers stay - // We just stop the rumble in case it's still playing an effect. for (int i = 0; i < MAX_WIIMOTES; i++) { - if (pRumble[i].g_pDevice && pRumble[i].g_pEffect) - pRumble[i].g_pEffect->Stop(); + if (WiiMapping[i].ID < NumPads) + if (WiiMapping[i].TriggerType == InputCommon::CTL_TRIGGER_XINPUT) + { +#ifdef _WIN32 + // Kill Xpad rumble + XINPUT_VIBRATION vib; + vib.wLeftMotorSpeed = 0; + vib.wRightMotorSpeed = 0; + XInputSetState(WiiMapping[i].ID, &vib); +#endif + } + else + { + // It may look weird, but we don't free anything here, it was the cause of crashes + // on stop, and the DLL isn't unloaded anyway, so the pointers stay + // We just stop the rumble in case it's still playing an effect. + if (pRumble[WiiMapping[i].ID].g_pDevice && pRumble[WiiMapping[i].ID].g_pEffect) + pRumble[WiiMapping[i].ID].g_pEffect->Stop(); + } } }