From 656ff26ed8fd2e47ff68e78dcf0bb588ef627865 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 5 Jun 2010 05:30:23 +0000 Subject: New GCPad/Wiimote: Enabled SDL 1.2 on the Windows build to support some gamepads that weren't working with DirectInput. Made DirectInput use (and prefer) buffered data rather than polled data (some gamepads should work better). In GUI: Changed all numeric wxChoice to wxSpinCtrl (config dialog opens much faster), removed "+" buttons, made UI more compact. Fixed a few problems that were introduced with the IniFile change. Made minor changes to IniFile. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5619 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../DirectInput/DirectInputJoystick.cpp | 103 +++++++++++++++------ .../DirectInput/DirectInputKeyboardMouse.cpp | 66 ++++++------- 2 files changed, 110 insertions(+), 59 deletions(-) (limited to 'Source/Core/InputCommon/Src/ControllerInterface/DirectInput') 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 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::vectorguidProduct.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; evtdwOfs < 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::vectorCreateDevice( 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() -- cgit v1.2.3