From 656ff26ed8fd2e47ff68e78dcf0bb588ef627865 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 5 Jun 2010 05:30:23 +0000 Subject: [PATCH] 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 --- Source/Core/Common/Src/IniFile.cpp | 47 +++++--- Source/Core/Common/Src/IniFile.h | 43 +++---- Source/Core/InputCommon/InputCommon.vcproj | 12 +- .../ControllerInterface.cpp | 5 +- .../ControllerInterface/ControllerInterface.h | 6 +- .../DirectInput/DirectInputJoystick.cpp | 105 ++++++++++++----- .../DirectInput/DirectInputKeyboardMouse.cpp | 64 ++++++----- .../Src/ControllerInterface/SDL/SDL.cpp | 3 +- .../InputPluginCommon/Src/ConfigDiag.cpp | 106 +++++++++--------- .../InputPluginCommon/Src/ConfigDiag.h | 10 +- .../InputPluginCommon/Src/ControllerEmu.cpp | 50 +++++---- .../InputPluginCommon/Src/ControllerEmu.h | 2 +- 12 files changed, 257 insertions(+), 196 deletions(-) diff --git a/Source/Core/Common/Src/IniFile.cpp b/Source/Core/Common/Src/IniFile.cpp index b9e46feb28..244d06a161 100644 --- a/Source/Core/Common/Src/IniFile.cpp +++ b/Source/Core/Common/Src/IniFile.cpp @@ -60,21 +60,6 @@ static void ParseLine(const std::string& line, std::string* keyOut, std::string* } -IniFile::Section::Section() - : lines(), name(""), comment("") {} - - -IniFile::Section::Section(const std::string& _name) - : lines(), name(_name), comment("") {} - - -IniFile::Section::Section(const Section& other) -{ - name = other.name; - comment = other.comment; - lines = other.lines; -} - std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut, std::string* commentOut) { for (std::vector::iterator iter = lines.begin(); iter != lines.end(); ++iter) @@ -104,6 +89,14 @@ void IniFile::Section::Set(const char* key, const char* newValue) } } +void IniFile::Section::Set(const char* key, const std::string& newValue, const std::string& defaultValue) +{ + if (newValue != defaultValue) + Set(key, newValue); + else + Delete(key); +} + bool IniFile::Section::Get(const char* key, std::string* value, const char* defaultValue) { std::string* line = GetLine(key, value, 0); @@ -118,6 +111,14 @@ bool IniFile::Section::Get(const char* key, std::string* value, const char* defa return true; } +void IniFile::Section::Set(const char* key, const float newValue, const float defaultValue) +{ + if (newValue != defaultValue) + Set(key, newValue); + else + Delete(key); +} + void IniFile::Section::Set(const char* key, const std::vector& newValues) { std::string temp; @@ -222,12 +223,22 @@ bool IniFile::Section::Exists(const char *key) const return false; } +bool IniFile::Section::Delete(const char *key) +{ + std::string* line = GetLine(key, 0, 0); + for (std::vector::iterator liter = lines.begin(); liter != lines.end(); ++liter) + { + if (line == &*liter) + { + lines.erase(liter); + return true; + } + } + return false; +} // IniFile -IniFile::IniFile() {} -IniFile::~IniFile() {} - const IniFile::Section* IniFile::GetSection(const char* sectionName) const { for (std::vector
::const_iterator iter = sections.begin(); iter != sections.end(); ++iter) diff --git a/Source/Core/Common/Src/IniFile.h b/Source/Core/Common/Src/IniFile.h index e287427c09..1b214edf86 100644 --- a/Source/Core/Common/Src/IniFile.h +++ b/Source/Core/Common/Src/IniFile.h @@ -28,19 +28,19 @@ class IniFile public: class Section { - public: - Section(); - Section(const std::string& _name); - Section(const Section& other); + friend class IniFile; - std::vector lines; - std::string name; - std::string comment; + public: + Section() {} + Section(const std::string& _name) : name(_name) {} bool Exists(const char *key) const; + bool Delete(const char *key); std::string* GetLine(const char* key, std::string* valueOut, std::string* commentOut); void Set(const char* key, const char* newValue); + void Set(const char* key, const std::string& newValue, const std::string& defaultValue); + void Set(const std::string &key, const std::string &value) { Set(key.c_str(), value.c_str()); } @@ -52,6 +52,7 @@ public: void Set(const char* key, float newValue) { Set(key, StringFromFormat("%f", newValue).c_str()); } + void Set(const char* key, const float newValue, const float defaultValue); void Set(const char* key, double newValue) { Set(key, StringFromFormat("%f", newValue).c_str()); } @@ -70,33 +71,15 @@ public: bool Get(const char* key, double* value, double defaultValue = false); bool Get(const char* key, std::vector& values); - // Direct getters, Billiard-style. - std::string Get(const char *key, const char *default_value) { - std::string value; Get(key, &value, default_value); return value; - } - int Get(const char *key, int defaultValue) { - int value; Get(key, &value, defaultValue); return value; - } - int Get(const char *key, u32 defaultValue) { - u32 value; Get(key, &value, defaultValue); return value; - } - int Get(const char *key, bool defaultValue) { - bool value; Get(key, &value, defaultValue); return value; - } - float Get(const char *key, float defaultValue) { - float value; Get(key, &value, defaultValue); return value; - } - double Get(const char *key, double defaultValue) { - double value; Get(key, &value, defaultValue); return value; - } - bool operator < (const Section& other) const { return name < other.name; } - }; - IniFile(); - ~IniFile(); + protected: + std::vector lines; + std::string name; + std::string comment; + }; bool Load(const char* filename); bool Load(const std::string &filename) { return Load(filename.c_str()); } diff --git a/Source/Core/InputCommon/InputCommon.vcproj b/Source/Core/InputCommon/InputCommon.vcproj index eaa33a78ca..c6a11789e0 100644 --- a/Source/Core/InputCommon/InputCommon.vcproj +++ b/Source/Core/InputCommon/InputCommon.vcproj @@ -45,7 +45,7 @@ UpdateInput() ) ++ok_count; - else - (*d)->ClearInputState(); + //else + // disabled. it might be causing problems + //(*d)->ClearInputState(); } return ( m_devices.size() == ok_count ); diff --git a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h index 8ecdf73de8..4133b02b5e 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h @@ -18,9 +18,11 @@ #if defined(HAVE_X11) && HAVE_X11 #define CIFACE_USE_XLIB #endif -#ifndef CIFACE_USE_DIRECTINPUT_JOYSTICK +//#ifndef CIFACE_USE_DIRECTINPUT_JOYSTICK +// enable SDL 1.2 in addition to DirectInput on windows, +// to support a few gamepads that aren't behaving with DInput #define CIFACE_USE_SDL -#endif +//#endif #if defined(__APPLE__) #define CIFACE_USE_OSX #endif 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,33 +180,38 @@ 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)) { + // 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; 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() diff --git a/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.cpp b/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.cpp index 24f934149c..1ccf3f460b 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.cpp @@ -3,6 +3,7 @@ #ifdef CIFACE_USE_SDL #include "SDL.h" +#include #ifdef _WIN32 #if SDL_VERSION_ATLEAST(1, 3, 0) @@ -209,7 +210,7 @@ bool Joystick::UpdateOutput() std::string Joystick::GetName() const { - return SDL_JoystickName( m_index ); + return StripSpaces(SDL_JoystickName(m_index)); } std::string Joystick::GetSource() const diff --git a/Source/Plugins/InputPluginCommon/Src/ConfigDiag.cpp b/Source/Plugins/InputPluginCommon/Src/ConfigDiag.cpp index ace72a812f..3413a334e3 100644 --- a/Source/Plugins/InputPluginCommon/Src/ConfigDiag.cpp +++ b/Source/Plugins/InputPluginCommon/Src/ConfigDiag.cpp @@ -1,7 +1,7 @@ #include "ConfigDiag.h" -#define _connect_macro_( b, f, c, s ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s ); +#define _connect_macro_( b, f, c, s ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s ) static Plugin* g_plugin; @@ -76,31 +76,14 @@ void PadSettingCheckBox::UpdateValue() value = 0.01 * GetValue(); } -PadSettingChoice::PadSettingChoice( wxWindow* const parent, ControllerEmu::ControlGroup::Setting* const setting ) - : wxChoice( parent, -1, wxDefaultPosition, wxSize( 54, -1 ) ) - , value(setting->value) -{ - Append( wxT("0") ); - for ( unsigned int i = setting->low; i<=setting->high; ++i ) - { - std::ostringstream ss; - ss << i; - Append( wxString::FromAscii( ss.str().c_str() ) ); - } - - UpdateGUI(); -} - void PadSettingChoice::UpdateGUI() { - std::ostringstream ss; - ss << int(value * 100); - SetSelection( FindString( wxString::FromAscii( ss.str().c_str() ) ) ); + SetValue(value * 100); } void PadSettingChoice::UpdateValue() { - value = float( atoi( GetStringSelection().mb_str() ) ) / 100; + value = float(GetValue()) / 100; } ControlDialog::ControlDialog( wxWindow* const parent, ControllerInterface::ControlReference* const ref, const std::vector& devs ) @@ -383,6 +366,20 @@ void GamepadPage::ConfigControl( wxCommandEvent& event ) UpdateGUI(); } +void GamepadPage::ClearControl( wxCommandEvent& event ) +{ + ControlButton* const btn = (ControlButton*)event.GetEventObject(); + btn->control_reference->control_qualifier.name.clear(); + btn->control_reference->device_qualifier = controller->default_device; + + g_plugin->controls_crit.Enter(); + controller->UpdateReferences( g_plugin->controller_interface ); + g_plugin->controls_crit.Leave(); + + // update changes + UpdateGUI(); +} + void ControlDialog::DetectControl( wxCommandEvent& event ) { // some hacks @@ -628,25 +625,27 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi ControlButton* const control_button = new ControlButton( parent, group->controls[c]->control_ref, 80 ); control_button->SetFont(m_SmallFont); - ControlButton* adv_button = new ControlButton( parent, group->controls[c]->control_ref, 18, "+" ); - adv_button->SetFont(m_SmallFont); controls.push_back( control_button ); control_buttons.push_back( control_button ); + control_button->SetToolTip(wxT("Right-click for more options.\nMiddle-click to clear.")); + _connect_macro_( control_button, GamepadPage::DetectControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink ); - _connect_macro_( adv_button, GamepadPage::ConfigControl, wxEVT_COMMAND_BUTTON_CLICKED, eventsink ); + _connect_macro_( control_button, GamepadPage::ConfigControl, wxEVT_RIGHT_UP, eventsink ); + _connect_macro_( control_button, GamepadPage::ClearControl, wxEVT_MIDDLE_DOWN, eventsink ); wxBoxSizer* const control_sizer = new wxBoxSizer( wxHORIZONTAL ); control_sizer->AddStretchSpacer( 1 ); - control_sizer->Add( label, 0, wxCENTER | wxRIGHT, 5 ); + control_sizer->Add( label, 0, wxCENTER | wxRIGHT, 3 ); control_sizer->Add( control_button, 0, 0, 0 ); - control_sizer->Add( adv_button, 0, 0, 5 ); - Add( control_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 ); + Add( control_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 3 ); } + wxMemoryDC dc; + switch ( group->type ) { case GROUP_TYPE_STICK : @@ -655,11 +654,8 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi case GROUP_TYPE_FORCE : { wxBitmap bitmap(64, 64); - wxMemoryDC dc; dc.SelectObject(bitmap); dc.Clear(); - dc.SelectObject(wxNullBitmap); - static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP ); std::vector< ControllerEmu::ControlGroup::Setting* >::const_iterator @@ -670,7 +666,7 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi for ( ; i!=e; ++i ) { PadSettingChoice* cbox = new PadSettingChoice( parent, *i ); - _connect_macro_( cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink ); + _connect_macro_( cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_SPINCTRL_UPDATED, eventsink ); options.push_back( cbox ); szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( (*i)->name ) ) ); szr->Add( cbox, 0, wxLEFT, 0 ); @@ -678,31 +674,31 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi wxBoxSizer* const h_szr = new wxBoxSizer( wxHORIZONTAL ); h_szr->Add( szr, 1, 0, 5 ); - h_szr->Add( static_bitmap, 0, wxALL|wxCENTER, 5 ); + h_szr->Add( static_bitmap, 0, wxALL|wxCENTER, 3 ); - Add( h_szr, 0, wxEXPAND|wxLEFT|wxCENTER|wxTOP, 5 ); + Add( h_szr, 0, wxEXPAND|wxLEFT|wxCENTER|wxTOP, 3 ); } break; case GROUP_TYPE_BUTTONS : { wxBitmap bitmap(int(12*group->controls.size()+1), 12); - wxMemoryDC dc; dc.SelectObject(bitmap); dc.Clear(); - dc.SelectObject(wxNullBitmap); static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP ); PadSettingChoice* const threshold_cbox = new PadSettingChoice( parent, group->settings[0] ); - _connect_macro_( threshold_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink ); + _connect_macro_( threshold_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_SPINCTRL_UPDATED, eventsink ); + + threshold_cbox->SetToolTip(wxT("Adjust the analog control pressure required to activate buttons.")); options.push_back( threshold_cbox ); wxBoxSizer* const szr = new wxBoxSizer( wxHORIZONTAL ); - szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( group->settings[0]->name ) ), 0, wxCENTER|wxRIGHT, 5 ); - szr->Add( threshold_cbox, 0, wxRIGHT, 5 ); + szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( group->settings[0]->name ) ), 0, wxCENTER|wxRIGHT, 3 ); + szr->Add( threshold_cbox, 0, wxRIGHT, 3 ); - Add( szr, 0, wxALL|wxCENTER, 5 ); - Add( static_bitmap, 0, wxALL|wxCENTER, 5 ); + Add( szr, 0, wxALL|wxCENTER, 3 ); + Add( static_bitmap, 0, wxALL|wxCENTER, 3 ); } break; case GROUP_TYPE_MIXED_TRIGGERS : @@ -716,10 +712,8 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi width = 64; } wxBitmap bitmap(width, height+1); - wxMemoryDC dc; dc.SelectObject(bitmap); dc.Clear(); - dc.SelectObject(wxNullBitmap); static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP ); std::vector::const_iterator @@ -728,15 +722,15 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi for ( ; i!=e; ++i ) { PadSettingChoice* cbox = new PadSettingChoice( parent, *i ); - _connect_macro_( cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink ); + _connect_macro_( cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_SPINCTRL_UPDATED, eventsink ); options.push_back( cbox ); wxBoxSizer* const szr = new wxBoxSizer( wxHORIZONTAL ); - szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( (*i)->name ) ), 0, wxCENTER|wxRIGHT, 5 ); - szr->Add( cbox, 0, wxRIGHT, 5 ); - Add( szr, 0, wxALL|wxCENTER, 5 ); + szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( (*i)->name ) ), 0, wxCENTER|wxRIGHT, 3 ); + szr->Add( cbox, 0, wxRIGHT, 3 ); + Add( szr, 0, wxALL|wxCENTER, 3 ); } - Add( static_bitmap, 0, wxALL|wxCENTER, 5 ); + Add( static_bitmap, 0, wxALL|wxCENTER, 3 ); } break; case GROUP_TYPE_EXTENSION : @@ -749,8 +743,8 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi _connect_macro_( attachments, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink ); _connect_macro_( configure, GamepadPage::ConfigExtension, wxEVT_COMMAND_BUTTON_CLICKED, eventsink ); - Add( attachments, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND, 5 ); - Add( configure, 0, wxALL|wxEXPAND, 5 ); + Add( attachments, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND, 3 ); + Add( configure, 0, wxALL|wxEXPAND, 3 ); } break; default : @@ -773,6 +767,8 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi break; } + dc.SelectObject(wxNullBitmap); + //AddStretchSpacer( 0 ); } @@ -827,12 +823,12 @@ GamepadPage::GamepadPage( wxWindow* parent, const unsigned int pad_num, ConfigDi _connect_macro_( device_cbox, GamepadPage::SetDevice, wxEVT_COMMAND_TEXT_ENTER, this ); _connect_macro_( refresh_button, GamepadPage::RefreshDevices, wxEVT_COMMAND_BUTTON_CLICKED, this ); - device_sbox->Add( device_cbox, 1, wxLEFT|wxRIGHT, 5 ); - device_sbox->Add( refresh_button, 0, wxRIGHT|wxBOTTOM, 5 ); + device_sbox->Add( device_cbox, 1, wxLEFT|wxRIGHT, 3 ); + device_sbox->Add( refresh_button, 0, wxRIGHT|wxBOTTOM, 3 ); wxStaticBoxSizer* const clear_sbox = new wxStaticBoxSizer( wxHORIZONTAL, this, wxT("Clear") ); wxButton* all_button = new wxButton( this, -1, wxT("All"), wxDefaultPosition, wxSize(48,-1) ); - clear_sbox->Add( all_button, 1, wxLEFT|wxRIGHT, 5 ); + clear_sbox->Add( all_button, 1, wxLEFT|wxRIGHT, 3 ); _connect_macro_(all_button, GamepadPage::ClearAll, wxEVT_COMMAND_BUTTON_CLICKED, this); @@ -846,10 +842,10 @@ GamepadPage::GamepadPage( wxWindow* parent, const unsigned int pad_num, ConfigDi _connect_macro_(psave_btn, GamepadPage::SaveProfile, wxEVT_COMMAND_BUTTON_CLICKED, this); _connect_macro_(pdelete_btn, GamepadPage::DeleteProfile, wxEVT_COMMAND_BUTTON_CLICKED, this); - profile_sbox->Add( profile_cbox, 1, wxLEFT, 5 ); - profile_sbox->Add( pload_btn, 0, wxLEFT, 5 ); - profile_sbox->Add( psave_btn, 0, 0, 5 ); - profile_sbox->Add( pdelete_btn, 0, wxRIGHT|wxBOTTOM, 5 ); + profile_sbox->Add( profile_cbox, 1, wxLEFT, 3 ); + profile_sbox->Add( pload_btn, 0, wxLEFT, 3 ); + profile_sbox->Add( psave_btn, 0, 0, 3 ); + profile_sbox->Add( pdelete_btn, 0, wxRIGHT|wxBOTTOM, 3 ); wxBoxSizer* const dio = new wxBoxSizer( wxHORIZONTAL ); dio->Add( device_sbox, 1, wxEXPAND|wxRIGHT, 5 ); diff --git a/Source/Plugins/InputPluginCommon/Src/ConfigDiag.h b/Source/Plugins/InputPluginCommon/Src/ConfigDiag.h index 9a2219b228..d8b28b66f7 100644 --- a/Source/Plugins/InputPluginCommon/Src/ConfigDiag.h +++ b/Source/Plugins/InputPluginCommon/Src/ConfigDiag.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -45,10 +46,14 @@ public: ControllerEmu::Extension* const extension; }; -class PadSettingChoice : public wxChoice, public PadSetting +class PadSettingChoice : public wxSpinCtrl, public PadSetting { public: - PadSettingChoice( wxWindow* const parent, ControllerEmu::ControlGroup::Setting* const setting ); + PadSettingChoice( wxWindow* const parent, ControllerEmu::ControlGroup::Setting* const setting ) + : wxSpinCtrl(parent, -1, wxEmptyString, wxDefaultPosition + , wxSize( 54, -1 ), 0, setting->low, setting->high, setting->value * 100) + , value(setting->value) {} + void UpdateGUI(); void UpdateValue(); @@ -167,6 +172,7 @@ public: void DeleteProfile( wxCommandEvent& event ); void ConfigControl( wxCommandEvent& event ); + void ClearControl( wxCommandEvent& event ); void DetectControl( wxCommandEvent& event ); void ConfigExtension( wxCommandEvent& event ); diff --git a/Source/Plugins/InputPluginCommon/Src/ControllerEmu.cpp b/Source/Plugins/InputPluginCommon/Src/ControllerEmu.cpp index a333d3b4c8..e1d433f33f 100644 --- a/Source/Plugins/InputPluginCommon/Src/ControllerEmu.cpp +++ b/Source/Plugins/InputPluginCommon/Src/ControllerEmu.cpp @@ -107,7 +107,10 @@ void ControllerEmu::ControlGroup::LoadConfig(IniFile::Section *sec, const std::s si = settings.begin(), se = settings.end(); for ( ; si!=se; ++si ) - (*si)->value = sec->Get((group+(*si)->name).c_str(), (*si)->default_value*100) / 100; + { + sec->Get((group+(*si)->name).c_str(), &(*si)->value, (*si)->default_value*100); + (*si)->value /= 100; + } // controls std::vector::const_iterator @@ -116,17 +119,18 @@ void ControllerEmu::ControlGroup::LoadConfig(IniFile::Section *sec, const std::s for ( ; ci!=ce; ++ci ) { // control and dev qualifier - (*ci)->control_ref->control_qualifier.name = sec->Get((group + (*ci)->name).c_str(), ""); - (*ci)->control_ref->device_qualifier.FromString( - sec->Get((group+(*ci)->name+"/Device").c_str(), defdev.c_str() ) ); + sec->Get((group + (*ci)->name).c_str(), &(*ci)->control_ref->control_qualifier.name, ""); + std::string dev; + sec->Get((group+(*ci)->name+"/Device").c_str(), &dev, defdev.c_str()); + (*ci)->control_ref->device_qualifier.FromString(dev); // range - (*ci)->control_ref->range = sec->Get( (group+(*ci)->name+"/Range").c_str(), 100.0f ) / 100; + sec->Get( (group+(*ci)->name+"/Range").c_str(), &(*ci)->control_ref->range, 100.0f); + (*ci)->control_ref->range /= 100; // input mode if ( (*ci)->control_ref->is_input ) - ((ControllerInterface::InputReference*)((*ci)->control_ref))->mode - = sec->Get( (group+(*ci)->name+"/Mode").c_str(), 0 ); + sec->Get( (group+(*ci)->name+"/Mode").c_str(), &((ControllerInterface::InputReference*)((*ci)->control_ref))->mode, 0 ); } // extensions @@ -136,7 +140,8 @@ void ControllerEmu::ControlGroup::LoadConfig(IniFile::Section *sec, const std::s ex->switch_extension = 0; unsigned int n = 0; - const std::string extname = sec->Get((base + name).c_str(), ""); + std::string extname; + sec->Get((base + name).c_str(), &extname, ""); std::vector::const_iterator ai = ((Extension*)this)->attachments.begin(), @@ -157,7 +162,7 @@ void ControllerEmu::LoadConfig( IniFile::Section *sec, const std::string& base ) std::string defdev = default_device.ToString(); if (base.empty()) { - defdev = sec->Get((base + "Device").c_str(), ""); + sec->Get((base + "Device").c_str(), &defdev, ""); default_device.FromString(defdev); } std::vector::const_iterator i = groups.begin(), @@ -175,7 +180,7 @@ void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section *sec, const std:: si = settings.begin(), se = settings.end(); for ( ; si!=se; ++si ) - sec->Set( (group+(*si)->name).c_str(), (*si)->value*100.0f); + sec->Set( (group+(*si)->name).c_str(), (*si)->value*100.0f, (*si)->default_value*100.0f); // controls std::vector::const_iterator @@ -184,23 +189,28 @@ void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section *sec, const std:: for ( ; ci!=ce; ++ci ) { // control and dev qualifier - sec->Set( (group+(*ci)->name).c_str(), (*ci)->control_ref->control_qualifier.name ); - sec->Set( (group+(*ci)->name+"/Device").c_str(), (*ci)->control_ref->device_qualifier.ToString()); + sec->Set( (group+(*ci)->name).c_str(), (*ci)->control_ref->control_qualifier.name, ""); + sec->Set( (group+(*ci)->name+"/Device").c_str(), (*ci)->control_ref->device_qualifier.ToString(), defdev); // range - sec->Set( (group+(*ci)->name+"/Range").c_str(), (*ci)->control_ref->range*100.0f); + sec->Set( (group+(*ci)->name+"/Range").c_str(), (*ci)->control_ref->range*100.0f, 100.0f); // input mode if ( (*ci)->control_ref->is_input ) - sec->Set( (group+(*ci)->name+"/Mode").c_str(), - ((ControllerInterface::InputReference*)((*ci)->control_ref))->mode); + { + const int mode = ((ControllerInterface::InputReference*)((*ci)->control_ref))->mode; + if (mode) + sec->Set((group+(*ci)->name+"/Mode").c_str(), mode); + else + sec->Delete((group+(*ci)->name+"/Mode").c_str()); + } } // extensions if ( GROUP_TYPE_EXTENSION == type ) { Extension* const ext = ((Extension*)this); - sec->Set((base + name).c_str(), ext->attachments[ext->switch_extension]->GetName()); + sec->Set((base + name).c_str(), ext->attachments[ext->switch_extension]->GetName(), "None"); std::vector::const_iterator ai = ((Extension*)this)->attachments.begin(), @@ -214,7 +224,7 @@ void ControllerEmu::SaveConfig( IniFile::Section *sec, const std::string& base ) { const std::string defdev = default_device.ToString(); if ( base.empty() ) - sec->Set( std::string(" ") + base + "Device", defdev ); + sec->Set( (/*std::string(" ") +*/ base + "Device").c_str(), defdev, ""); std::vector::const_iterator i = groups.begin(), e = groups.end(); @@ -229,7 +239,7 @@ ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGrou controls.push_back( new Input( "Modifier" ) ); - settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); + settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) ); settings.push_back( new Setting("Square Stick", 0 ) ); } @@ -259,7 +269,7 @@ ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GR controls.push_back( new Input( "Backward" ) ); controls.push_back( new Input( "Modifier" ) ); - settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); + settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) ); } ControllerEmu::Tilt::Tilt( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_TILT ) @@ -273,7 +283,7 @@ ControllerEmu::Tilt::Tilt( const char* const _name ) : ControlGroup( _name, GROU controls.push_back( new Input( "Modifier" ) ); - settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) ); + settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) ); settings.push_back( new Setting("Circle Stick", 0 ) ); } diff --git a/Source/Plugins/InputPluginCommon/Src/ControllerEmu.h b/Source/Plugins/InputPluginCommon/Src/ControllerEmu.h index ee4b689356..8ea5ebf9d2 100644 --- a/Source/Plugins/InputPluginCommon/Src/ControllerEmu.h +++ b/Source/Plugins/InputPluginCommon/Src/ControllerEmu.h @@ -85,7 +85,7 @@ public: public: Setting(const char* const _name, const ControlState def_value - , const unsigned int _low = 1, const unsigned int _high = 100 ) + , const unsigned int _low = 0, const unsigned int _high = 100 ) : name(_name) , value(def_value) , default_value(def_value)