#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
--- /dev/null
+#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;
+}
--- /dev/null
+#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.
+ */