GCPad/Wiimote New: (OS X Config Dialog) Temporarily fix a crash when selecting an item in the device list (a current bug in wxWidgets with wxTE_PROCESS_ENTER). (Windows DirectInput) Hopefully made axis enumeration and the fall back to polled data(for drivers which don't support buffered data) simpler and more foolproof (a few users were having issues with a few specific gamepads).

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6143 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Jordan Woyak 2010-08-29 03:45:56 +00:00
parent 6f6acf3970
commit 4e81cb4012
2 changed files with 30 additions and 69 deletions

View File

@ -5,11 +5,6 @@
#include "DInputJoystick.h"
#include "DInput.h"
inline bool operator<(const GUID & lhs, const GUID & rhs)
{
return memcmp(&lhs, &rhs, sizeof(GUID)) < 0;
}
namespace ciface
{
namespace DInput
@ -198,18 +193,20 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI
js_caps.dwPOVs = std::min((DWORD)4, js_caps.dwPOVs);
// polled or buffered data
m_must_poll = (js_caps.dwFlags & DIDC_POLLEDDATAFORMAT) != 0;
if (false == m_must_poll)
{
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;
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));
// 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();
@ -225,68 +222,28 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI
AddInput( new Hat( i, d ) );
}
// get up to 6 axes and 2 sliders
std::list<DIDEVICEOBJECTINSTANCE> axes;
m_device->EnumObjects(DIEnumDeviceObjectsCallback, (LPVOID)&axes, DIDFT_ABSAXIS);
unsigned int cur_slider = 0;
// map of axis offsets in joystate dataformat based on axis guidType
std::map<GUID,int> types;
types[GUID_XAxis] = 0;
types[GUID_YAxis] = 1;
types[GUID_ZAxis] = 2;
types[GUID_RxAxis] = 3;
types[GUID_RyAxis] = 4;
types[GUID_RzAxis] = 5;
// going in reverse leaves the list more organized in the end for me :/
std::list<DIDEVICEOBJECTINSTANCE>::const_reverse_iterator
i = axes.rbegin(),
e = axes.rend();
for( ; i!=e; ++i )
// screw EnumObjects, just go through all the axis offsets and try to GetProperty
// this should be more foolproof, less code, and probably faster
for (unsigned int offset = 0; offset < DIJOFS_BUTTON(0) / sizeof(LONG); ++offset)
{
DIPROPRANGE range;
ZeroMemory( &range, sizeof(range ) );
range.diph.dwSize = sizeof(range);
range.diph.dwHeaderSize = sizeof(range.diph);
range.diph.dwHow = DIPH_BYID;
range.diph.dwObj = i->dwType;
range.diph.dwHow = DIPH_BYOFFSET;
range.diph.dwObj = offset * sizeof(LONG);
// try to set some nice power of 2 values (8192)
range.lMin = -(1<<13);
range.lMax = (1<<13);
range.lMin = -(1 << 13);
range.lMax = (1 << 13);
m_device->SetProperty(DIPROP_RANGE, &range.diph);
// but i guess not all devices support setting range
m_device->SetProperty( DIPROP_RANGE, &range.diph );
// so i getproperty right afterward incase it didn't set :P
// this also checks that the axis is present
if (SUCCEEDED(m_device->GetProperty(DIPROP_RANGE, &range.diph)))
{
int offset = -1;
if (GUID_Slider ==i->guidType)
{
// max of 2 sliders / limit of used data format
if (cur_slider < 2)
offset = 6 + cur_slider++;
}
else
{
// don't add duplicate axes, some buggy drivers report the same axis twice
const std::map<GUID,int>::iterator f = types.find(i->guidType);
if (types.end() != f)
{
offset = f->second;
// remove from the map so it isn't added again
types.erase(f);
}
}
if ( offset >= 0 )
{
const LONG base = (range.lMin + range.lMax) / 2;
// each axis gets a negative and a positive input instance associated with it
AddInput( new Axis( offset, base, range.lMin-base ) );
AddInput( new Axis( offset, base, range.lMax-base ) );
}
const LONG base = (range.lMin + range.lMax) / 2;
// each axis gets a negative and a positive input instance associated with it
AddInput(new Axis(offset, base, range.lMin-base));
AddInput(new Axis(offset, base, range.lMax-base));
}
}

View File

@ -908,7 +908,11 @@ GamepadPage::GamepadPage( wxWindow* parent, InputPlugin& plugin, const unsigned
wxStaticBoxSizer* const device_sbox = new wxStaticBoxSizer( wxHORIZONTAL, this, wxT("Device") );
device_cbox = new wxComboBox( this, -1, wxT(""), wxDefaultPosition, wxSize(64,-1), 0, 0, wxTE_PROCESS_ENTER );
device_cbox = new wxComboBox(this, -1, wxT(""), wxDefaultPosition, wxSize(64,-1));
#ifndef __APPLE__
// causes a crash with some OS X wxWidgets
device_cbox->ToggleWindowStyle(wxTE_PROCESS_ENTER);
#endif
wxButton* refresh_button = new wxButton( this, -1, wxT("Refresh"), wxDefaultPosition, wxSize(60,-1) );