From fab5c0fe20ecf0294ce5365f081943d4b008b07b Mon Sep 17 00:00:00 2001 From: Mark Cannon Date: Mon, 4 Aug 2008 04:36:23 +0000 Subject: [PATCH] Added PacDrive lights driver, some minor fixups git-svn-id: https://openitg.svn.sourceforge.net/svnroot/openitg@472 83fadc84-e282-4d84-a09a-c4228d6ae7e5 --- src/CoinQueue.h | 2 +- src/LightsManager.cpp | 1 + src/LightsManager.h | 1 - src/Makefile.am | 4 +- src/ScreenGameplay.cpp | 4 -- src/arch/InputHandler/InputHandler_X11.cpp | 4 ++ src/arch/InputHandler/Selector_InputHandler.h | 1 + src/arch/Lights/LightsDriver_PacDrive.cpp | 93 +++++++++++++++++++++++++++ src/arch/Lights/LightsDriver_PacDrive.h | 46 +++++++++++++ src/arch/Lights/Selector_LightsDriver.h | 1 + src/arch/arch.cpp | 4 +- src/io/PacDrive.cpp | 69 ++++++++++++++++++++ src/io/PacDrive.h | 41 ++++++++++++ src/io/USBDriver.cpp | 22 +++++++ 14 files changed, 285 insertions(+), 8 deletions(-) create mode 100644 src/arch/Lights/LightsDriver_PacDrive.cpp create mode 100644 src/arch/Lights/LightsDriver_PacDrive.h create mode 100644 src/io/PacDrive.cpp create mode 100644 src/io/PacDrive.h diff --git a/src/CoinQueue.h b/src/CoinQueue.h index afede341..83c68604 100644 --- a/src/CoinQueue.h +++ b/src/CoinQueue.h @@ -2,7 +2,7 @@ #define COINQUEUE_H // Experimental data type to reconcile coins entered during loads -// on threaded drivers (which are usually lost). +// on threaded drivers (which are potentially lost). class CoinQueue { diff --git a/src/LightsManager.cpp b/src/LightsManager.cpp index b392946b..3691d75c 100755 --- a/src/LightsManager.cpp +++ b/src/LightsManager.cpp @@ -1,4 +1,5 @@ #include "global.h" +#include "RageLog.h" #include "RageUtil.h" #include "RageTimer.h" #include "RageThreads.h" diff --git a/src/LightsManager.h b/src/LightsManager.h index 0d93ac95..e6d5f1d7 100755 --- a/src/LightsManager.h +++ b/src/LightsManager.h @@ -3,7 +3,6 @@ #ifndef LightsManager_H #define LightsManager_H -#include "RageLog.h" // XXX #include "RageThreads.h" #include "PlayerNumber.h" #include "GameInput.h" diff --git a/src/Makefile.am b/src/Makefile.am index 95474f10..fa83d570 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -118,6 +118,7 @@ LIBS += -lusb DataStructures += io/USBDriver.cpp io/USBDriver.h \ io/PIUIO.cpp io/PIUIO.h \ io/ITGIO.cpp io/ITGIO.h \ + io/PacDrive.cpp io/PacDrive.h \ io/USBDevice.h # these both use the same .h file @@ -168,7 +169,8 @@ MovieTexture = arch/MovieTexture/MovieTexture.cpp arch/MovieTexture/MovieTexture Lights = arch/Lights/LightsDriver.h \ arch/Lights/LightsDriver_SystemMessage.cpp arch/Lights/LightsDriver_SystemMessage.h \ - arch/Lights/LightsDriver_External.cpp arch/Lights/LightsDriver_External.h + arch/Lights/LightsDriver_External.cpp arch/Lights/LightsDriver_External.h \ + arch/Lights/LightsDriver_PacDrive.cpp arch/Lights/LightsDriver_PacDrive.h MemoryCard = arch/MemoryCard/MemoryCardDriver.cpp arch/MemoryCard/MemoryCardDriver.h LowLevelWindow = arch/LowLevelWindow/LowLevelWindow.h diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index 7bcf663e..aae9bd4d 100755 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -65,10 +65,6 @@ #define COMPARE_SCORES THEME->GetMetricB(m_sName, "CompareScores" ) // set an adjusted limit based off the song allowance -// XXX: if OpenITG crashes, blame this first. -// -// YYY: yes, it crashes because a const variable was assigned a value from -// a non const field, so I turned it into a macro for the time being --infamouspat #define MAX_CUSTOM_LENGTH ((float)(PREFSMAN->m_iCustomMaxSeconds + 10)) static ThemeMetric INITIAL_BACKGROUND_BRIGHTNESS ("ScreenGameplay","InitialBackgroundBrightness"); diff --git a/src/arch/InputHandler/InputHandler_X11.cpp b/src/arch/InputHandler/InputHandler_X11.cpp index f63d85f0..e3002773 100755 --- a/src/arch/InputHandler/InputHandler_X11.cpp +++ b/src/arch/InputHandler/InputHandler_X11.cpp @@ -129,6 +129,8 @@ InputHandler_X11::InputHandler_X11() XGetKeyboardControl( X11Helper::Dpy, &InitialState ); m_iRepeatSetting = InitialState.global_auto_repeat; + LOG->Warn( "Initial state: %i", m_iRepeatSetting ); + XKeyboardControl state; state.auto_repeat_mode = AutoRepeatModeOff; XChangeKeyboardControl( X11Helper::Dpy, KBAutoRepeatMode, &state ); @@ -140,6 +142,8 @@ InputHandler_X11::~InputHandler_X11() { XKeyboardControl state; state.auto_repeat_mode = m_iRepeatSetting; + LOG->Warn( "Setting state: %i", state.auto_repeat_mode ); + XChangeKeyboardControl( X11Helper::Dpy, KBAutoRepeatMode, &state ); X11Helper::CloseMask(KeyPressMask); X11Helper::CloseMask(KeyReleaseMask); X11Helper::Stop(); diff --git a/src/arch/InputHandler/Selector_InputHandler.h b/src/arch/InputHandler/Selector_InputHandler.h index 0a9d3d8b..5675b078 100755 --- a/src/arch/InputHandler/Selector_InputHandler.h +++ b/src/arch/InputHandler/Selector_InputHandler.h @@ -11,6 +11,7 @@ // These are confirmed cross-platform #include "InputHandler_Iow.h" #include "InputHandler_PIUIO.h" +#include "InputHandler_MK6IO.h" #ifdef HAVE_LINUXKERNEL #include "InputHandler_Linux_Joystick.h" diff --git a/src/arch/Lights/LightsDriver_PacDrive.cpp b/src/arch/Lights/LightsDriver_PacDrive.cpp new file mode 100644 index 00000000..e37abf54 --- /dev/null +++ b/src/arch/Lights/LightsDriver_PacDrive.cpp @@ -0,0 +1,93 @@ +// Cross-platform, libusb-based driver for outputting lights +// via a PacDrive (http://www.ultimarc.com/pacdrive.html) + +#include "global.h" +#include "RageLog.h" +#include "io/PacDrive.h" +#include "LightsDriver_PacDrive.h" + +LightsDriver_PacDrive::LightsDriver_PacDrive() +{ + m_bHasDevice = Board.Open(); + + if( m_bHasDevice == false ) + { + LOG->Warn( "Could not establish a connection with PacDrive." ); + return; + } + + // clear all lights + Board.Write( 0 ); +} + +LightsDriver_PacDrive::~LightsDriver_PacDrive() +{ + if( !m_bHasDevice ) + return; + + // clear all lights and close the connection + Board.Write( 0 ); + Board.Close(); +} + +void LightsDriver_PacDrive::Set( const LightsState *ls ) +{ + if( !m_bHasDevice ) + return; + + uint8_t iCabinetData = 0; + uint8_t iPadData = 0; + + // Lights 1 - 8 are used for the cabinet lights + FOREACH_CabinetLight( cl ) + if( ls->m_bCabinetLights[cl] ) + iCabinetData |= (1 << cl); + + LOG->Debug( "iCabinetData: %#2x", iCabinetData ); + + // Lights 9-13 for P1 pad, 14-18 for P2 pad + // FIXME: make this work for all game-types? + FOREACH_GameController( gc ) + FOREACH_ENUM( GameButton, 4, gb ) + if( ls->m_bGameButtonLights[gc][gb] ) + iPadData |= (1 << (gb + gc*4)); + + LOG->Debug( "iPadData: %#2x", iPadData ); + + // combine the data set above + uint16_t iData = (uint16_t)(iCabinetData << 8) | iPadData; + + LOG->Debug( "Writing %#4x to PacDrive.", iData ); + + // write the data - if it fails, stop updating + if( !Board.Write(iData) ) + { + LOG->Warn( "Lost connection with PacDrive." ); + m_bHasDevice = false; + } +} + +/* + * Copyright (c) 2008 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. + */ diff --git a/src/arch/Lights/LightsDriver_PacDrive.h b/src/arch/Lights/LightsDriver_PacDrive.h new file mode 100644 index 00000000..e4e76c56 --- /dev/null +++ b/src/arch/Lights/LightsDriver_PacDrive.h @@ -0,0 +1,46 @@ +#ifndef LIGHTSDRIVER_PACDRIVE_H +#define LIGHTSDRIVER_PACDRIVE_H + +#include "LightsDriver.h" +#include "io/PacDrive.h" + +class LightsDriver_PacDrive: public LightsDriver +{ +public: + LightsDriver_PacDrive(); + ~LightsDriver_PacDrive(); + + void Set( const LightsState *ls ); +private: + PacDrive Board; + bool m_bHasDevice; +}; + +#define USE_LIGHTS_DRIVER_PACDRIVE + +#endif // LIGHTSDRIVER_PACDRIVE_H + +/* + * Copyright (c) 2008 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. + */ diff --git a/src/arch/Lights/Selector_LightsDriver.h b/src/arch/Lights/Selector_LightsDriver.h index bd8a09f2..3b4b38c7 100755 --- a/src/arch/Lights/Selector_LightsDriver.h +++ b/src/arch/Lights/Selector_LightsDriver.h @@ -13,6 +13,7 @@ #endif #include "LightsDriver_External.h" #include "LightsDriver_SystemMessage.h" +#include "LightsDriver_PacDrive.h" #include "LightsDriver_Null.h" #endif diff --git a/src/arch/arch.cpp b/src/arch/arch.cpp index 86ced7f0..b1795f74 100755 --- a/src/arch/arch.cpp +++ b/src/arch/arch.cpp @@ -53,7 +53,6 @@ void MakeInputHandlers(CString drivers, vector &Add) #endif #ifdef USE_INPUT_HANDLER_PIUIO if(!s->CompareNoCase("PIUIO") ) ret = new InputHandler_PIUIO; -#endif #ifdef USE_INPUT_HANDLER_IOW if(!s->CompareNoCase("IOW") ) ret = new InputHandler_Iow; #endif @@ -78,6 +77,9 @@ void MakeLightsDrivers(CString driver, vector &Add) #ifdef USE_LIGHTS_DRIVER_EXTERNAL if( !driver.CompareNoCase("Ext") ) ret = new LightsDriver_External; #endif +#ifdef USE_LIGHTS_DRIVER_PACDRIVE + if( !driver.CompareNoCase("PacDrive") ) ret = new LightsDriver_PacDrive; +#endif #ifdef USE_LIGHTS_DRIVER_LINUX_PARALLEL if( !driver.CompareNoCase("LinuxParallel") ) ret = new LightsDriver_LinuxParallel; #endif diff --git a/src/io/PacDrive.cpp b/src/io/PacDrive.cpp new file mode 100644 index 00000000..f43ee1a2 --- /dev/null +++ b/src/io/PacDrive.cpp @@ -0,0 +1,69 @@ +#include "global.h" +#include "RageLog.h" +#include "PacDrive.h" + +/* TODO: define these for all USBDriver code. */ +#define HID_GET_REPORT 0x01 +#define HID_SET_REPORT 0x09 + +const int IFACE_IN = 256; +const int IFACE_OUT = 512; + +bool PacDrive::Matches( int idVendor, int idProduct ) const +{ + if( idVendor != 0xd209 ) + return false; + + /* PacDrives have PIDs 1500-1508 */ + if( (idProduct & ~0x07) != 0x1500 ) + return false; + + return true; +} + +/* While waiting for this to reconnect, we would likely run into a condition + * where LightsDriver::Set() is being called constantly and none of the calls + * actually terminate. If this write fails, assume it's lost and don't reconnect. + */ +bool PacDrive::Write( uint16_t iData ) +{ + uint32_t data = (iData << 16); + + LOG->Debug( "%#8x", data ); + + // output is within the first 16 bits - accept a 16-bit arg and cast it, for simplicity's sake. + int iReturn = usb_control_msg( m_pHandle, USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + HID_SET_REPORT, IFACE_OUT, 0, (char *)&data, 4, 10000 ); + + if( iReturn == 4 ) + return true; + + LOG->Warn( "PacDrive writing failed, returned %i: %s", iReturn, usb_strerror() ); + + return false; +} + +/* + * Copyright (c) 2008 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. + */ diff --git a/src/io/PacDrive.h b/src/io/PacDrive.h new file mode 100644 index 00000000..1959e430 --- /dev/null +++ b/src/io/PacDrive.h @@ -0,0 +1,41 @@ +#ifndef IO_PACDRIVE_H +#define IO_PACDRIVE_H + +#include "USBDriver.h" + +class PacDrive: public USBDriver +{ +public: + bool Write( uint16_t iData ); + +protected: + bool Matches( int idVendor, int idProduct ) const; +}; + +#endif /* IO_PACDRIVE_H */ + +/* + * Copyright (c) 2008 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. + */ + diff --git a/src/io/USBDriver.cpp b/src/io/USBDriver.cpp index cab97dc5..1b23c6d2 100644 --- a/src/io/USBDriver.cpp +++ b/src/io/USBDriver.cpp @@ -82,6 +82,28 @@ bool USBDriver::Open() return false; } +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + + // The device may be claimed by a kernel driver. Attempt to reclaim it. + // This macro is self-porting, so no ifdef LINUX should be needed. + LOG->Debug( "USBDriver::Open(): attempting to detach kernel drivers..." ); + + for( unsigned i = 0; i < dev->config->bNumInterfaces; i++ ) + { + int iResult = usb_detach_kernel_driver_np( m_pHandle, i ); + + LOG->Debug( "iResult: %i", iResult ); + + // ignore "No data available" - means there was no driver claiming it + if( iResult != 0 && iResult != -61 ) + { + LOG->Warn( "USBDriver::Open(): usb_detach_kernel_driver_np: %s", usb_strerror() ); + return false; + } + } + +#endif + if ( usb_set_configuration(m_pHandle, dev->config->bConfigurationValue) < 0 ) { LOG->Warn( "USBDriver::Open(): usb_set_configuration: %s", usb_strerror() ); -- 2.11.0