summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/Src/ControllerInterface/DirectInput
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/InputCommon/Src/ControllerInterface/DirectInput')
-rw-r--r--Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp103
-rw-r--r--Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp66
2 files changed, 110 insertions, 59 deletions
diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp
index c1234f7f4c..75d7f9d9f1 100644
--- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp
+++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp
@@ -3,6 +3,7 @@
#ifdef CIFACE_USE_DIRECTINPUT_JOYSTICK
#include "DirectInputJoystick.h"
+#include <StringUtil.h>
inline bool operator<(const GUID & lhs, const GUID & rhs)
{
@@ -14,6 +15,8 @@ namespace ciface
namespace DirectInput
{
+#define DATA_BUFFER_SIZE 32
+
#ifdef NO_DUPLICATE_DINPUT_XINPUT
//-----------------------------------------------------------------------------
// Modified some MSDN code to get all the XInput device GUID.Data1 values in a vector,
@@ -177,32 +180,37 @@ void InitJoystick( IDirectInput8* const idi8, std::vector<ControllerInterface::D
if ( std::find( xinput_guids.begin(), xinput_guids.end(), i->guidProduct.Data1 ) != xinput_guids.end() )
continue;
#endif
- // TODO: this has potential to mess up on createdev or setdatafmt failure
LPDIRECTINPUTDEVICE8 js_device;
- if ( DI_OK == idi8->CreateDevice( i->guidInstance, &js_device, NULL ) )
- if ( DI_OK == js_device->SetDataFormat( &c_dfDIJoystick ) )
- // using foregroundwindow seems like a hack
- if ( DI_OK != js_device->SetCooperativeLevel( GetForegroundWindow(), DISCL_BACKGROUND | DISCL_EXCLUSIVE ) )
+ if (DI_OK == idi8->CreateDevice(i->guidInstance, &js_device, NULL))
{
- // fall back to non-exclusive mode, with no rumble
- if ( DI_OK != js_device->SetCooperativeLevel( NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE ) )
+ if (DI_OK == js_device->SetDataFormat(&c_dfDIJoystick))
{
- js_device->Release();
- continue;
+ // using foregroundwindow seems like a hack
+ if (DI_OK != js_device->SetCooperativeLevel(GetForegroundWindow(), DISCL_BACKGROUND | DISCL_EXCLUSIVE))
+ {
+ //PanicAlert("SetCooperativeLevel(DISCL_EXCLUSIVE) failed!");
+ // fall back to non-exclusive mode, with no rumble
+ if (DI_OK != js_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))
+ {
+ //PanicAlert("SetCooperativeLevel failed!");
+ js_device->Release();
+ continue;
+ }
+ }
+
+ Joystick* js = new Joystick(/*&*i, */js_device, name_counts[i->tszInstanceName].value++);
+ // only add if it has some inputs/outpus
+ if (js->Inputs().size() || js->Outputs().size())
+ devices.push_back(js);
+ else
+ delete js;
}
- }
-
- if ( DI_OK == js_device->Acquire() )
- {
- Joystick* js = new Joystick( /*&*i, */js_device, name_counts[i->tszInstanceName].value++ );
- // only add if it has some inputs/outpus
- if ( js->Inputs().size() || js->Outputs().size() )
- devices.push_back( js );
else
- delete js;
+ {
+ //PanicAlert("SetDataFormat failed!");
+ js_device->Release();
+ }
}
- else
- js_device->Release();
}
}
@@ -222,7 +230,22 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI
js_caps.dwButtons = std::min((DWORD)32, js_caps.dwButtons);
js_caps.dwPOVs = std::min((DWORD)4, js_caps.dwPOVs);
- m_must_poll = ( ( js_caps.dwFlags & DIDC_POLLEDDATAFORMAT ) > 0 );
+ // polled or buffered data
+ {
+ DIPROPDWORD dipdw;
+ dipdw.diph.dwSize = sizeof(DIPROPDWORD);
+ dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+ dipdw.diph.dwObj = 0;
+ dipdw.diph.dwHow = DIPH_DEVICE;
+ dipdw.dwData = DATA_BUFFER_SIZE;
+
+ // set the buffer size,
+ // if we can't set the property, we can't use buffered data,
+ // must use polling, which apparently doesn't work as well
+ m_must_poll = (DI_OK != m_device->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph));
+ }
+
+ m_device->Acquire();
// buttons
for ( unsigned int i = 0; i < js_caps.dwButtons; ++i )
@@ -339,7 +362,7 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI
dipdw.diph.dwHeaderSize = sizeof( DIPROPHEADER );
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
- dipdw.dwData = FALSE;
+ dipdw.dwData = DIPROPAUTOCENTER_OFF;
m_device->SetProperty( DIPROP_AUTOCENTER, &dipdw.diph );
}
@@ -377,7 +400,7 @@ std::string Joystick::GetName() const
str.diph.dwHeaderSize = sizeof(str.diph);
str.diph.dwHow = DIPH_DEVICE;
m_device->GetProperty( DIPROP_PRODUCTNAME, &str.diph );
- return TStringToString( str.wsz );
+ return StripSpaces(TStringToString(str.wsz));
//return m_name;
}
@@ -395,16 +418,42 @@ std::string Joystick::GetSource() const
bool Joystick::UpdateInput()
{
- if ( m_must_poll )
+ HRESULT hr = 0;
+
+ if (m_must_poll)
+ {
m_device->Poll();
+ hr = m_device->GetDeviceState(sizeof(m_state_in), &m_state_in);
+ }
+ else
+ {
+ DIDEVICEOBJECTDATA evtbuf[DATA_BUFFER_SIZE];
+ DWORD numevents = DATA_BUFFER_SIZE;
- HRESULT hr = m_device->GetDeviceState( sizeof(m_state_in), &m_state_in );
+ hr = m_device->GetDeviceData(sizeof(*evtbuf), evtbuf, &numevents, 0);
+ //PanicAlert("GetDeviceData %l", hr);
+ while (DI_OK == hr && numevents)
+ {
+ for (LPDIDEVICEOBJECTDATA evt = evtbuf; evt<evtbuf + numevents; ++evt)
+ {
+ // all the buttons are at the end of the data format
+ // they are bytes rather than longs
+ if (evt->dwOfs < DIJOFS_BUTTON(0))
+ *(DWORD*)(((u8*)&m_state_in) + evt->dwOfs) = evt->dwData;
+ else
+ *(BYTE*)(((u8*)&m_state_in) + evt->dwOfs) = (BYTE)evt->dwData;
+ }
+
+ numevents = DATA_BUFFER_SIZE;
+ hr = m_device->GetDeviceData(sizeof(evtbuf), evtbuf, &numevents, 0);
+ }
+ }
// try reacquire if input lost
- if ( DIERR_INPUTLOST == hr )
+ if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr)
hr = m_device->Acquire();
- return ( DI_OK == hr );
+ return (DI_OK == hr);
}
bool Joystick::UpdateOutput()
diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp
index 071a233887..adc5dadc42 100644
--- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp
+++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp
@@ -46,39 +46,30 @@ void InitKeyboardMouse( IDirectInput8* const idi8, std::vector<ControllerInterfa
// if thats dumb, i will make a VirtualDevice class that just uses ranges of inputs/outputs from other devices
// so there can be a separated Keyboard and mouse, as well as combined KeyboardMouse
- // TODO: this has potential to not release devices if set datafmt or cooplevel fails
+ LPDIRECTINPUTDEVICE8 kb_device = NULL;
+ LPDIRECTINPUTDEVICE8 mo_device = NULL;
- LPDIRECTINPUTDEVICE8 kb_device;
- LPDIRECTINPUTDEVICE8 mo_device;
-
- if ( DI_OK == idi8->CreateDevice( GUID_SysKeyboard, &kb_device, NULL ) )
- if ( DI_OK == kb_device->SetDataFormat( &c_dfDIKeyboard ) )
- if ( DI_OK == kb_device->SetCooperativeLevel( NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) )
- if ( DI_OK == kb_device->Acquire() )
+ if (DI_OK == idi8->CreateDevice( GUID_SysKeyboard, &kb_device, NULL))
{
-
- if ( DI_OK == idi8->CreateDevice( GUID_SysMouse, &mo_device, NULL ) )
- if ( DI_OK == mo_device->SetDataFormat( &c_dfDIMouse2 ) )
- if ( DI_OK == mo_device->SetCooperativeLevel( NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) )
- if ( DI_OK == mo_device->Acquire() )
+ if (DI_OK == kb_device->SetDataFormat(&c_dfDIKeyboard))
+ if (DI_OK == kb_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))
{
- devices.push_back( new KeyboardMouse( kb_device, mo_device ) );
- return;
+ if (DI_OK == idi8->CreateDevice( GUID_SysMouse, &mo_device, NULL ))
+ {
+ if (DI_OK == mo_device->SetDataFormat(&c_dfDIMouse2))
+ if (DI_OK == mo_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))
+ {
+ devices.push_back(new KeyboardMouse(kb_device, mo_device));
+ return;
+ }
+ }
}
- else
- goto release_mouse;
-
- goto unacquire_kb;
}
- else
- goto release_kb;
-
-release_mouse:
- mo_device->Release();
-unacquire_kb:
- kb_device->Unacquire();
-release_kb:
- kb_device->Release();
+
+ if (kb_device)
+ kb_device->Release();
+ if (mo_device)
+ mo_device->Release();
}
KeyboardMouse::~KeyboardMouse()
@@ -95,6 +86,9 @@ KeyboardMouse::KeyboardMouse( const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRE
: m_kb_device(kb_device)
, m_mo_device(mo_device)
{
+ m_kb_device->Acquire();
+ m_mo_device->Acquire();
+
m_last_update = wxGetLocalTimeMillis();
ZeroMemory( &m_state_in, sizeof(m_state_in) );
@@ -144,8 +138,16 @@ bool KeyboardMouse::UpdateInput()
m_last_update = cur_time;
- if ( DI_OK == m_kb_device->GetDeviceState( sizeof(m_state_in.keyboard), &m_state_in.keyboard )
- && DI_OK == m_mo_device->GetDeviceState( sizeof(tmp_mouse), &tmp_mouse ) )
+ HRESULT kb_hr = m_kb_device->GetDeviceState(sizeof(m_state_in.keyboard), &m_state_in.keyboard);
+ HRESULT mo_hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse);
+
+ if (DIERR_INPUTLOST == kb_hr || DIERR_NOTACQUIRED == kb_hr)
+ m_kb_device->Acquire();
+
+ if (DIERR_INPUTLOST == mo_hr || DIERR_NOTACQUIRED == mo_hr)
+ m_mo_device->Acquire();
+
+ if (DI_OK == kb_hr && DI_OK == mo_hr)
{
// need to smooth out the axes, otherwise it doesnt work for shit
for ( unsigned int i = 0; i < 3; ++i )
@@ -155,8 +157,8 @@ bool KeyboardMouse::UpdateInput()
memcpy( m_state_in.mouse.rgbButtons, tmp_mouse.rgbButtons, sizeof(m_state_in.mouse.rgbButtons) );
return true;
}
- else
- return false;
+
+ return false;
}
bool KeyboardMouse::UpdateOutput()