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
This commit is contained in:
Jordan Woyak
2010-06-05 05:30:23 +00:00
parent 6b872bb81c
commit 656ff26ed8
12 changed files with 257 additions and 196 deletions

View File

@ -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,33 +180,38 @@ 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))
{
// 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;
}
else
{
//PanicAlert("SetDataFormat failed!");
js_device->Release();
continue;
}
}
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;
}
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 )
m_device->Poll();
HRESULT hr = 0;
HRESULT hr = m_device->GetDeviceState( sizeof(m_state_in), &m_state_in );
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;
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()

View File

@ -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()