PRODUCT_PLATFORM defined, minor code fixes, libusb-based USBDevice files for Windows...
authorMark Cannon <vyhdycokio@gmail.com>
Wed, 27 Feb 2008 03:20:41 +0000 (03:20 +0000)
committerMark Cannon <vyhdycokio@gmail.com>
Wed, 27 Feb 2008 03:20:41 +0000 (03:20 +0000)
git-svn-id: https://openitg.svn.sourceforge.net/svnroot/openitg@63 83fadc84-e282-4d84-a09a-c4228d6ae7e5

src/GameState.h
src/Makefile.am
src/MiscITG.cpp
src/PrefsManager.cpp
src/ProductInfo.h
src/ScreenArcadeDiagnostics.cpp
src/io/USBDevice_Libusb.cpp [new file with mode: 0755]
src/io/USBDevice_Libusb.h [new file with mode: 0755]
src/io/USBDriver.cpp

index 8bf262a..aebd139 100755 (executable)
@@ -91,8 +91,8 @@ public:
        bool AnyPlayersAreCpu() const;
 
        void GetCharacters( vector<Character*> &apCharactersOut );
-       Character* GameState::GetRandomCharacter();
-       Character* GameState::GetDefaultCharacter();
+       Character* GetRandomCharacter();
+       Character* GetDefaultCharacter();
 
 
        bool IsCourseMode() const;
index cbe27ce..186ab67 100755 (executable)
@@ -114,9 +114,12 @@ LoadingWindow = arch/LoadingWindow/LoadingWindow.h \
 #if HAVE_LIBUSB
 LIBS += -lusb
 DataStructures += io/USBDriver.cpp io/USBDriver.h \
+                 io/USBDevice.cpp io/USBDevice.h \
                  io/PIUIO.cpp io/PIUIO.h
 #endif
 
+
+
 if HAVE_GTK
 LoadingWindow += arch/LoadingWindow/LoadingWindow_Gtk.cpp arch/LoadingWindow/LoadingWindow_Gtk.h
 endif
index 9605a83..5d82742 100644 (file)
@@ -60,7 +60,7 @@ int GetRevision()
        xml->Clear();
        xml->m_sName = "patch";
        
-       bool bLoaded;
+       bool bLoaded = false;
 
        // Check for the file existing
        if( !IsAFile(sPath) )
index fa5ec70..7839a8f 100755 (executable)
 #include "Preference.h"
 #include "RageLog.h"
 
-#define DEFAULTS_INI_PATH      "Data/Defaults.ini"             // these can be overridden
-#define STEPMANIA_INI_PATH     "Data/StepMania.ini"    // overlay on Defaults.ini, contains the user's choices
-#define STATIC_INI_PATH                "Data/Static.ini"               // overlay on the 2 above, can't be overridden
+#ifdef ITG_ARCADE
+#define INI_FOLDER     "Stats/"
+#else
+#define INI_FOLDER     "Data/"
+#endif
+
+#define DEFAULTS_INI_PATH      INI_FOLDER "Defaults.ini"       // these can be overridden
+#define STEPMANIA_INI_PATH     INI_FOLDER "StepMania.ini"      // overlay on Defaults.ini, contains the user's choices
+#define STATIC_INI_PATH                INI_FOLDER "Static.ini"         // overlay on the 2 above, can't be overridden
 
 PrefsManager*  PREFSMAN = NULL;        // global and accessable from anywhere in our program
 
index 074fa57..f6fcd3b 100755 (executable)
@@ -3,23 +3,24 @@
 #ifndef PRODUCT_INFO_H
 #define PRODUCT_INFO_H
 
-// Don't forget to also change ProductInfo.inc!
-
-/* If we're building internal builds for our own use,  *
- * append "DEV-X" to the product version string, "X"   *
- * being the build we've put together. This will help  *
- * us (me) from mixing code versions, and we don't want        *
- * to support problems in dev builds since they're not *
- * official releases and likely have bugs we've fixed. */
+#include "config.h" // for ITG_ARCADE
+
+#if defined(ITG_ARCADE)
+#define PRODUCT_PLATFORM "AC"
+#elif defined(XBOX)
+/* Not likely at all, but might as well be ready for it. */
+#define PRODUCT_PLATFORM "CS" 
+#else
+#define PRODUCT_PLATFORM "PC"
+#endif
 
-/* I guess this is the official name now. :P   --Vyhd  */
+// Don't forget to also change ProductInfo.inc!
 #define PRODUCT_NAME "OpenITG"
 #define PRODUCT_VER "alpha 3"
-#define PRODUCT_SERIAL "ITG-C-12222007-529-3"
 
-#define PRODUCT_NAME_VER PRODUCT_NAME " " PRODUCT_VER
+#define PRODUCT_NAME_VER PRODUCT_NAME " " PRODUCT_PLATFORM " " PRODUCT_VER
 
-/* A central location from which we can update crash handler data. */
+/* A central location from which we can update crash handler data... */
 #define CRASH_REPORT_URL "http://boxorroxors.net/forum/viewtopic.php?t=657"
 
 #endif
index 897940d..a8ef0f7 100644 (file)
@@ -123,10 +123,7 @@ void ScreenArcadeDiagnostics::MenuBack( PlayerNumber pn )
 {
        if(!IsTransitioning())
        {
-               //COMMAND( m_Title, "Off" );
-               //COMMAND( m_USBInfo, "Off" );
-
-               this->PlayCommand( "Off" ); // don't forget m_USBInfo!
+               this->PlayCommand( "Off" );
                StartTransitioning( SM_GoToPrevScreen );                
        }
 }
diff --git a/src/io/USBDevice_Libusb.cpp b/src/io/USBDevice_Libusb.cpp
new file mode 100755 (executable)
index 0000000..1b35bc5
--- /dev/null
@@ -0,0 +1,254 @@
+#include "global.h"
+#include "io/USBDevice.h"
+#include "RageUtil.h"
+#include "RageLog.h"
+#include <cstdlib>
+#include <map>
+#include <usb.h>
+
+static CString sClassDescriptions[] =
+{
+       "Unknown", // 0
+       "Audio", // 1
+       "Communications", // 2
+       "Input", // 3
+       "Unknown", // 4
+       "Unknown", // 5
+       "Camera", // 6
+       "Printer", // 7
+       "Storage", // 8
+       "Hub", // 9
+       "Data" // 10?  Shows up for my Motorola Razr
+};
+
+USBDevice::USBDevice() {}
+
+USBDevice::~USBDevice() {}
+
+/* This isn't as easy to do with libusb as it is with Unix/Linux.
+ * Format, from what I can tell:
+ *     "x-x" = bus, port
+ *     "x-x:x.x" bus, port, config, interface (multi-interface)
+ *     "x-x.x" bus, port, sub-port (child device)
+ *
+ * Please note that isn't implemented yet...
+ * 
+ * XXX: I think "devnum" might be Linux-only. We need to check that out.
+ */
+CString USBDevice::GetDeviceDir()
+{
+       LOG->Warn( "Bus: %i, Device: %i", atoi(m_Device->bus->dirname), m_Device->devnum );
+
+       return ssprintf( "%i-%i", atoi(m_Device->bus->dirname), m_Device->devnum );
+}
+
+CString USBDevice::GetClassDescription( unsigned iClass )
+{
+       if ( iClass == 255 )
+               return "Vendor";
+       if ( iClass > 10)
+               return "Unknown";
+
+       return sClassDescriptions[iClass];
+}
+
+CString USBDevice::GetDescription()
+{
+       if( IsITGIO() || IsPIUIO() )
+               return "Input/lights controller";
+       
+       vector<CString> sInterfaceDescriptions;
+
+       for (unsigned i = 0; i < m_iInterfaceClasses.size(); i++)
+               sInterfaceDescriptions.push_back( GetClassDescription(m_iInterfaceClasses[i]) );
+
+       return join( ", ", sInterfaceDescriptions );
+}
+
+/* Ugly... */
+bool USBDevice::GetDeviceProperty( const CString &sProperty, CString &sOut )
+{
+       if( sProperty == "idVendor" )
+               sOut = ssprintf( "%x", m_Device->descriptor.idVendor );
+       else if( sProperty == "idProduct" )
+               sOut = ssprintf( "%x", m_Device->descriptor.idProduct );
+       else if( sProperty == "bMaxPower" )
+       /* HACK: for some reason, MaxPower is returning half the actual value... */
+               sOut = ssprintf( "%i", m_Device->config->MaxPower*2 );
+//     else if( sProperty == "bDeviceClass" )
+//             sOut = m_Device->descriptor.bDeviceClass;
+       else
+               return false;
+
+       return true;
+}
+
+/* XXX: doesn't get multiple interfaces like the Linux code does. */
+bool USBDevice::GetInterfaceProperty( const CString &sProperty, const unsigned iInterface, CString &sOut )
+{
+       if( (signed)iInterface > m_Device->config->bNumInterfaces )
+       {
+               LOG->Warn( "Cannot access interface %i with USBDevice interface count %i",
+                           iInterface, m_Device->config->bNumInterfaces );
+               return false;
+       }
+
+       if( sProperty == "bInterfaceClass" )
+               sOut = ssprintf( "%i", m_Device->config->interface->altsetting[iInterface].bInterfaceClass );
+       else
+               return false;
+
+       return true;            
+}
+
+bool USBDevice::IsHub()
+{
+       CString sClass;
+
+       if( GetDeviceProperty( "bDeviceClass", sClass ) && atoi(sClass) == 9 )
+               return true;
+
+       for (unsigned i = 0; i < m_iInterfaceClasses.size(); i++)
+               if( m_iInterfaceClasses[i] == 9 )
+                       return true;
+
+       return false;
+}
+
+bool USBDevice::IsITGIO()
+{
+       // return ITGIO::DeviceMatches( m_iIdVendor, m_iIdProduct );
+       if ( m_iIdVendor == 0x7c0 )
+               if ( m_iIdProduct == 0x1501 || m_iIdProduct == 0x1582 || m_iIdProduct == 0x1584)
+                       return true;
+
+       return false;
+}
+
+bool USBDevice::IsPIUIO()
+{
+       // return PIUIO::DeviceMatches( m_iIdVendor, m_iIdProduct );
+       if ( m_iIdVendor == 0x547 && m_iIdProduct == 0x1002 ) return true;
+
+       return false;
+}
+
+bool USBDevice::Load( struct usb_device *dev )
+{
+       m_Device = dev;
+       
+       if( m_Device == NULL )
+       {
+               LOG->Warn( "Invalid usb_device passed to Load()." );
+               return false;
+       }
+
+       CString buf;
+
+       if( GetDeviceProperty("idVendor", buf) )
+               sscanf(buf, "%x", &m_iIdVendor);
+       else
+               m_iIdVendor = -1;
+
+       if( GetDeviceProperty("idProduct", buf) )
+
+               sscanf(buf, "%x", &m_iIdProduct);
+       else
+               m_iIdProduct = -1;
+
+       if( GetDeviceProperty("bMaxPower", buf) )
+               sscanf(buf, "%imA", &m_iMaxPower);
+       else
+               m_iMaxPower = -1;
+
+       if (m_iIdVendor == -1 || m_iIdProduct == -1 || m_iMaxPower == -1)
+       {
+               LOG->Warn( "Could not load USBDevice" );
+               return false;
+       }
+
+       /* Irrelevant USB objects... */
+       if( m_iIdVendor == 0 || m_iIdProduct == 0 )
+               return false;
+
+       for (int i = 0; i < m_Device->config->interface->num_altsetting; i++)
+       {
+               int iClass;
+               if ( GetInterfaceProperty( "bInterfaceClass", i, buf ) )
+                       sscanf( buf, "%i", &iClass );
+               else
+               {
+                       LOG->Warn("Could not read interface %i.", i );
+                       iClass = -1;
+               }
+
+               m_iInterfaceClasses.push_back( iClass );
+       }
+
+       return true;
+}
+
+// this is the diary of a mad man
+/* I'm keeping the checkpoints for now, just to make sure. -- Vyhd */
+bool GetUSBDeviceList(vector<USBDevice> &pDevList)
+{
+       usb_init();
+       usb_find_busses();
+       usb_find_devices();
+       
+       CHECKPOINT_M( "USB initiated" );
+
+       vector<struct usb_device> vDevices;
+       vector<CString> vDeviceDirs;
+
+       CHECKPOINT_M( "Device created" );
+
+       /* get all devices on the system */
+       for( struct usb_bus *bus = usb_busses; bus; bus = bus->next )
+       {
+               if( bus->root_dev )
+                       vDevices.push_back( *bus->root_dev );
+               else
+                       for( struct usb_device *dev = bus->devices; dev; dev->next )
+                               vDevices.push_back( *dev );
+
+               CHECKPOINT_M( ssprintf( "%i devices set", vDevices.size()) );
+       }
+
+       /* get their children - in other cases, this could be an accidental
+        * infinite loop, but here, it works out nicely as a recursion process. */
+       for( unsigned i = 0; i < vDevices.size(); i++ )
+       {
+               for( unsigned j = 0; j < vDevices[i].num_children; j++ )
+               {
+                       /* Talk about a dumb oversight, huh. */
+                       if( vDevices[i].children[j] )
+                               vDevices.push_back( *vDevices[i].children[j] );
+
+                       CHECKPOINT_M( ssprintf("Child %i on %i set", j, i) );
+               }
+       }
+
+       for( unsigned i = 0; i < vDevices.size(); i++ )
+       {
+               CHECKPOINT_M( ssprintf( "Assigning device %i of %i", i, vDevices.size()) );
+               USBDevice newDev;
+
+               LOG->Trace( "Attempting to load from idVendor %x, idProduct %x",
+                       vDevices[i].descriptor.idVendor, 
+                       vDevices[i].descriptor.idProduct );
+
+               if ( newDev.Load( &vDevices[i] ) )
+               {
+                       pDevList.push_back( newDev );
+                       CHECKPOINT_M( ssprintf( "Device %i of %i assigned", i, vDevices.size()) );
+               }
+               else
+               {
+                       if( vDevices[i].descriptor.idVendor != 0 && vDevices[i].descriptor.idProduct != 0 )
+                               LOG->Warn( "Loading failed: %x, %x", vDevices[i].descriptor.idVendor, vDevices[i].descriptor.idProduct );
+               }
+       }
+
+       return true;
+}
diff --git a/src/io/USBDevice_Libusb.h b/src/io/USBDevice_Libusb.h
new file mode 100755 (executable)
index 0000000..032a7ef
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef IO_USBDEVICE_H
+#define IO_USBDEVICE_H
+#include "global.h"
+
+#include <usb.h>
+
+// XXX: we probably need to move this to arch or archutils in preparation for windows portability
+//           --infamouspat
+
+/* A class we can use to characterize all USB devices on the system */
+class USBDevice
+{
+public:
+       USBDevice();
+       ~USBDevice();
+
+       bool Load( struct usb_device *dev );
+
+       bool GetDeviceProperty( const CString &sProperty, CString &out );
+       bool GetInterfaceProperty( const CString &sProperty, const unsigned iInterface, CString &out);
+       CString GetClassDescription( unsigned iClass );
+       CString GetDescription();
+
+       int GetIdVendor() { return m_iIdVendor; }
+       int GetIdProduct() { return m_iIdProduct; }
+       int GetMaxPower() { return m_iMaxPower; }
+
+       CString GetDeviceDir();
+
+       bool IsHub();
+       bool IsITGIO();
+       bool IsPIUIO();
+
+private:
+       int m_iIdVendor;
+       int m_iIdProduct;
+       int m_iMaxPower;
+
+       CString m_sDeviceDir;
+
+       struct usb_device *m_Device;
+
+       vector<CString> m_sInterfaceDeviceDirs;
+       vector<unsigned> m_iInterfaceClasses;
+
+};
+
+bool GetUSBDeviceList(vector<USBDevice> &pDevList);
+
+#endif /* IO_USBDEVICE_H */
+
+/*
+ * (c) 2005 Glenn Maynard reimplemented by nice people @ BoXoRRoXoRs
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons to
+ * whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
index d515a46..e1fc0bc 100644 (file)
@@ -42,12 +42,12 @@ struct usb_device *USBDriver::FindDevice( usb_bus *usb_busses )
 
 void USBDriver::Close()
 {
-       LOG->Trace( "USBDriver::Close()" );
-
        // never opened
        if( m_pHandle == NULL )
                return;
 
+       LOG->Trace( "USBDriver::Close()" );
+
        usb_set_altinterface( m_pHandle, 0 );
        usb_reset( m_pHandle );
        usb_close( m_pHandle );