Lock the Pump pad device while enumerating DI8 devices, to work around

a DI8 bug.
This commit is contained in:
Glenn Maynard
2002-08-24 02:26:39 +00:00
parent c8865e95d7
commit 9ef1b27c4a
2 changed files with 40 additions and 20 deletions
+38 -18
View File
@@ -462,16 +462,33 @@ HRESULT RageInput::Initialize()
m_AbsPosition_x = 640/2; m_AbsPosition_x = 640/2;
m_AbsPosition_y = 480/2; m_AbsPosition_y = 480/2;
} }
//////////////////////////////
// Create the joystick devices {
////////////////////////////// /* Nasty hack to work around a bug in DirectInput8: Pump pads
// Look for joysticks * crash EnumDevices. Prevent this by opening the pad with
// TODO: Why is this function so slow to return? Is it just my machine? * exclusive access while we enumerate, then closing it when
if( FAILED( hr = m_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, * we finish. We don't do anything with this; we open it
EnumJoysticksCallback, * for real down below, since we don't *really* want to open
(VOID*)this, * the pad with exclusive access. (I also don't want to introduce
DIEDFL_ATTACHEDONLY ) ) ) * dependencies, such as "pump must be initialized before joysticks",
throw RageException( hr, "m_pDI->EnumDevices failed." ); * so this doesn't bite us again down the road.) */
pump_t m_TempPumps[NUM_PUMPS];
for(int pumpNo = 0; pumpNo < NUM_PUMPS; ++pumpNo)
m_TempPumps[pumpNo].init(pumpNo, false);
//////////////////////////////
// Create the joystick devices
//////////////////////////////
// Look for joysticks
// TODO: Why is this function so slow to return? Is it just my machine?
if( FAILED( hr = m_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
EnumJoysticksCallback,
(VOID*)this,
DIEDFL_ATTACHEDONLY ) ) )
throw RageException( hr, "m_pDI->EnumDevices failed." );
}
// for(int pumpNo = 0; pumpNo < NUM_PUMPS; ++pumpNo)
// m_Pumps[pumpNo].init(pumpNo);
for( int i=0; i<NUM_JOYSTICKS; i++ ) for( int i=0; i<NUM_JOYSTICKS; i++ )
{ {
@@ -516,7 +533,10 @@ HRESULT RageInput::Initialize()
} }
for(int pumpNo = 0; pumpNo < NUM_PUMPS; ++pumpNo) for(int pumpNo = 0; pumpNo < NUM_PUMPS; ++pumpNo)
m_Pumps[pumpNo].init(pumpNo); {
if(m_Pumps[pumpNo].init(pumpNo))
LOG->Trace("Found Pump pad %i\n", pumpNo);
}
return S_OK; return S_OK;
} }
@@ -847,7 +867,7 @@ err:
#endif #endif
} }
HANDLE USB::OpenUSB (int VID, int PID, int num) HANDLE USB::OpenUSB (int VID, int PID, int num, bool share)
{ {
#ifndef HAVE_DDK #ifndef HAVE_DDK
LOG->Trace( "Can't open USB device %-4.4x:%-4.4x#%i: DDK not available.", LOG->Trace( "Can't open USB device %-4.4x:%-4.4x#%i: DDK not available.",
@@ -864,9 +884,10 @@ HANDLE USB::OpenUSB (int VID, int PID, int num)
if(h != INVALID_HANDLE_VALUE) if(h != INVALID_HANDLE_VALUE)
CloseHandle (h); CloseHandle (h);
int ShareMode = 0;
if(share) ShareMode |= FILE_SHARE_READ | FILE_SHARE_WRITE;
h = CreateFile (path, GENERIC_READ, h = CreateFile (path, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, ShareMode, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
free(path); free(path);
@@ -905,12 +926,11 @@ RageInput::pump_t::~pump_t()
CloseHandle(h); CloseHandle(h);
} }
void RageInput::pump_t::init(int devno) bool RageInput::pump_t::init(int devno, bool share)
{ {
const int pump_usb_vid = 0x0d2f, pump_usb_pid = 0x0001; const int pump_usb_vid = 0x0d2f, pump_usb_pid = 0x0001;
h = USB::OpenUSB (pump_usb_vid, pump_usb_pid, devno); h = USB::OpenUSB (pump_usb_vid, pump_usb_pid, devno, share);
if(h != INVALID_HANDLE_VALUE) return h != INVALID_HANDLE_VALUE;
LOG->Trace("Found Pump pad %i\n", devno);
} }
int RageInput::pump_t::GetPadEvent() int RageInput::pump_t::GetPadEvent()
+2 -2
View File
@@ -143,7 +143,7 @@ private:
pump_t(); pump_t();
~pump_t(); ~pump_t();
void init(int devno); /* added a return type because it generates a warning in VC7 -Chris */ bool init(int devno, bool share=true);
int GetPadEvent(); int GetPadEvent();
} *m_Pumps; } *m_Pumps;
@@ -182,7 +182,7 @@ public:
namespace USB { namespace USB {
char *GetUSBDevicePath (int num); char *GetUSBDevicePath (int num);
HANDLE OpenUSB (int VID, int PID, int num); HANDLE OpenUSB (int VID, int PID, int num, bool share=true);
}; };
extern RageInput* INPUTMAN; // global and accessable from anywhere in our program extern RageInput* INPUTMAN; // global and accessable from anywhere in our program