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:
parent
6f6acf3970
commit
4e81cb4012
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) );
|
||||
|
||||
|
|
Loading…
Reference in New Issue