add InputDevice::DevicesChanged
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include "LightsManager.h"
|
#include "LightsManager.h"
|
||||||
#include "NetworkSyncManager.h"
|
#include "NetworkSyncManager.h"
|
||||||
#include "RageTimer.h"
|
#include "RageTimer.h"
|
||||||
|
#include "RageInput.h"
|
||||||
|
|
||||||
#include "StepMania.h"
|
#include "StepMania.h"
|
||||||
|
|
||||||
@@ -97,6 +98,13 @@ void GameLoop()
|
|||||||
/* Important: Process input AFTER updating game logic, or input will be acting on song beat from last frame */
|
/* Important: Process input AFTER updating game logic, or input will be acting on song beat from last frame */
|
||||||
HandleInputEvents( fDeltaTime );
|
HandleInputEvents( fDeltaTime );
|
||||||
|
|
||||||
|
if( INPUTMAN->DevicesChanged() )
|
||||||
|
{
|
||||||
|
SAFE_DELETE( INPUTMAN );
|
||||||
|
INPUTMAN = new RageInput( PREFSMAN->GetInputDrivers() );
|
||||||
|
StepMania::CheckForChangedInputDevicesAndRemap();
|
||||||
|
}
|
||||||
|
|
||||||
LIGHTSMAN->Update( fDeltaTime );
|
LIGHTSMAN->Update( fDeltaTime );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -34,6 +34,17 @@ void RageInput::Update( float fDeltaTime )
|
|||||||
m_pDevices[i]->Update( fDeltaTime );
|
m_pDevices[i]->Update( fDeltaTime );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RageInput::DevicesChanged()
|
||||||
|
{
|
||||||
|
/* Update optional devices. */
|
||||||
|
for( unsigned i = 0; i < m_pDevices.size(); ++i )
|
||||||
|
{
|
||||||
|
if( m_pDevices[i]->DevicesChanged() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void RageInput::GetDevicesAndDescriptions( vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut )
|
void RageInput::GetDevicesAndDescriptions( vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut )
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < m_pDevices.size(); ++i )
|
for( unsigned i = 0; i < m_pDevices.size(); ++i )
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public:
|
|||||||
~RageInput();
|
~RageInput();
|
||||||
|
|
||||||
void Update( float fDeltaTime );
|
void Update( float fDeltaTime );
|
||||||
|
bool DevicesChanged();
|
||||||
void GetDevicesAndDescriptions( vector<InputDevice>& vDevicesOut, vector<CString>& vsDescriptionsOut );
|
void GetDevicesAndDescriptions( vector<InputDevice>& vDevicesOut, vector<CString>& vsDescriptionsOut );
|
||||||
void WindowReset();
|
void WindowReset();
|
||||||
void AddHandler( InputHandler *pHandler );
|
void AddHandler( InputHandler *pHandler );
|
||||||
|
|||||||
@@ -289,6 +289,13 @@ void StepMania::ResetGame()
|
|||||||
TEXTUREMAN->DoDelayedDelete();
|
TEXTUREMAN->DoDelayedDelete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PREFSMAN->SavePrefsToDisk();
|
||||||
|
|
||||||
|
CheckForChangedInputDevicesAndRemap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StepMania::CheckForChangedInputDevicesAndRemap()
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// update last seen joysticks
|
// update last seen joysticks
|
||||||
//
|
//
|
||||||
@@ -299,22 +306,27 @@ void StepMania::ResetGame()
|
|||||||
|
|
||||||
if( PREFSMAN->m_sLastSeenInputDevices.Get() != sInputDevices )
|
if( PREFSMAN->m_sLastSeenInputDevices.Get() != sInputDevices )
|
||||||
{
|
{
|
||||||
LOG->Info( "Input devices changed from '%s' to '%s'.", PREFSMAN->m_sLastSeenInputDevices.Get().c_str(), sInputDevices.c_str() );
|
CString sMessage = ssprintf(
|
||||||
|
"Input devices changed from '%s' to '%s'.",
|
||||||
|
PREFSMAN->m_sLastSeenInputDevices.Get().c_str(),
|
||||||
|
sInputDevices.c_str() );
|
||||||
|
|
||||||
if( PREFSMAN->m_bAutoMapOnJoyChange )
|
if( PREFSMAN->m_bAutoMapOnJoyChange )
|
||||||
{
|
{
|
||||||
LOG->Info( "Remapping joysticks." );
|
sMessage += "\nRemapping joysticks.";
|
||||||
INPUTMAPPER->AutoMapJoysticksForCurrentGame();
|
INPUTMAPPER->AutoMapJoysticksForCurrentGame();
|
||||||
INPUTMAPPER->SaveMappingsToDisk();
|
INPUTMAPPER->SaveMappingsToDisk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG->Info( sMessage );
|
||||||
|
SCREENMAN->SystemMessage( sMessage );
|
||||||
|
|
||||||
PREFSMAN->m_sLastSeenInputDevices.Set( sInputDevices );
|
PREFSMAN->m_sLastSeenInputDevices.Set( sInputDevices );
|
||||||
}
|
}
|
||||||
|
|
||||||
PREFSMAN->SavePrefsToDisk();
|
PREFSMAN->SavePrefsToDisk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool ChangeAppPri()
|
static bool ChangeAppPri()
|
||||||
{
|
{
|
||||||
if( PREFSMAN->m_BoostAppPriority.Get() == PrefsManager::BOOST_NO )
|
if( PREFSMAN->m_BoostAppPriority.Get() == PrefsManager::BOOST_NO )
|
||||||
@@ -1100,6 +1112,8 @@ int main(int argc, char* argv[])
|
|||||||
* dependencies on the SDL video subsystem, so it must be initialized after DISPLAY. */
|
* dependencies on the SDL video subsystem, so it must be initialized after DISPLAY. */
|
||||||
INPUTMAN = new RageInput( PREFSMAN->GetInputDrivers() );
|
INPUTMAN = new RageInput( PREFSMAN->GetInputDrivers() );
|
||||||
|
|
||||||
|
StepMania::CheckForChangedInputDevicesAndRemap();
|
||||||
|
|
||||||
// These things depend on the TextureManager, so do them after!
|
// These things depend on the TextureManager, so do them after!
|
||||||
FONT = new FontManager;
|
FONT = new FontManager;
|
||||||
SCREENMAN = new ScreenManager;
|
SCREENMAN = new ScreenManager;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace StepMania
|
|||||||
void ApplyGraphicOptions();
|
void ApplyGraphicOptions();
|
||||||
void NORETURN HandleException( CString error );
|
void NORETURN HandleException( CString error );
|
||||||
void ResetGame();
|
void ResetGame();
|
||||||
|
void CheckForChangedInputDevicesAndRemap();
|
||||||
void ChangeCurrentGame( const Game* g );
|
void ChangeCurrentGame( const Game* g );
|
||||||
void FocusChanged( bool bHasFocus );
|
void FocusChanged( bool bHasFocus );
|
||||||
bool AppHasFocus();
|
bool AppHasFocus();
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public:
|
|||||||
InputHandler() { m_iInputsSinceUpdate = 0; }
|
InputHandler() { m_iInputsSinceUpdate = 0; }
|
||||||
virtual ~InputHandler() { }
|
virtual ~InputHandler() { }
|
||||||
virtual void Update( float fDeltaTime ) { }
|
virtual void Update( float fDeltaTime ) { }
|
||||||
|
virtual bool DevicesChanged() { return false; }
|
||||||
virtual void GetDevicesAndDescriptions( vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut ) = 0;
|
virtual void GetDevicesAndDescriptions( vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut ) = 0;
|
||||||
|
|
||||||
// Override to return a pretty string that's specific to the controller type.
|
// Override to return a pretty string that's specific to the controller type.
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ InputHandler_DInput::InputHandler_DInput()
|
|||||||
CheckForDirectInputDebugMode();
|
CheckForDirectInputDebugMode();
|
||||||
|
|
||||||
shutdown = false;
|
shutdown = false;
|
||||||
|
m_bDevicesChanged = false;
|
||||||
g_NumJoysticks = 0;
|
g_NumJoysticks = 0;
|
||||||
|
|
||||||
AppInstance inst;
|
AppInstance inst;
|
||||||
@@ -227,108 +228,116 @@ HRESULT GetDeviceState(LPDIRECTINPUTDEVICE2 dev, int size, void *ptr)
|
|||||||
* it out. Be sure to call InputHandler::Update() between each poll. */
|
* it out. Be sure to call InputHandler::Update() between each poll. */
|
||||||
void InputHandler_DInput::UpdatePolled(DIDevice &device, const RageTimer &tm)
|
void InputHandler_DInput::UpdatePolled(DIDevice &device, const RageTimer &tm)
|
||||||
{
|
{
|
||||||
if( device.type == device.KEYBOARD )
|
switch( device.type )
|
||||||
{
|
{
|
||||||
unsigned char keys[256];
|
default:
|
||||||
|
ASSERT(0);
|
||||||
HRESULT hr = GetDeviceState(device.Device, 256, keys);
|
case device.KEYBOARD:
|
||||||
if ( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( hr != DI_OK )
|
|
||||||
{
|
{
|
||||||
LOG->MapLog( "UpdatePolled", hr_ssprintf(hr, "Failures on polled keyboard update") );
|
unsigned char keys[256];
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int k = 0; k < 256; ++k )
|
HRESULT hr = GetDeviceState(device.Device, 256, keys);
|
||||||
{
|
if ( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED )
|
||||||
const int key = device.Inputs[k].num;
|
return;
|
||||||
ButtonPressed(DeviceInput(device.dev, key), !!(keys[k] & 0x80));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DIJOYSTATE state;
|
if ( hr != DI_OK )
|
||||||
|
|
||||||
HRESULT hr = GetDeviceState(device.Device, sizeof(state), &state);
|
|
||||||
if ( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED )
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Set each known axis, button and POV. */
|
|
||||||
for(unsigned i = 0; i < device.Inputs.size(); ++i)
|
|
||||||
{
|
|
||||||
const input_t &in = device.Inputs[i];
|
|
||||||
const InputDevice dev = device.dev;
|
|
||||||
|
|
||||||
switch(in.type)
|
|
||||||
{
|
|
||||||
case in.BUTTON:
|
|
||||||
{
|
|
||||||
DeviceInput di(dev, JOY_BUTTON_1 + in.num, -1, tm);
|
|
||||||
ButtonPressed(di, !!state.rgbButtons[in.ofs - DIJOFS_BUTTON0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case in.AXIS:
|
|
||||||
{
|
|
||||||
JoystickButton neg = NUM_JOYSTICK_BUTTONS, pos = NUM_JOYSTICK_BUTTONS;
|
|
||||||
int val = 0;
|
|
||||||
switch(in.ofs)
|
|
||||||
{
|
{
|
||||||
case DIJOFS_X: neg = JOY_LEFT; pos = JOY_RIGHT;
|
LOG->MapLog( "UpdatePolled", hr_ssprintf(hr, "Failures on polled keyboard update") );
|
||||||
val = state.lX;
|
return;
|
||||||
break;
|
|
||||||
case DIJOFS_Y: neg = JOY_UP; pos = JOY_DOWN;
|
|
||||||
val = state.lY;
|
|
||||||
break;
|
|
||||||
case DIJOFS_Z: neg = JOY_Z_UP; pos = JOY_Z_DOWN;
|
|
||||||
val = state.lZ;
|
|
||||||
break;
|
|
||||||
case DIJOFS_RX: neg = JOY_ROT_LEFT; pos = JOY_ROT_RIGHT;
|
|
||||||
val = state.lRx;
|
|
||||||
break;
|
|
||||||
case DIJOFS_RY: neg = JOY_ROT_UP; pos = JOY_ROT_DOWN;
|
|
||||||
val = state.lRy;
|
|
||||||
break;
|
|
||||||
case DIJOFS_RZ: neg = JOY_ROT_Z_UP; pos = JOY_ROT_Z_DOWN;
|
|
||||||
val = state.lRz;
|
|
||||||
break;
|
|
||||||
case DIJOFS_SLIDER(0):
|
|
||||||
neg = JOY_AUX_1; pos = JOY_AUX_2;
|
|
||||||
val = state.rglSlider[0];
|
|
||||||
break;
|
|
||||||
case DIJOFS_SLIDER(1):
|
|
||||||
neg = JOY_AUX_3; pos = JOY_AUX_4;
|
|
||||||
val = state.rglSlider[1];
|
|
||||||
break;
|
|
||||||
default: LOG->MapLog("unknown input",
|
|
||||||
"Controller '%s' is returning an unknown joystick offset, %i",
|
|
||||||
device.JoystickInst.tszProductName, in.ofs );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if( neg != NUM_JOYSTICK_BUTTONS )
|
|
||||||
{
|
|
||||||
float l = SCALE( int(val), 0.0f, 100.0f, 0.0f, 1.0f );
|
|
||||||
ButtonPressed(DeviceInput(dev, neg, max(-l,0), tm), val < -50);
|
|
||||||
ButtonPressed(DeviceInput(dev, pos, max(+l,0), tm), val > 50);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
for( int k = 0; k < 256; ++k )
|
||||||
}
|
|
||||||
|
|
||||||
case in.HAT:
|
|
||||||
if( in.num == 0 )
|
|
||||||
{
|
{
|
||||||
const int pos = TranslatePOV(state.rgdwPOV[in.ofs - DIJOFS_POV(0)]);
|
const int key = device.Inputs[k].num;
|
||||||
ButtonPressed(DeviceInput(dev, JOY_HAT_UP, -1, tm), !!(pos & HAT_UP_MASK));
|
ButtonPressed(DeviceInput(device.dev, key), !!(keys[k] & 0x80));
|
||||||
ButtonPressed(DeviceInput(dev, JOY_HAT_DOWN, -1, tm), !!(pos & HAT_DOWN_MASK));
|
|
||||||
ButtonPressed(DeviceInput(dev, JOY_HAT_LEFT, -1, tm), !!(pos & HAT_LEFT_MASK));
|
|
||||||
ButtonPressed(DeviceInput(dev, JOY_HAT_RIGHT, -1, tm), !!(pos & HAT_RIGHT_MASK));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case device.JOYSTICK:
|
||||||
|
{
|
||||||
|
DIJOYSTATE state;
|
||||||
|
|
||||||
|
HRESULT hr = GetDeviceState(device.Device, sizeof(state), &state);
|
||||||
|
if ( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED )
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Set each known axis, button and POV. */
|
||||||
|
for(unsigned i = 0; i < device.Inputs.size(); ++i)
|
||||||
|
{
|
||||||
|
const input_t &in = device.Inputs[i];
|
||||||
|
const InputDevice dev = device.dev;
|
||||||
|
|
||||||
|
switch(in.type)
|
||||||
|
{
|
||||||
|
case in.BUTTON:
|
||||||
|
{
|
||||||
|
DeviceInput di(dev, JOY_BUTTON_1 + in.num, -1, tm);
|
||||||
|
ButtonPressed(di, !!state.rgbButtons[in.ofs - DIJOFS_BUTTON0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case in.AXIS:
|
||||||
|
{
|
||||||
|
JoystickButton neg = NUM_JOYSTICK_BUTTONS, pos = NUM_JOYSTICK_BUTTONS;
|
||||||
|
int val = 0;
|
||||||
|
switch(in.ofs)
|
||||||
|
{
|
||||||
|
case DIJOFS_X: neg = JOY_LEFT; pos = JOY_RIGHT;
|
||||||
|
val = state.lX;
|
||||||
|
break;
|
||||||
|
case DIJOFS_Y: neg = JOY_UP; pos = JOY_DOWN;
|
||||||
|
val = state.lY;
|
||||||
|
break;
|
||||||
|
case DIJOFS_Z: neg = JOY_Z_UP; pos = JOY_Z_DOWN;
|
||||||
|
val = state.lZ;
|
||||||
|
break;
|
||||||
|
case DIJOFS_RX: neg = JOY_ROT_LEFT; pos = JOY_ROT_RIGHT;
|
||||||
|
val = state.lRx;
|
||||||
|
break;
|
||||||
|
case DIJOFS_RY: neg = JOY_ROT_UP; pos = JOY_ROT_DOWN;
|
||||||
|
val = state.lRy;
|
||||||
|
break;
|
||||||
|
case DIJOFS_RZ: neg = JOY_ROT_Z_UP; pos = JOY_ROT_Z_DOWN;
|
||||||
|
val = state.lRz;
|
||||||
|
break;
|
||||||
|
case DIJOFS_SLIDER(0):
|
||||||
|
neg = JOY_AUX_1; pos = JOY_AUX_2;
|
||||||
|
val = state.rglSlider[0];
|
||||||
|
break;
|
||||||
|
case DIJOFS_SLIDER(1):
|
||||||
|
neg = JOY_AUX_3; pos = JOY_AUX_4;
|
||||||
|
val = state.rglSlider[1];
|
||||||
|
break;
|
||||||
|
default: LOG->MapLog("unknown input",
|
||||||
|
"Controller '%s' is returning an unknown joystick offset, %i",
|
||||||
|
device.JoystickInst.tszProductName, in.ofs );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( neg != NUM_JOYSTICK_BUTTONS )
|
||||||
|
{
|
||||||
|
float l = SCALE( int(val), 0.0f, 100.0f, 0.0f, 1.0f );
|
||||||
|
ButtonPressed(DeviceInput(dev, neg, max(-l,0), tm), val < -50);
|
||||||
|
ButtonPressed(DeviceInput(dev, pos, max(+l,0), tm), val > 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case in.HAT:
|
||||||
|
if( in.num == 0 )
|
||||||
|
{
|
||||||
|
const int pos = TranslatePOV(state.rgdwPOV[in.ofs - DIJOFS_POV(0)]);
|
||||||
|
ButtonPressed(DeviceInput(dev, JOY_HAT_UP, -1, tm), !!(pos & HAT_UP_MASK));
|
||||||
|
ButtonPressed(DeviceInput(dev, JOY_HAT_DOWN, -1, tm), !!(pos & HAT_DOWN_MASK));
|
||||||
|
ButtonPressed(DeviceInput(dev, JOY_HAT_LEFT, -1, tm), !!(pos & HAT_LEFT_MASK));
|
||||||
|
ButtonPressed(DeviceInput(dev, JOY_HAT_RIGHT, -1, tm), !!(pos & HAT_RIGHT_MASK));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +439,7 @@ void InputHandler_DInput::PollAndAcquireDevices()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputHandler_DInput::Update(float fDeltaTime)
|
void InputHandler_DInput::Update( float fDeltaTime )
|
||||||
{
|
{
|
||||||
RageTimer zero;
|
RageTimer zero;
|
||||||
zero.SetZero();
|
zero.SetZero();
|
||||||
@@ -451,6 +460,10 @@ void InputHandler_DInput::Update(float fDeltaTime)
|
|||||||
InputHandler::UpdateTimer();
|
InputHandler::UpdateTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InputHandler_DInput::DevicesChanged()
|
||||||
|
{
|
||||||
|
return m_bDevicesChanged;
|
||||||
|
}
|
||||||
|
|
||||||
void InputHandler_DInput::InputThreadMain()
|
void InputHandler_DInput::InputThreadMain()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ public:
|
|||||||
~InputHandler_DInput();
|
~InputHandler_DInput();
|
||||||
void GetDevicesAndDescriptions( vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut );
|
void GetDevicesAndDescriptions( vector<InputDevice>& vDevicesOut, vector<CString>& vDescriptionsOut );
|
||||||
void Update( float fDeltaTime );
|
void Update( float fDeltaTime );
|
||||||
|
bool DevicesChanged();
|
||||||
void WindowReset();
|
void WindowReset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RageThread InputThread;
|
RageThread InputThread;
|
||||||
bool shutdown;
|
bool shutdown;
|
||||||
|
bool m_bDevicesChanged;
|
||||||
|
|
||||||
void UpdatePolled( DIDevice &device, const RageTimer &tm );
|
void UpdatePolled( DIDevice &device, const RageTimer &tm );
|
||||||
void UpdateBuffered( DIDevice &device, const RageTimer &tm );
|
void UpdateBuffered( DIDevice &device, const RageTimer &tm );
|
||||||
|
|||||||
Reference in New Issue
Block a user