detect changing USB joysticks and remap on the fly
This commit is contained in:
@@ -464,6 +464,42 @@ void FileWrite( RageFileBasic& f, float fWrite );
|
|||||||
bool FileCopy( RString sSrcFile, RString sDstFile );
|
bool FileCopy( RString sSrcFile, RString sDstFile );
|
||||||
bool FileCopy( RageFileBasic &in, RageFileBasic &out, RString &sError, bool *bReadError = NULL );
|
bool FileCopy( RageFileBasic &in, RageFileBasic &out, RString &sError, bool *bReadError = NULL );
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool VectorsAreEqual( const T &a, const T &b )
|
||||||
|
{
|
||||||
|
if( a.size() != b.size() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for( unsigned i=0; i<a.size(); i++ )
|
||||||
|
{
|
||||||
|
if( a[i] != b[i] )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void GetAsNotInBs( const vector<T> &as, const vector<T> &bs, vector<T> &difference )
|
||||||
|
{
|
||||||
|
vector<T> bsUnmatched = bs;
|
||||||
|
FOREACH_CONST( T, as, a )
|
||||||
|
{
|
||||||
|
vector<T>::iterator iter = find( bsUnmatched.begin(), bsUnmatched.end(), *a );
|
||||||
|
if( iter != bsUnmatched.end() )
|
||||||
|
bsUnmatched.erase( iter );
|
||||||
|
else
|
||||||
|
difference.push_back( *a );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void GetConnectsDisconnects( const vector<T> &before, const vector<T> &after, vector<T> &disconnects, vector<T> &connects )
|
||||||
|
{
|
||||||
|
GetAsNotInBs( before, after, disconnects );
|
||||||
|
GetAsNotInBs( after, before, connects );
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+19
-12
@@ -290,8 +290,6 @@ void StepMania::ResetGame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
PREFSMAN->SavePrefsToDisk();
|
PREFSMAN->SavePrefsToDisk();
|
||||||
|
|
||||||
CheckForChangedInputDevicesAndRemap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StepMania::CheckForChangedInputDevicesAndRemap()
|
void StepMania::CheckForChangedInputDevicesAndRemap()
|
||||||
@@ -300,20 +298,28 @@ void StepMania::CheckForChangedInputDevicesAndRemap()
|
|||||||
// update last seen joysticks
|
// update last seen joysticks
|
||||||
//
|
//
|
||||||
vector<InputDevice> vDevices;
|
vector<InputDevice> vDevices;
|
||||||
vector<CString> vDescriptions;
|
vector<CString> vsDescriptions;
|
||||||
INPUTMAN->GetDevicesAndDescriptions(vDevices,vDescriptions);
|
INPUTMAN->GetDevicesAndDescriptions( vDevices, vsDescriptions );
|
||||||
CString sInputDevices = join( ",", vDescriptions );
|
CString sInputDevices = join( ",", vsDescriptions );
|
||||||
|
|
||||||
if( PREFSMAN->m_sLastSeenInputDevices.Get() != sInputDevices )
|
if( PREFSMAN->m_sLastSeenInputDevices.Get() != sInputDevices )
|
||||||
{
|
{
|
||||||
CString sMessage = ssprintf(
|
vector<CString> vsLastSeen;
|
||||||
"Input devices changed from '%s' to '%s'.",
|
split( PREFSMAN->m_sLastSeenInputDevices, ",", vsLastSeen );
|
||||||
PREFSMAN->m_sLastSeenInputDevices.Get().c_str(),
|
|
||||||
sInputDevices.c_str() );
|
vector<CString> vsConnects, vsDisconnects;
|
||||||
|
GetConnectsDisconnects( vsLastSeen, vsDescriptions, vsDisconnects, vsConnects );
|
||||||
|
|
||||||
|
CString sMessage;
|
||||||
|
|
||||||
|
if( !vsConnects.empty() )
|
||||||
|
sMessage += "Connected: " + join( "\n", vsConnects ) + "\n";
|
||||||
|
if( !vsDisconnects.empty() )
|
||||||
|
sMessage += "Disconnected: " + join( "\n", vsDisconnects ) + "\n";
|
||||||
|
|
||||||
if( PREFSMAN->m_bAutoMapOnJoyChange )
|
if( PREFSMAN->m_bAutoMapOnJoyChange )
|
||||||
{
|
{
|
||||||
sMessage += "\nRemapping joysticks.";
|
sMessage += "Remapping all joysticks.";
|
||||||
INPUTMAPPER->AutoMapJoysticksForCurrentGame();
|
INPUTMAPPER->AutoMapJoysticksForCurrentGame();
|
||||||
INPUTMAPPER->SaveMappingsToDisk();
|
INPUTMAPPER->SaveMappingsToDisk();
|
||||||
}
|
}
|
||||||
@@ -1112,8 +1118,6 @@ 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;
|
||||||
@@ -1137,6 +1141,9 @@ int main(int argc, char* argv[])
|
|||||||
SCREENMAN->ThemeChanged();
|
SCREENMAN->ThemeChanged();
|
||||||
SCREENMAN->SetNewScreen( CommonMetrics::INITIAL_SCREEN );
|
SCREENMAN->SetNewScreen( CommonMetrics::INITIAL_SCREEN );
|
||||||
|
|
||||||
|
// Do this after ThemeChanged so that we can show a system message
|
||||||
|
StepMania::CheckForChangedInputDevicesAndRemap();
|
||||||
|
|
||||||
CodeDetector::RefreshCacheItems();
|
CodeDetector::RefreshCacheItems();
|
||||||
|
|
||||||
/* Initialize which courses are ranking courses here. */
|
/* Initialize which courses are ranking courses here. */
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "archutils/Win32/AppInstance.h"
|
#include "archutils/Win32/AppInstance.h"
|
||||||
#include "archutils/Win32/GraphicsWindow.h"
|
#include "archutils/Win32/GraphicsWindow.h"
|
||||||
|
#include "archutils/Win32/RegistryAccess.h"
|
||||||
#include "InputFilter.h"
|
#include "InputFilter.h"
|
||||||
#include "PrefsManager.h"
|
#include "PrefsManager.h"
|
||||||
|
|
||||||
@@ -66,6 +67,14 @@ static void CheckForDirectInputDebugMode()
|
|||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int GetNumUsbHidDevices()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
bool b = RegistryAccess::GetRegValue( "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\HidUsb\\Enum", "Count", i );
|
||||||
|
ASSERT( b );
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
InputHandler_DInput::InputHandler_DInput()
|
InputHandler_DInput::InputHandler_DInput()
|
||||||
{
|
{
|
||||||
LOG->Trace( "InputHandler_DInput::InputHandler_DInput()" );
|
LOG->Trace( "InputHandler_DInput::InputHandler_DInput()" );
|
||||||
@@ -73,7 +82,7 @@ InputHandler_DInput::InputHandler_DInput()
|
|||||||
CheckForDirectInputDebugMode();
|
CheckForDirectInputDebugMode();
|
||||||
|
|
||||||
shutdown = false;
|
shutdown = false;
|
||||||
m_bDevicesChanged = false;
|
m_iLastSeenNumUsbHid = GetNumUsbHidDevices();
|
||||||
g_NumJoysticks = 0;
|
g_NumJoysticks = 0;
|
||||||
|
|
||||||
AppInstance inst;
|
AppInstance inst;
|
||||||
@@ -462,7 +471,9 @@ void InputHandler_DInput::Update( float fDeltaTime )
|
|||||||
|
|
||||||
bool InputHandler_DInput::DevicesChanged()
|
bool InputHandler_DInput::DevicesChanged()
|
||||||
{
|
{
|
||||||
return m_bDevicesChanged;
|
int iOldNumUsbHid = m_iLastSeenNumUsbHid;
|
||||||
|
m_iLastSeenNumUsbHid = GetNumUsbHidDevices();
|
||||||
|
return iOldNumUsbHid != m_iLastSeenNumUsbHid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputHandler_DInput::InputThreadMain()
|
void InputHandler_DInput::InputThreadMain()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
RageThread InputThread;
|
RageThread InputThread;
|
||||||
bool shutdown;
|
bool shutdown;
|
||||||
bool m_bDevicesChanged;
|
int m_iLastSeenNumUsbHid; // use this to figure out if a device was plugged/unplugged
|
||||||
|
|
||||||
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 );
|
||||||
|
|||||||
@@ -8,21 +8,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
template<class T>
|
|
||||||
bool VectorsAreEqual( const T &a, const T &b )
|
|
||||||
{
|
|
||||||
if( a.size() != b.size() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for( unsigned i=0; i<a.size(); i++ )
|
|
||||||
{
|
|
||||||
if( a[i] != b[i] )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MemoryCardDriverThreaded_Linux::TestWrite( UsbStorageDevice* pDevice )
|
bool MemoryCardDriverThreaded_Linux::TestWrite( UsbStorageDevice* pDevice )
|
||||||
{
|
{
|
||||||
if( access(pDevice->sOsMountDir, W_OK) == -1 )
|
if( access(pDevice->sOsMountDir, W_OK) == -1 )
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ void MemoryCardDriverThreaded_Windows::GetUSBStorageDevices( vector<UsbStorageDe
|
|||||||
usbd.sDevice = sDrive;
|
usbd.sDevice = sDrive;
|
||||||
usbd.sVolumeLabel = sVolumeLabel;
|
usbd.sVolumeLabel = sVolumeLabel;
|
||||||
|
|
||||||
|
// TODO: fill in bus/level/port with this:
|
||||||
|
// http://www.codeproject.com/system/EnumDeviceProperties.asp
|
||||||
|
|
||||||
// find volume size
|
// find volume size
|
||||||
DWORD dwSectorsPerCluster;
|
DWORD dwSectorsPerCluster;
|
||||||
DWORD dwBytesPerSector;
|
DWORD dwBytesPerSector;
|
||||||
|
|||||||
Reference in New Issue
Block a user