From efe3984ad58049853ba55a23ea4eb4c81f52742c Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 18 Dec 2005 07:13:13 +0000 Subject: [PATCH] detect changing USB joysticks and remap on the fly --- stepmania/src/RageUtil.h | 36 +++++++++++++++++++ stepmania/src/StepMania.cpp | 31 +++++++++------- .../InputHandler/InputHandler_DirectInput.cpp | 15 ++++++-- .../InputHandler/InputHandler_DirectInput.h | 2 +- .../MemoryCardDriverThreaded_Linux.cpp | 15 -------- .../MemoryCardDriverThreaded_Windows.cpp | 3 ++ 6 files changed, 72 insertions(+), 30 deletions(-) diff --git a/stepmania/src/RageUtil.h b/stepmania/src/RageUtil.h index c3e7eb3c89..5df2f50d0d 100644 --- a/stepmania/src/RageUtil.h +++ b/stepmania/src/RageUtil.h @@ -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 +bool VectorsAreEqual( const T &a, const T &b ) +{ + if( a.size() != b.size() ) + return false; + + for( unsigned i=0; i +void GetAsNotInBs( const vector &as, const vector &bs, vector &difference ) +{ + vector bsUnmatched = bs; + FOREACH_CONST( T, as, a ) + { + vector::iterator iter = find( bsUnmatched.begin(), bsUnmatched.end(), *a ); + if( iter != bsUnmatched.end() ) + bsUnmatched.erase( iter ); + else + difference.push_back( *a ); + } +} + +template +void GetConnectsDisconnects( const vector &before, const vector &after, vector &disconnects, vector &connects ) +{ + GetAsNotInBs( before, after, disconnects ); + GetAsNotInBs( after, before, connects ); +} + #endif /* diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 23de24dc69..4e418da2a7 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -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 vDevices; - vector vDescriptions; - INPUTMAN->GetDevicesAndDescriptions(vDevices,vDescriptions); - CString sInputDevices = join( ",", vDescriptions ); + vector 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 vsLastSeen; + split( PREFSMAN->m_sLastSeenInputDevices, ",", vsLastSeen ); + + vector 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. */ diff --git a/stepmania/src/arch/InputHandler/InputHandler_DirectInput.cpp b/stepmania/src/arch/InputHandler/InputHandler_DirectInput.cpp index 53e8e55186..f778bde89c 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_DirectInput.cpp +++ b/stepmania/src/arch/InputHandler/InputHandler_DirectInput.cpp @@ -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() diff --git a/stepmania/src/arch/InputHandler/InputHandler_DirectInput.h b/stepmania/src/arch/InputHandler/InputHandler_DirectInput.h index a9eca8c320..3e14aa7638 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_DirectInput.h +++ b/stepmania/src/arch/InputHandler/InputHandler_DirectInput.h @@ -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 ); diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp index 84babdcad5..f612b966d4 100644 --- a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp @@ -8,21 +8,6 @@ #include #include -template -bool VectorsAreEqual( const T &a, const T &b ) -{ - if( a.size() != b.size() ) - return false; - - for( unsigned i=0; isOsMountDir, W_OK) == -1 ) diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp index cc125f3531..d9d5e986ec 100644 --- a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp @@ -94,6 +94,9 @@ void MemoryCardDriverThreaded_Windows::GetUSBStorageDevices( vector