From 910eafbf9fd8552ae30a1e53fa1181e64420e819 Mon Sep 17 00:00:00 2001 From: Shenjoku Date: Tue, 21 May 2013 23:48:49 -0700 Subject: [PATCH] Fixed some problems introduced in ba0d2d1 that were causing joystick inputs to be incorrectly mapped when using DirectInput. --- .../InputHandler_DirectInputHelper.cpp | 72 ++++++++++++++++--- .../InputHandler_DirectInputHelper.h | 18 ++++- 2 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/arch/InputHandler/InputHandler_DirectInputHelper.cpp b/src/arch/InputHandler/InputHandler_DirectInputHelper.cpp index 1234a4e6ad..40b8131cc9 100644 --- a/src/arch/InputHandler/InputHandler_DirectInputHelper.cpp +++ b/src/arch/InputHandler/InputHandler_DirectInputHelper.cpp @@ -151,30 +151,59 @@ static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev if(!(dev->dwType & SupportedMask)) return DIENUM_CONTINUE; // unsupported - in.ofs = dev->dwOfs; - if(dev->dwType & DIDFT_BUTTON) { if( device->buttons == 24 ) return DIENUM_CONTINUE; // too many buttons + in.ofs = DIJOFS_BUTTON(device->buttons); in.type = in.BUTTON; in.num = device->buttons; - device->buttons++; } else if(dev->dwType & DIDFT_POV) { + in.ofs = DIJOFS_POV(device->hats); in.type = in.HAT; in.num = device->hats; - device->hats++; } else { // dev->dwType & DIDFT_AXIS DIPROPRANGE diprg; DIPROPDWORD dilong; + // Figure out which axis we're looking at and store the correct DIJOFS_* value. + if( dev->guidType == GUID_XAxis ) + { + in.ofs = DIJOFS_X; + } + else if( dev->guidType == GUID_YAxis ) + { + in.ofs = DIJOFS_Y; + } + else if( dev->guidType == GUID_ZAxis ) + { + in.ofs = DIJOFS_Z; + } + else if( dev->guidType == GUID_RxAxis ) + { + in.ofs = DIJOFS_RX; + } + else if( dev->guidType == GUID_RyAxis ) + { + in.ofs = DIJOFS_RY; + } + else if( dev->guidType == GUID_RzAxis ) + { + in.ofs = DIJOFS_RZ; + } + else + { + // No idea what this is so ignore it. + return DIENUM_CONTINUE; + } + in.type = in.AXIS; in.num = device->axes; diprg.diph.dwSize = sizeof(diprg); diprg.diph.dwHeaderSize = sizeof(diprg.diph); - diprg.diph.dwObj = dev->dwOfs; - diprg.diph.dwHow = DIPH_BYOFFSET; + diprg.diph.dwObj = dev->dwType; + diprg.diph.dwHow = DIPH_BYID; diprg.lMin = -100; diprg.lMax = 100; @@ -185,17 +214,38 @@ static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev // Set dead zone to 0. dilong.diph.dwSize = sizeof(dilong); dilong.diph.dwHeaderSize = sizeof(dilong.diph); - dilong.diph.dwObj = dev->dwOfs; - dilong.diph.dwHow = DIPH_BYOFFSET; + dilong.diph.dwObj = dev->dwType; + dilong.diph.dwHow = DIPH_BYID; dilong.dwData = 0; hr = device->Device->SetProperty( DIPROP_DEADZONE, &dilong.diph ); if ( hr != DI_OK ) return DIENUM_CONTINUE; // don't use this axis - - device->axes++; } - device->Inputs.push_back(in); + /* For some devices it's possible to find multiple objects of the same type. When trying to + * figure out which device caused an event it doesn't matter which one it finds so there's + * no need to include a duplicate if one has already been added. + */ + if( std::find_if( device->Inputs.begin(), device->Inputs.end(), input_t::Compare( in.ofs ) ) == device->Inputs.end() ) + { + device->Inputs.push_back(in); + + // Increment the number of buttons/axes/hats only after it has been added. + switch ( in.type ) + { + case input_t::BUTTON: + ++device->buttons; + break; + + case input_t::AXIS: + ++device->axes; + break; + + case input_t::HAT: + ++device->hats; + break; + } + } return DIENUM_CONTINUE; } diff --git a/src/arch/InputHandler/InputHandler_DirectInputHelper.h b/src/arch/InputHandler/InputHandler_DirectInputHelper.h index 57a178ba54..9d3c7cb1a2 100644 --- a/src/arch/InputHandler/InputHandler_DirectInputHelper.h +++ b/src/arch/InputHandler/InputHandler_DirectInputHelper.h @@ -9,7 +9,7 @@ extern LPDIRECTINPUT8 g_dinput; #define INPUT_QSIZE 32 -typedef struct input_t +struct input_t { // DirectInput offset for this input type: DWORD ofs; @@ -18,7 +18,21 @@ typedef struct input_t enum Type { KEY, BUTTON, AXIS, HAT } type; int num; -} input_t; + + // Comparitor for finding the input_t with the matching ofs member in std containers. + class Compare + { + public: + + Compare(DWORD _ofs) : ofs(_ofs) { } + + bool operator()(const input_t & input) const { return input.ofs == ofs; } + + private: + + DWORD ofs; + }; +}; struct DIDevice {