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)