Basic support for the USB pump pad. It is not HID-compliant and reports strange values when buttons are pressed and released. In particular, it claims that it's values are in the range [0,1], yet actually returns values in the range [0,3]. Also, there are two instances where releasing two buttons sends the same report (UR and MID, as well as DL and DR).

I suspect this makes it pretty much impossible to use (although the guy with the pad has the glowing report of, "and it seemed to work OK") but without actually having a pad with which to test, it's about all I can do.
This commit is contained in:
Steve Checkoway
2006-02-24 13:29:15 +00:00
parent 1b923c5a14
commit c4fde125e4
5 changed files with 191 additions and 6 deletions
@@ -90,6 +90,10 @@
AA1B08400762532800835464 /* Preference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA1B083B0762532800835464 /* Preference.cpp */; };
AA1CD943060AE571003702C4 /* RageSoundDriver_Generic_Software.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA1CD941060AE571003702C4 /* RageSoundDriver_Generic_Software.cpp */; };
AA1CD944060AE571003702C4 /* RageSoundDriver_Generic_Software.h in Headers */ = {isa = PBXBuildFile; fileRef = AA1CD942060AE571003702C4 /* RageSoundDriver_Generic_Software.h */; };
AA1F9C4709AF1BF5002C15A8 /* PumpDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = AA1F9C4509AF1BF5002C15A8 /* PumpDevice.h */; };
AA1F9C4809AF1BF5002C15A8 /* PumpDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA1F9C4609AF1BF5002C15A8 /* PumpDevice.cpp */; };
AA1F9C4909AF1BF5002C15A8 /* PumpDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = AA1F9C4509AF1BF5002C15A8 /* PumpDevice.h */; };
AA1F9C4A09AF1BF5002C15A8 /* PumpDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA1F9C4609AF1BF5002C15A8 /* PumpDevice.cpp */; };
AA21D59D0712ADE4008B825F /* ScreenDimensions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA21D59C0712ADE4008B825F /* ScreenDimensions.cpp */; };
AA21D5A20712AE16008B825F /* ThemeMetric.h in Headers */ = {isa = PBXBuildFile; fileRef = AA21D5A10712AE16008B825F /* ThemeMetric.h */; };
AA22CBA506DE909C0083BA97 /* ScreenNetSelectMusic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA22CBA306DE909C0083BA97 /* ScreenNetSelectMusic.cpp */; };
@@ -1945,6 +1949,8 @@
AA1DC47804A4866B00D02EE9 /* ActorCollision.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ActorCollision.h; path = ../src/ActorCollision.h; sourceTree = "<group>"; };
AA1DCB6104A4872700D02EE9 /* glext.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = glext.h; path = ../src/glext.h; sourceTree = "<group>"; };
AA1DCB6304A4872700D02EE9 /* MenuInput.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = MenuInput.h; path = ../src/MenuInput.h; sourceTree = "<group>"; };
AA1F9C4509AF1BF5002C15A8 /* PumpDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PumpDevice.h; sourceTree = "<group>"; };
AA1F9C4609AF1BF5002C15A8 /* PumpDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PumpDevice.cpp; sourceTree = "<group>"; };
AA21D59C0712ADE4008B825F /* ScreenDimensions.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = ScreenDimensions.cpp; path = ../src/ScreenDimensions.cpp; sourceTree = "<group>"; };
AA21D5A10712AE16008B825F /* ThemeMetric.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ThemeMetric.h; path = ../src/ThemeMetric.h; sourceTree = "<group>"; };
AA22CBA306DE909C0083BA97 /* ScreenNetSelectMusic.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = ScreenNetSelectMusic.cpp; path = ../src/ScreenNetSelectMusic.cpp; sourceTree = "<group>"; };
@@ -4008,6 +4014,8 @@
AA4470BA098476F600983E82 /* KeyboardDevice.h */,
AA2FB62909120FC5000FD574 /* PreferredLanguage.m */,
AAF744A306116B0500B19AD1 /* PublicUtility */,
AA1F9C4609AF1BF5002C15A8 /* PumpDevice.cpp */,
AA1F9C4509AF1BF5002C15A8 /* PumpDevice.h */,
AABBFCD209838C3A00F077E2 /* SMMain.mm */,
AAABB2D90979DB5B006C9F25 /* SMMainThread.h */,
AAABB2DA0979DB5B006C9F25 /* SMMainThread.m */,
@@ -4520,6 +4528,7 @@
AAB55EBC09A7E3D3008FDC69 /* ScreenGameplaySyncMachine.h in Headers */,
AAB55EBE09A7E3D3008FDC69 /* ScreenUnlockBrowse.h in Headers */,
AAB55EC009A7E3D3008FDC69 /* ScreenUnlockCelebrate.h in Headers */,
AA1F9C4709AF1BF5002C15A8 /* PumpDevice.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4976,6 +4985,7 @@
AA40D37A09A08D650068C0D5 /* AdjustSync.h in Headers */,
AAB55FFF09A84E62008FDC69 /* ScreenUnlockCelebrate.h in Headers */,
AAB5600109A84E64008FDC69 /* ScreenUnlockBrowse.h in Headers */,
AA1F9C4909AF1BF5002C15A8 /* PumpDevice.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -5647,6 +5657,7 @@
AAB55EBB09A7E3D3008FDC69 /* ScreenGameplaySyncMachine.cpp in Sources */,
AAB55EBD09A7E3D3008FDC69 /* ScreenUnlockBrowse.cpp in Sources */,
AAB55EBF09A7E3D3008FDC69 /* ScreenUnlockCelebrate.cpp in Sources */,
AA1F9C4809AF1BF5002C15A8 /* PumpDevice.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -6056,6 +6067,7 @@
AA40D51309A08D650068C0D5 /* AdjustSync.cpp in Sources */,
AAB5600009A84E63008FDC69 /* ScreenUnlockCelebrate.cpp in Sources */,
AAB5600209A84E65008FDC69 /* ScreenUnlockBrowse.cpp in Sources */,
AA1F9C4A09AF1BF5002C15A8 /* PumpDevice.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -10,6 +10,7 @@
#include "archutils/Darwin/DarwinThreadHelpers.h"
#include "archutils/Darwin/KeyboardDevice.h"
#include "archutils/Darwin/JoystickDevice.h"
#include "archutils/Darwin/PumpDevice.h"
#include <IOKit/IOMessage.h>
void InputHandler_Carbon::QueueCallBack( void *target, int result, void *refcon, void *sender )
@@ -159,13 +160,15 @@ static HIDDevice *MakeDevice( InputDevice id )
return new KeyboardDevice;
if( id <= DEVICE_JOY16 )
return new JoystickDevice;
if( id <= DEVICE_PUMP2 )
return new PumpDevice;
return NULL;
}
void InputHandler_Carbon::AddDevices( int usage, InputDevice &id )
void InputHandler_Carbon::AddDevices( int usagePage, int usage, InputDevice &id )
{
io_iterator_t iter;
CFDictionaryRef dict = GetMatchingDictionary( kHIDPage_GenericDesktop, usage );
CFDictionaryRef dict = GetMatchingDictionary( usagePage, usage );
kern_return_t ret = IOServiceAddMatchingNotification( m_NotifyPort, kIOFirstMatchNotification, dict,
InputHandler_Carbon::DeviceAdded, this, &iter );
io_object_t device;
@@ -216,10 +219,12 @@ InputHandler_Carbon::InputHandler_Carbon() : m_Sem( "Input thread started" ), m_
m_NotifyPort = IONotificationPortCreate( kIOMasterPortDefault );
// Add devices.
AddDevices( kHIDUsage_GD_Keyboard, id );
AddDevices( kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard, id );
id = DEVICE_JOY1;
AddDevices( kHIDUsage_GD_Joystick, id );
AddDevices( kHIDUsage_GD_GamePad, id );
AddDevices( kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick, id );
AddDevices( kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad, id );
id = DEVICE_PUMP1;
AddDevices( 0xFF00, 0x0001, id ); // Pump pads use the first vendor specific usage page.
m_bChanged = false;
if( PREFSMAN->m_bThreadedInput )
@@ -26,7 +26,7 @@ private:
static void DeviceAdded( void *refCon, io_iterator_t iter );
static void DeviceChanged( void *refCon, io_service_t service, natural_t messageType, void *arg );
void StartDevices();
void AddDevices( int usage, InputDevice &id );
void AddDevices( int usagePage, int usage, InputDevice &id );
public:
InputHandler_Carbon();
@@ -0,0 +1,119 @@
#include "global.h"
#include "PumpDevice.h"
#include "EnumHelper.h"
void PumpDevice::Open()
{
AddElementToQueue( 2 );
AddElementToQueue( 3 );
AddElementToQueue( 4 );
AddElementToQueue( 6 );
}
void PumpDevice::GetButtonPresses( vector<pair<DeviceInput, bool> >& vPresses, int cookie,
int value, const RageTimer& now ) const
{
DeviceButton db1 = DeviceButton_Invalid;
DeviceButton db2 = DeviceButton_Invalid;
bool pressed;
LOG->Trace( "Pump button: %d, %d.", cookie, value );
switch( cookie )
{
case 2:
db1 = JOY_BUTTON_1;
pressed = value == 0;
break;
case 3:
switch( value )
{
case 1:
db1 = JOY_BUTTON_5;
pressed = true;
break;
case 2:
db1 = JOY_BUTTON_4;
pressed = true;
break;
case 3:
db1 = JOY_BUTTON_5;
db2 = JOY_BUTTON_4;
pressed = false;
break;
}
break;
case 4:
switch( value )
{
case 1:
db1 = JOY_BUTTON_2;
pressed = true;
break;
case 2:
db1 = JOY_BUTTON_3;
pressed = true;
break;
case 3:
db1 = JOY_BUTTON_2;
db2 = JOY_BUTTON_3;
pressed = false;
break;
}
break;
case 6:
db1 = JOY_BUTTON_6;
pressed = value == 2;
break;
}
if( db1 != DeviceButton_Invalid )
{
DeviceInput di( id, db1, pressed ? 1.0f : 0.0f , now );
vPresses.push_back( pair<DeviceInput, bool>(di, pressed) );
}
if( db2 != DeviceButton_Invalid )
{
DeviceInput di( id, db2, pressed ? 1.0f : 0.0f , now );
vPresses.push_back( pair<DeviceInput, bool>(di, pressed) );
}
}
int PumpDevice::AssignIDs( InputDevice startID )
{
id = DEVICE_NONE;
if( startID < DEVICE_PUMP1 || startID > DEVICE_PUMP2 )
return 0;
id = startID;
return 1;
}
void PumpDevice::GetDevicesAndDescriptions( vector<InputDevice>& dev, vector<RString>& desc ) const
{
dev.push_back( id );
desc.push_back( "Pump USB" );
}
/*
* (c) 2005-2006 Steve Checkoway
* 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.
*/
@@ -0,0 +1,49 @@
#ifndef PUMP_DEVICE_H
#define PUMP_DEVICE_H
#include "HIDDevice.h"
class PumpDevice : public HIDDevice
{
private:
InputDevice id;
protected:
bool AddLogicalDevice( int usagePage, int usage ) { return true; }
void AddElement( int usagePage, int usage, int cookie,
const CFDictionaryRef properties ) { }
void Open();
bool SupportsVidPid( int vid, int pid ) { return vid == 0x0d2f && pid == 0x0001; }
public:
void GetButtonPresses( vector<pair<DeviceInput, bool> >& vPresses, int cookie,
int value, const RageTimer& now ) const;
int AssignIDs( InputDevice startID );
void GetDevicesAndDescriptions( vector<InputDevice>& dev, vector<RString>& desc ) const;
};
#endif
/*
* (c) 2006 Steve Checkoway
* 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.
*/