diff --git a/stepmania/src/Makefile.am b/stepmania/src/Makefile.am index 827485427e..23b2bdd1a5 100644 --- a/stepmania/src/Makefile.am +++ b/stepmania/src/Makefile.am @@ -114,6 +114,9 @@ Lights = arch/Lights/LightsDriver.h \ arch/Lights/LightsDriver_LinuxSerial.cpp arch/Lights/LightsDriver_LinuxSerial.h \ arch/Lights/LightsDriver_SystemMessage.cpp arch/Lights/LightsDriver_SystemMessage.h +Lights = arch/MemoryCard/MemoryCardDriver.h \ + arch/MemoryCard/MemoryCardDriver_Linux.cpp arch/MemoryCard/MemoryCardDriver_Linux.h + LowLevelWindow = arch/LowLevelWindow/LowLevelWindow.h \ arch/LowLevelWindow/LowLevelWindow_SDL.cpp arch/LowLevelWindow/LowLevelWindow_SDL.h diff --git a/stepmania/src/MemoryCardManager.cpp b/stepmania/src/MemoryCardManager.cpp index 4b527ab8f4..48e5486d6d 100644 --- a/stepmania/src/MemoryCardManager.cpp +++ b/stepmania/src/MemoryCardManager.cpp @@ -12,296 +12,102 @@ */ #include "MemoryCardManager.h" +#include "arch/MemoryCard/MemoryCardDriver.h" // for UsbStorageDevice +#include "arch/arch.h" +#include "ScreenManager.h" MemoryCardManager* MEMCARDMAN = NULL; // global and accessable from anywhere in our program -// -// TODO: Change this to use arch/driver format -// -#ifdef LINUX +vector g_StorageDevices; - #include - #include "RageLog.h" - #include "RageUtil.h" - #include "ScreenManager.h" - #include - #include - #include - #include - - static const char *USB_DEVICE_LIST_FILE = "/proc/bus/usb/devices"; - static int g_fds = -1; - static time_t g_last_mtime = 0; - - struct UsbStorageDevice +MemoryCardManager::MemoryCardManager() +{ + m_pDriver = MakeMemoryCardDriver(); + m_bCardsLocked = false; + for( int p=0; p g_StorageDevices; - - void UpdateAttachedUsbStorageDevices() - { - vector &vDevicesOut = g_StorageDevices; - - vDevicesOut.clear(); - - { - // Find all attached USB devices. Output looks like: - - // T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 - // B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0 - // D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 - // P: Vendor=0000 ProdID=0000 Rev= 0.00 - // S: Product=USB UHCI Root Hub - // S: SerialNumber=ff80 - // C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA - // I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub - // E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms - // T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 - // D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 - // P: Vendor=04e8 ProdID=0100 Rev= 0.01 - // S: Manufacturer=KINGSTON - // S: Product=USB DRIVE - // S: SerialNumber=1125198948886 - // C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr= 90mA - // I: If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage - // E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms - // E: Ad=03(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms - - ifstream f; - CString fn = "/proc/bus/usb/devices"; - f.open(fn); - if( !f.is_open() ) - { - LOG->Warn( "can't open '%s'", fn.c_str() ); - return; - } - - UsbStorageDevice usbd; - CString sLine; - while( getline(f, sLine) ) - { - int iRet, iThrowAway; - - // T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 - int iBus, iPort, iDevice; - iRet = sscanf( sLine.c_str(), "T: Bus=%d Lev=%d Prnt=%d Port=%d Cnt=%d Dev#=%d Spd=%d MxCh=%d", &iBus, &iThrowAway, &iThrowAway, &iPort, &iThrowAway, &iDevice, &iThrowAway, &iThrowAway ); - if( iRet == 8 ) - { - usbd.iBus = iBus; - usbd.iDeviceOnBus = iDevice; - usbd.iPortOnHub = iPort; - continue; // stop processing this line - } - - // S: SerialNumber=ff80 - char szSerial[1024]; - iRet = sscanf( sLine.c_str(), "S: SerialNumber=%[^\n]", szSerial ); - if( iRet == 1 ) - { - usbd.sSerial = szSerial; - continue; // stop processing this line - } - - // I: If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage - int iClass; - iRet = sscanf( sLine.c_str(), "I: If#=%d Alt=%d #EPs=%d Cls=%d", &iThrowAway, &iThrowAway, &iThrowAway, &iClass ); - if( iRet == 4 ) - { - if( iClass == 8 ) // storage class - vDevicesOut.push_back( usbd ); - continue; // stop processing this line - } - } - } - - { - // Find the usb-storage device index for all storage class devices. - for( unsigned i=0; iWarn( "can't open '%s'", fn.c_str() ); - return; - } - - CString sLine; - while( getline(f, sLine) ) - { - // Serial Number: 1125198948886 - char szSerial[1024]; - int iRet = sscanf( sLine.c_str(), "Serial Number: %[^\n]", szSerial ); - if( iRet == 1 ) // we found our line - { - usbd.iUsbStorageIndex = i; - break; // stop looking - } - } - } - } - - { - // Find where each device is mounted. Output looks like: - - // /dev/sda1 /mnt/flash1 auto noauto,owner 0 0 - // /dev/sdb1 /mnt/flash2 auto noauto,owner 0 0 - // /dev/sdc1 /mnt/flash3 auto noauto,owner 0 0 - - CString fn = "/etc/fstab"; - ifstream f; - f.open(fn); - if( !f.is_open() ) - { - LOG->Warn( "can't open '%s'", fn.c_str() ); - return; - } - - CString sLine; - while( getline(f, sLine) ) - { - // /dev/sda1 /mnt/flash1 auto noauto,owner 0 0 - char cScsiDev; - char szMountPoint[1024]; - int iRet = sscanf( sLine.c_str(), "/dev/sd%c1 %s", &cScsiDev, szMountPoint ); - if( iRet != 2 ) - continue; // don't process this line - - int iUsbStorageIndex = cScsiDev - 'a'; - CString sMountPoint = szMountPoint; - TrimLeft( sMountPoint ); - TrimRight( sMountPoint ); - - // search for the usb-storage device corresponding to the SCSI device - for( unsigned i=0; iStorageDevicesChanged() ) { - g_fds = open(USB_DEVICE_LIST_FILE, O_RDONLY); - ASSERT( g_fds != -1 ); - } + vector vOld = g_StorageDevices; // make a copy + m_pDriver->GetStorageDevices( g_StorageDevices ); + vector &vNew = g_StorageDevices; - MemoryCardManager::~MemoryCardManager() - { - if( g_fds != -1 ) + unsigned i; + + // check for disconnects + for( i=0; iSystemMessage( ssprintf("Disconnected bus %d port %d device %d path %s", old.iBus, old.iPortOnHub, old.iDeviceOnBus, old.sOsMountDir.c_str()) ); + } + + // check for connects + for( i=0; iSystemMessage( ssprintf("Connected bus %d port %d device %d path %s", newd.iBus, newd.iPortOnHub, newd.iDeviceOnBus, newd.sOsMountDir.c_str()) ); } } +} +MemoryCardManager::CardState MemoryCardManager::GetCardState( PlayerNumber pn ) +{ + if( m_pDevice[pn] == NULL ) + return no_card; + else if( m_bTooLate[pn] ) + return too_late; + else if( m_bWriteError[pn] ) + return write_error; + else + return ready; +} - bool UsbChanged() +CString MemoryCardManager::GetOsMountDir( PlayerNumber pn ) +{ + if( m_pDevice[pn] == NULL ) + return ""; + else + return m_pDevice[pn]->sOsMountDir; +} + +void MemoryCardManager::LockCards( bool bLock ) +{ + if( bLock == m_bCardsLocked ) + return; // redundant + + m_bCardsLocked = bLock; + + if( bLock ) { - // has USB_DEVICE_LIST_FILE changed? - if( g_fds == -1 ) - return false; - - struct stat st; - if( fstat(g_fds, &st) == -1 ) + // try mounting + for( int p=0; pWarn( "stat failed." ); - return false; - } - - bool bChanged = st.st_mtime != g_last_mtime; - g_last_mtime = st.st_mtime; - - return bChanged; - } - - void MemoryCardManager::Update( float fDelta ) - { - if( UsbChanged() ) - { - vector vOld = g_StorageDevices; // make a copy - UpdateAttachedUsbStorageDevices(); - vector &vNew = g_StorageDevices; - - unsigned i; - - // check for disconnects - for( i=0; iSystemMessage( ssprintf("Disconnected bus %d port %d device %d path %s", old.iBus, old.iPortOnHub, old.iDeviceOnBus, old.sOsMountDir.c_str()) ); - } - - // check for connects - for( i=0; iSystemMessage( ssprintf("Connected bus %d port %d device %d path %s", newd.iBus, newd.iPortOnHub, newd.iDeviceOnBus, newd.sOsMountDir.c_str()) ); - } + if( m_pDevice[p] ) + m_bWriteError[p] = m_pDriver->MountAndTestWrite( m_pDevice[p] ); } } + else + { + // clear error flags + for( int p=0; p -# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# Microsoft Developer Studio Generated Build File, Format Version 60000 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Application" 0x0101 @@ -65,7 +65,7 @@ IntDir=.\../Debug6 TargetDir=\stepmania\stepmania\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -82,24 +82,28 @@ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -XBCP=xbecopy.exe -# ADD BASE XBCP /NOLOGO -# ADD XBCP /NOLOGO -XBE=imagebld.exe -# ADD BASE XBE /nologo /stack:0x10000 /debug -# ADD XBE /nologo /stack:0x10000 /debug /out:"../default.xbe" -LINK32=link.exe -# ADD BASE LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /subsystem:xbox /fixed:no /TMP -# ADD LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /nodefaultlib:"libcd" /nodefaultlib:"libcmt" /out:"../StepManiaXbox-debug.exe" /subsystem:xbox /fixed:no /TMP -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo CPP=cl.exe # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_XBOX" /D "_DEBUG" /YX /FD /G6 /Ztmp /c # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /D "OGG_ONLY" /YX /FD /G6 /Ztmp /c +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /subsystem:xbox /fixed:no /TMP +# ADD LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /nodefaultlib:"libcd" /nodefaultlib:"libcmt" /out:"../StepManiaXbox-debug.exe" /subsystem:xbox /fixed:no /TMP +XBE=imagebld.exe +# ADD BASE XBE /nologo /stack:0x10000 /debug +# ADD XBE /nologo /stack:0x10000 /debug /out:"../default.xbe" +XBCP=xbecopy.exe +# ADD BASE XBCP /NOLOGO +# ADD XBCP /NOLOGO # Begin Special Build Tool -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp \ - /Fo$(IntDir)\ +IntDir=.\Debug +TargetDir=\stepmania\stepmania +TargetName=default +SOURCE="$(InputPath)" +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp \ + /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -132,14 +136,14 @@ BSC32=bscmake.exe LINK32=link.exe # ADD BASE LINK32 $(intdir)\verstub.obj kernel32.lib gdi32.lib shell32.lib user32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /pdb:"../release6/StepMania.pdb" /map /debug /machine:I386 # SUBTRACT BASE LINK32 /verbose /pdb:none -# ADD LINK32 $(intdir)\verstub.obj kernel32.lib gdi32.lib shell32.lib user32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"../../itg/Program/StepMania.exe" +# ADD LINK32 $(intdir)\verstub.obj kernel32.lib gdi32.lib shell32.lib user32.lib advapi32.lib winmm.lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"../Program/StepMania.exe" # SUBTRACT LINK32 /verbose /pdb:none # Begin Special Build Tool IntDir=.\../Release6 -TargetDir=\stepmania\itg\Program +TargetDir=\stepmania\stepmania\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -157,27 +161,31 @@ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania # PROP Intermediate_Dir "StepMania___Xbox_Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -XBCP=xbecopy.exe -# ADD BASE XBCP /NOLOGO -# ADD XBCP /NOLOGO -XBE=imagebld.exe -# ADD BASE XBE /nologo /stack:0x10000 /debug -# ADD XBE /nologo /testid:"123456" /stack:0x10000 /debug /out:"../default.xbe" +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /Fr /YX"global.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "NDEBUG" /YX"global.h" /FD /c +# SUBTRACT CPP /Fr +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 $(intdir)\verstub.obj xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /pdb:"../debug6/StepMania-debug.pdb" /map /debug /machine:IX86 /nodefaultlib:"libcmtd.lib" /out:"../StepMania-debug.exe" # SUBTRACT BASE LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib # ADD LINK32 $(intdir)\verstub.obj xapilib.lib d3d8.lib d3dx8.lib xgraphics.lib dsound.lib dmusic.lib xnet.lib xboxkrnl.lib libcmt.lib /nologo /incremental:no /pdb:"../release6xbox/StepMania.pdb" /machine:I386 /nodefaultlib:"libc" /nodefaultlib:"libcmtd" /out:"../StepManiaXbox.exe" /subsystem:xbox /fixed:no /TMP /OPT:REF # SUBTRACT LINK32 /pdb:none /map /debug -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -CPP=cl.exe -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /Fr /YX"global.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "NDEBUG" /YX"global.h" /FD /c -# SUBTRACT CPP /Fr +XBE=imagebld.exe +# ADD BASE XBE /nologo /stack:0x10000 /debug +# ADD XBE /nologo /testid:"123456" /stack:0x10000 /debug /out:"../default.xbe" +XBCP=xbecopy.exe +# ADD BASE XBCP /NOLOGO +# ADD XBCP /NOLOGO # Begin Special Build Tool -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp \ - /Fo$(IntDir)\ +IntDir=.\StepMania___Xbox_Release +TargetDir=\stepmania\stepmania +TargetName=default +SOURCE="$(InputPath)" +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp \ + /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -2191,6 +2199,25 @@ SOURCE=.\arch\InputHandler\InputHandler_SDL.h # End Source File # Begin Source File +SOURCE=.\arch\InputHandler\InputHandler_Win32_Para.cpp + +!IF "$(CFG)" == "StepMania - Win32 Debug" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Debug" + +!ELSEIF "$(CFG)" == "StepMania - Win32 Release" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\arch\InputHandler\InputHandler_Win32_Para.h +# End Source File +# Begin Source File + SOURCE=.\arch\InputHandler\InputHandler_Win32_Pump.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" @@ -2432,6 +2459,18 @@ SOURCE=.\arch\Lights\LightsDriver_Win32Parallel.cpp SOURCE=.\arch\Lights\LightsDriver_Win32Parallel.h # End Source File # End Group +# Begin Group "MemoryCard" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\arch\MemoryCard\MemoryCardDriver.h +# End Source File +# Begin Source File + +SOURCE=.\arch\MemoryCard\MemoryCardDriver_Null.h +# End Source File +# End Group # Begin Source File SOURCE=.\arch\arch.cpp diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index c9bbd29f1d..d4a35858e0 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -992,6 +992,16 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ RelativePath="arch\Lights\LightsDriver_Win32Parallel.h"> + + + + + + & vStorageDevicesOut ) = 0; + virtual bool MountAndTestWrite( UsbStorageDevice* pDevice ) = 0; // return false if mount or write fails + virtual void Unmount( UsbStorageDevice* pDevice ) = 0; +}; + +#endif + +/* + * Copyright (c) 2003 by the person(s) listed below. All rights reserved. + * Chris Danford + */ diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriver_Linux.cpp b/stepmania/src/arch/MemoryCard/MemoryCardDriver_Linux.cpp new file mode 100644 index 0000000000..4ee5d5ca7b --- /dev/null +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriver_Linux.cpp @@ -0,0 +1,239 @@ +#include "global.h" +#include "MemoryCardDriver_Linux.h" + +#include +#include "RageLog.h" +#include "RageUtil.h" +#include +#include +#include +#include + +static const char *USB_DEVICE_LIST_FILE = "/proc/bus/usb/devices"; + +MemoryCardDriver_Linux::MemoryCardDriver_Linux() +{ + m_lastModTime = 0; + m_fds = open(USB_DEVICE_LIST_FILE, O_RDONLY); + if( m_fds == -1 ) + LOG->Warn( "Failed to open '%s'", USB_DEVICE_LIST_FILE ); +} + +MemoryCardDriver_Linux::~MemoryCardDriver_Linux() +{ + if( m_fds != -1 ) + { + close( m_fds ); + m_fds = -1; + } +} + +bool MemoryCardDriver_Linux::StorageDevicesChanged() +{ + // has USB_DEVICE_LIST_FILE changed? + if( g_fds == -1 ) // file not opened + return false; // we'll never know... + + struct stat st; + if( fstat(g_fds, &st) == -1 ) + { + LOG->Warn( "stat of '%s' failed.", USB_DEVICE_LIST_FILE ); + return false; + } + + bool bChanged = st.st_mtime != m_lastModTime; + m_lastModTime = st.st_mtime; + + return bChanged; +} + +void MemoryCardDriver_Linux::GetStorageDevices( vector& vDevicesOut ) +{ + vDevicesOut.clear(); + + { + // Find all attached USB devices. Output looks like: + + // T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 + // B: Alloc= 0/900 us ( 0%), #Int= 0, #Iso= 0 + // D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 + // P: Vendor=0000 ProdID=0000 Rev= 0.00 + // S: Product=USB UHCI Root Hub + // S: SerialNumber=ff80 + // C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA + // I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub + // E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms + // T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 + // D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 + // P: Vendor=04e8 ProdID=0100 Rev= 0.01 + // S: Manufacturer=KINGSTON + // S: Product=USB DRIVE + // S: SerialNumber=1125198948886 + // C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr= 90mA + // I: If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage + // E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms + // E: Ad=03(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms + + ifstream f; + CString fn = "/proc/bus/usb/devices"; + f.open(fn); + if( !f.is_open() ) + { + LOG->Warn( "can't open '%s'", fn.c_str() ); + return; + } + + UsbStorageDevice usbd; + CString sLine; + while( getline(f, sLine) ) + { + int iRet, iThrowAway; + + // T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 + int iBus, iPort, iDevice; + iRet = sscanf( sLine.c_str(), "T: Bus=%d Lev=%d Prnt=%d Port=%d Cnt=%d Dev#=%d Spd=%d MxCh=%d", &iBus, &iThrowAway, &iThrowAway, &iPort, &iThrowAway, &iDevice, &iThrowAway, &iThrowAway ); + if( iRet == 8 ) + { + usbd.iBus = iBus; + usbd.iDeviceOnBus = iDevice; + usbd.iPortOnHub = iPort; + continue; // stop processing this line + } + + // S: SerialNumber=ff80 + char szSerial[1024]; + iRet = sscanf( sLine.c_str(), "S: SerialNumber=%[^\n]", szSerial ); + if( iRet == 1 ) + { + usbd.sSerial = szSerial; + continue; // stop processing this line + } + + // I: If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage + int iClass; + iRet = sscanf( sLine.c_str(), "I: If#=%d Alt=%d #EPs=%d Cls=%d", &iThrowAway, &iThrowAway, &iThrowAway, &iClass ); + if( iRet == 4 ) + { + if( iClass == 8 ) // storage class + vDevicesOut.push_back( usbd ); + continue; // stop processing this line + } + } + } + + { + // Find the usb-storage device index for all storage class devices. + for( unsigned i=0; iWarn( "can't open '%s'", fn.c_str() ); + return; + } + + CString sLine; + while( getline(f, sLine) ) + { + // Serial Number: 1125198948886 + char szSerial[1024]; + int iRet = sscanf( sLine.c_str(), "Serial Number: %[^\n]", szSerial ); + if( iRet == 1 ) // we found our line + { + usbd.iUsbStorageIndex = i; + break; // stop looking + } + } + } + } + + { + // Find where each device is mounted. Output looks like: + + // /dev/sda1 /mnt/flash1 auto noauto,owner 0 0 + // /dev/sdb1 /mnt/flash2 auto noauto,owner 0 0 + // /dev/sdc1 /mnt/flash3 auto noauto,owner 0 0 + + CString fn = "/etc/fstab"; + ifstream f; + f.open(fn); + if( !f.is_open() ) + { + LOG->Warn( "can't open '%s'", fn.c_str() ); + return; + } + + CString sLine; + while( getline(f, sLine) ) + { + // /dev/sda1 /mnt/flash1 auto noauto,owner 0 0 + char cScsiDev; + char szMountPoint[1024]; + int iRet = sscanf( sLine.c_str(), "/dev/sd%c1 %s", &cScsiDev, szMountPoint ); + if( iRet != 2 ) + continue; // don't process this line + + int iUsbStorageIndex = cScsiDev - 'a'; + CString sMountPoint = szMountPoint; + TrimLeft( sMountPoint ); + TrimRight( sMountPoint ); + + // search for the usb-storage device corresponding to the SCSI device + for( unsigned i=0; isOsMountDir.empty() ) + return false; + CString sCommand = "mount " + usbd.sOsMountDir; + system( sCommand ); + + // Try to write a file. + // TODO: Can we use RageFile for this? + const CString sFile = "temp"; + int fd = open( sFile, O_WRONLY|O_CREAT|O_TRUNC ); + if( fd == -1 ) + return false; + close( fd ); + remove( sFile ); + + return true; +} + +void MemoryCardDriver_Linux::Unmount( UsbStorageDevice* pDevice ) +{ + if( !pDevice->sOsMountDir.empty() ) + return; + CString sCommand = "umount " + usbd.sOsMountDir; + system( sCommand ); +} + +/* + * Copyright (c) 2003 by the person(s) listed below. All rights reserved. + * Chris Danford + */ diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriver_Linux.h b/stepmania/src/arch/MemoryCard/MemoryCardDriver_Linux.h new file mode 100644 index 0000000000..ec50fff0c8 --- /dev/null +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriver_Linux.h @@ -0,0 +1,23 @@ +#ifndef MEMORY_CARD_DRIVER_LINUX_H +#define MEMORY_CARD_DRIVER_LINUX_H 1 + +class MemoryCardDriver_Linux : public MemoryCardDriver +{ +public: + MemoryCardDriver_Linux(); + virtual ~MemoryCardDriver_Linux(); + virtual bool StorageDevicesChanged(); + virtual void GetStorageDevices( vector& vStorageDevicesOut ); + virtual bool MountAndTestWrite( UsbStorageDevice* pDevice ); + virtual void Unmount( UsbStorageDevice* pDevice ); +protected: + int m_fds; + time_t m_lastModTime; +}; + +#endif + +/* + * Copyright (c) 2003 by the person(s) listed below. All rights reserved. + * Chris Danford + */ diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriver_Null.h b/stepmania/src/arch/MemoryCard/MemoryCardDriver_Null.h new file mode 100644 index 0000000000..e7d49cd860 --- /dev/null +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriver_Null.h @@ -0,0 +1,21 @@ +#ifndef MEMORY_CARD_ENUMERATOR_NULL_H +#define MEMORY_CARD_ENUMERATOR_NULL_H 1 + +#include "MemoryCardDriver.h" + +class MemoryCardDriver_Null : public MemoryCardDriver +{ +public: + MemoryCardDriver_Null() {}; + virtual bool StorageDevicesChanged() { return false; }; + virtual void GetStorageDevices( vector& vStorageDevicesOut ) {}; + virtual bool MountAndTestWrite( UsbStorageDevice* pDevice ) { return false; }; + virtual void Unmount( UsbStorageDevice* pDevice ) {}; +}; + +#endif + +/* + * Copyright (c) 2003 by the person(s) listed below. All rights reserved. + * Chris Danford + */ diff --git a/stepmania/src/arch/arch.cpp b/stepmania/src/arch/arch.cpp index ac09f8f8ca..a8e7183a71 100644 --- a/stepmania/src/arch/arch.cpp +++ b/stepmania/src/arch/arch.cpp @@ -165,6 +165,20 @@ LightsDriver *MakeLightsDriver(CString driver) return ret; } +/* Err, this is ugly--breaks arch encapsulation. Hmm. */ +MemoryCardDriver *MakeMemoryCardDriver() +{ + MemoryCardDriver *ret = NULL; + +#ifdef LINUX + ret = new MemoryCardDriver_Linux; +#endif + if( !ret ) + ret = new MemoryCardDriver_Null; + + return ret; +} + /* * Copyright (c) 2002 by the person(s) listed below. All rights reserved. * diff --git a/stepmania/src/arch/arch.h b/stepmania/src/arch/arch.h index 1f86e4d7f9..7917ed5158 100644 --- a/stepmania/src/arch/arch.h +++ b/stepmania/src/arch/arch.h @@ -8,6 +8,7 @@ class ArchHooks; class InputHandler; class LowLevelWindow; class LightsDriver; +class MemoryCardDriver; LoadingWindow *MakeLoadingWindow(); ArchHooks *MakeArchHooks(); @@ -16,6 +17,7 @@ LowLevelWindow *MakeLowLevelWindow(); void MakeInputHandlers(vector &Add); RageSoundDriver *MakeRageSoundDriver(CString drivers); LightsDriver *MakeLightsDriver(CString driver); +MemoryCardDriver *MakeMemoryCardDriver(); /* These definitions are in here, instead of in arch_*.h, because they * need to be available to other modules. It'd be overkill to create separate diff --git a/stepmania/src/arch/arch_default.h b/stepmania/src/arch/arch_default.h index 2764120f0a..c83319f0c1 100644 --- a/stepmania/src/arch/arch_default.h +++ b/stepmania/src/arch/arch_default.h @@ -35,6 +35,7 @@ #include "Sound/RageSoundDriver_Null.h" #include "Lights/LightsDriver_Null.h" #include "Lights/LightsDriver_SystemMessage.h" +#include "MemoryCard/MemoryCardDriver_Null.h" #if defined(SUPPORT_OPENGL) #include "LowLevelWindow/LowLevelWindow_SDL.h" diff --git a/stepmania/src/arch/arch_linux.h b/stepmania/src/arch/arch_linux.h index 6dd4784df8..359758c580 100644 --- a/stepmania/src/arch/arch_linux.h +++ b/stepmania/src/arch/arch_linux.h @@ -21,6 +21,8 @@ #include "Lights/LightsDriver_LinuxSerial.h" +#include "Lights/MemoryCardEnumerator_Linux.h" + #endif /* * Copyright (c) 2002-2003 by the person(s) listed below. All rights reserved.