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( 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
|
||||
|
||||
/*
|
||||
|
||||
+19
-12
@@ -290,8 +290,6 @@ void StepMania::ResetGame()
|
||||
}
|
||||
|
||||
PREFSMAN->SavePrefsToDisk();
|
||||
|
||||
CheckForChangedInputDevicesAndRemap();
|
||||
}
|
||||
|
||||
void StepMania::CheckForChangedInputDevicesAndRemap()
|
||||
@@ -300,20 +298,28 @@ void StepMania::CheckForChangedInputDevicesAndRemap()
|
||||
// update last seen joysticks
|
||||
//
|
||||
vector<InputDevice> vDevices;
|
||||
vector<CString> vDescriptions;
|
||||
INPUTMAN->GetDevicesAndDescriptions(vDevices,vDescriptions);
|
||||
CString sInputDevices = join( ",", vDescriptions );
|
||||
vector<CString> vsDescriptions;
|
||||
INPUTMAN->GetDevicesAndDescriptions( vDevices, vsDescriptions );
|
||||
CString sInputDevices = join( ",", vsDescriptions );
|
||||
|
||||
if( PREFSMAN->m_sLastSeenInputDevices.Get() != sInputDevices )
|
||||
{
|
||||
CString sMessage = ssprintf(
|
||||
"Input devices changed from '%s' to '%s'.",
|
||||
PREFSMAN->m_sLastSeenInputDevices.Get().c_str(),
|
||||
sInputDevices.c_str() );
|
||||
vector<CString> vsLastSeen;
|
||||
split( PREFSMAN->m_sLastSeenInputDevices, ",", vsLastSeen );
|
||||
|
||||
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 )
|
||||
{
|
||||
sMessage += "\nRemapping joysticks.";
|
||||
sMessage += "Remapping all joysticks.";
|
||||
INPUTMAPPER->AutoMapJoysticksForCurrentGame();
|
||||
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. */
|
||||
INPUTMAN = new RageInput( PREFSMAN->GetInputDrivers() );
|
||||
|
||||
StepMania::CheckForChangedInputDevicesAndRemap();
|
||||
|
||||
// These things depend on the TextureManager, so do them after!
|
||||
FONT = new FontManager;
|
||||
SCREENMAN = new ScreenManager;
|
||||
@@ -1137,6 +1141,9 @@ int main(int argc, char* argv[])
|
||||
SCREENMAN->ThemeChanged();
|
||||
SCREENMAN->SetNewScreen( CommonMetrics::INITIAL_SCREEN );
|
||||
|
||||
// Do this after ThemeChanged so that we can show a system message
|
||||
StepMania::CheckForChangedInputDevicesAndRemap();
|
||||
|
||||
CodeDetector::RefreshCacheItems();
|
||||
|
||||
/* Initialize which courses are ranking courses here. */
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "RageLog.h"
|
||||
#include "archutils/Win32/AppInstance.h"
|
||||
#include "archutils/Win32/GraphicsWindow.h"
|
||||
#include "archutils/Win32/RegistryAccess.h"
|
||||
#include "InputFilter.h"
|
||||
#include "PrefsManager.h"
|
||||
|
||||
@@ -66,6 +67,14 @@ static void CheckForDirectInputDebugMode()
|
||||
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()
|
||||
{
|
||||
LOG->Trace( "InputHandler_DInput::InputHandler_DInput()" );
|
||||
@@ -73,7 +82,7 @@ InputHandler_DInput::InputHandler_DInput()
|
||||
CheckForDirectInputDebugMode();
|
||||
|
||||
shutdown = false;
|
||||
m_bDevicesChanged = false;
|
||||
m_iLastSeenNumUsbHid = GetNumUsbHidDevices();
|
||||
g_NumJoysticks = 0;
|
||||
|
||||
AppInstance inst;
|
||||
@@ -462,7 +471,9 @@ void InputHandler_DInput::Update( float fDeltaTime )
|
||||
|
||||
bool InputHandler_DInput::DevicesChanged()
|
||||
{
|
||||
return m_bDevicesChanged;
|
||||
int iOldNumUsbHid = m_iLastSeenNumUsbHid;
|
||||
m_iLastSeenNumUsbHid = GetNumUsbHidDevices();
|
||||
return iOldNumUsbHid != m_iLastSeenNumUsbHid;
|
||||
}
|
||||
|
||||
void InputHandler_DInput::InputThreadMain()
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
private:
|
||||
RageThread InputThread;
|
||||
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 UpdateBuffered( DIDevice &device, const RageTimer &tm );
|
||||
|
||||
@@ -8,21 +8,6 @@
|
||||
#include <fcntl.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 )
|
||||
{
|
||||
if( access(pDevice->sOsMountDir, W_OK) == -1 )
|
||||
|
||||
@@ -94,6 +94,9 @@ void MemoryCardDriverThreaded_Windows::GetUSBStorageDevices( vector<UsbStorageDe
|
||||
usbd.sDevice = sDrive;
|
||||
usbd.sVolumeLabel = sVolumeLabel;
|
||||
|
||||
// TODO: fill in bus/level/port with this:
|
||||
// http://www.codeproject.com/system/EnumDeviceProperties.asp
|
||||
|
||||
// find volume size
|
||||
DWORD dwSectorsPerCluster;
|
||||
DWORD dwBytesPerSector;
|
||||
|
||||
Reference in New Issue
Block a user