Added support for X360pad rumble
Need someone who has a X360pad to test. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4929 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
2098271bc8
commit
1ecbcb39ea
|
@ -97,17 +97,17 @@ int GetXI(int Controller, int Button)
|
||||||
{
|
{
|
||||||
// Update the internal status
|
// Update the internal status
|
||||||
DWORD dwResult;
|
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:
|
case InputCommon::XI_TRIGGER_L:
|
||||||
return g_Controllers[0].state.Gamepad.bLeftTrigger;
|
return g_Controllers[Controller].state.Gamepad.bLeftTrigger;
|
||||||
|
|
||||||
case InputCommon::XI_TRIGGER_R:
|
case InputCommon::XI_TRIGGER_R:
|
||||||
return g_Controllers[0].state.Gamepad.bRightTrigger;
|
return g_Controllers[Controller].state.Gamepad.bRightTrigger;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -23,6 +23,10 @@
|
||||||
#include "ConfigBox.h"
|
#include "ConfigBox.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "XInput.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Declare config window so that we can write debugging info to it from functions in this file
|
// Declare config window so that we can write debugging info to it from functions in this file
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
GCPadConfigDialog* m_ConfigFrame = NULL;
|
GCPadConfigDialog* m_ConfigFrame = NULL;
|
||||||
|
@ -457,7 +461,15 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
|
||||||
{
|
{
|
||||||
if (_NumPads > GCMapping[i].ID)
|
if (_NumPads > GCMapping[i].ID)
|
||||||
if(joyinfo.at(GCMapping[i].ID).Good)
|
if(joyinfo.at(GCMapping[i].ID).Good)
|
||||||
|
{
|
||||||
GCMapping[i].joy = joyinfo.at(GCMapping[i].ID).joy;
|
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;
|
return Success;
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
|
|
||||||
#include "GCpad.h"
|
#include "GCpad.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "XInput.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef RUMBLE_HACK
|
#ifdef RUMBLE_HACK
|
||||||
|
|
||||||
|
@ -35,57 +39,63 @@ BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContex
|
||||||
BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext);
|
BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext);
|
||||||
void SetDeviceForcesXY(int pad, int nXYForce);
|
void SetDeviceForcesXY(int pad, int nXYForce);
|
||||||
HRESULT InitRumble(HWND hWnd);
|
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
|
LPDIRECTINPUT8 g_Rumble; // DInput Rumble object
|
||||||
RUMBLE pRumble[4]; // 4 GC Rumble Pads
|
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)
|
void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
|
||||||
{
|
{
|
||||||
if (GCMapping[_numPAD].ID >= NumPads || !GCMapping[_numPAD].Rumble)
|
if (GCMapping[_numPAD].ID >= NumPads || !GCMapping[_numPAD].Rumble)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Pad_Use_Rumble(_numPAD);
|
unsigned int Strength = 0;
|
||||||
|
|
||||||
int Strenght = 0;
|
|
||||||
|
|
||||||
if (_uType == 1 && _uStrength > 2)
|
if (_uType == 1 && _uStrength > 2)
|
||||||
{
|
{
|
||||||
// it looks like _uStrength is equal to 3 everytime anyway...
|
Strength = 1000 * GCMapping[_numPAD].RumbleStrength;
|
||||||
Strenght = 1000 * GCMapping[_numPAD].RumbleStrength;
|
Strength = Strength > 10000 ? 10000 : Strength;
|
||||||
Strenght = Strenght > 10000 ? 10000 : Strenght;
|
|
||||||
}
|
}
|
||||||
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)
|
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
|
// a DInput device is created even if rumble is disabled on startup
|
||||||
// this way, you can toggle the rumble setting while in game
|
// 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()
|
void PAD_RumbleClose()
|
||||||
{
|
{
|
||||||
// It may look weird, but we don't free anything here, it was the cause of crashes
|
for (int i = 0; i < 4; i++)
|
||||||
// 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++)
|
|
||||||
{
|
{
|
||||||
if (pRumble[i].g_pDevice && pRumble[i].g_pEffect)
|
if (GCMapping[i].ID < NumPads)
|
||||||
pRumble[i].g_pEffect->Stop();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
#include "Encryption.h" // for extension encryption
|
#include "Encryption.h" // for extension encryption
|
||||||
#include "Config.h" // for g_Config
|
#include "Config.h" // for g_Config
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "XInput.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
extern SWiimoteInitialize g_WiimoteInitialize;
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
namespace WiiMoteEmu
|
||||||
|
@ -87,9 +91,16 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
|
||||||
{
|
{
|
||||||
if (_NumPads > WiiMapping[i].ID)
|
if (_NumPads > WiiMapping[i].ID)
|
||||||
if(_joyinfo.at(WiiMapping[i].ID).Good)
|
if(_joyinfo.at(WiiMapping[i].ID).Good)
|
||||||
|
{
|
||||||
WiiMapping[i].joy = _joyinfo.at(WiiMapping[i].ID).joy;
|
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;
|
return WasGotten;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
#include "../../../Core/InputCommon/Src/SDL.h" // Core
|
#include "../../../Core/InputCommon/Src/SDL.h" // Core
|
||||||
#include "EmuDefinitions.h"
|
#include "EmuDefinitions.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "XInput.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
namespace WiiMoteEmu
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -57,58 +61,67 @@ BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContex
|
||||||
BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext);
|
BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext);
|
||||||
void SetDeviceForcesXY(int pad, int nXYForce);
|
void SetDeviceForcesXY(int pad, int nXYForce);
|
||||||
HRESULT InitRumble(HWND hWnd);
|
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
|
LPDIRECTINPUT8 g_Rumble; // DInput Rumble object
|
||||||
RUMBLE pRumble[MAX_WIIMOTES];
|
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)
|
if (!g_Rumble)
|
||||||
{
|
{
|
||||||
// GetForegroundWindow() always sends the good HWND
|
// GetForegroundWindow() always sends the good HWND
|
||||||
if (FAILED(InitRumble(GetForegroundWindow())))
|
if (FAILED(InitRumble(GetForegroundWindow())))
|
||||||
PanicAlert("Could not initialize Rumble!");
|
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
|
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)
|
HRESULT InitRumble(HWND hWnd)
|
||||||
{
|
{
|
||||||
DIPROPDWORD dipdw;
|
DIPROPDWORD dipdw;
|
||||||
|
@ -279,13 +292,27 @@ BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pCont
|
||||||
|
|
||||||
void PAD_RumbleClose()
|
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++)
|
for (int i = 0; i < MAX_WIIMOTES; i++)
|
||||||
{
|
{
|
||||||
if (pRumble[i].g_pDevice && pRumble[i].g_pEffect)
|
if (WiiMapping[i].ID < NumPads)
|
||||||
pRumble[i].g_pEffect->Stop();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue