pcsx2/plugins/onepad/wx_dialog/GamepadConfiguration.cpp

186 lines
6.9 KiB
C++

/* GamepadConfiguration.cpp
* PCSX2 Dev Team
* Copyright (C) 2015
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "GamepadConfiguration.h"
GamepadConfiguration::GamepadConfiguration(int pad, wxWindow *parent)
: wxDialog(parent, wxID_ANY, _T("Gamepad"), wxDefaultPosition, wxDefaultSize,
wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
{
m_pad_id = pad;
wxBoxSizer *gamepad_box = new wxBoxSizer(wxVERTICAL);
wxArrayString choices;
for (const auto &j : s_vgamePad) {
choices.Add(j->GetName());
}
m_joy_map = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
m_cb_rumble = new wxCheckBox(this, enable_rumble_id, _T("&Enable rumble"));
wxStaticBoxSizer *rumble_box = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Rumble intensity"));
m_sl_rumble_intensity = new wxSlider(this, rumble_slider_id, 0, 0, 0x7FFF, wxDefaultPosition, wxDefaultSize,
wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM);
wxStaticBoxSizer *joy_box = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Joystick sensibility"));
m_sl_joystick_sensibility = new wxSlider(this, joy_slider_id, 0, 0, 200, wxDefaultPosition, wxDefaultSize,
wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM);
gamepad_box->Add(m_joy_map, wxSizerFlags().Expand().Border(wxALL, 5));
gamepad_box->Add(m_cb_rumble, wxSizerFlags().Expand());
rumble_box->Add(m_sl_rumble_intensity, wxSizerFlags().Expand().Border(wxALL, 5));
joy_box->Add(m_sl_joystick_sensibility, wxSizerFlags().Expand().Border(wxALL, 5));
gamepad_box->Add(rumble_box, wxSizerFlags().Expand().Border(wxALL, 5));
gamepad_box->Add(joy_box, wxSizerFlags().Expand().Border(wxALL, 5));
gamepad_box->Add(CreateSeparatedButtonSizer(wxOK), wxSizerFlags().Right().Border(wxALL, 5));
Bind(wxEVT_BUTTON, &GamepadConfiguration::OnOk, this, wxID_OK);
Bind(wxEVT_SCROLL_THUMBRELEASE, &GamepadConfiguration::OnSliderReleased, this);
Bind(wxEVT_CHECKBOX, &GamepadConfiguration::OnCheckboxChange, this);
Bind(wxEVT_CHOICE, &GamepadConfiguration::OnChoiceChange, this);
repopulate();
SetSizerAndFit(gamepad_box);
}
/**
Initialize the frame
Check if a gamepad is detected
Check if the gamepad support rumbles
*/
void GamepadConfiguration::InitGamepadConfiguration()
{
repopulate(); // Set label and fit simulated key array
/*
* Check if there exist at least one pad available
* if the pad id is 0, you need at least 1 gamepad connected,
* if the pad id is 1, you need at least 2 gamepads connected,
* Prevent to use a none initialized value on s_vgamePad (core dump)
*/
if (s_vgamePad.size() >= m_pad_id + 1) {
/*
* Determine if the device can use rumble
* Use TestForce with a very low strength (can't be felt)
* May be better to create a new function in order to check only that
*/
// Bad idea. Some connected devices might support rumble but not all connected devices.
// if (!s_vgamePad[m_pad_id]->TestForce(0.001f)) {
// wxMessageBox(L"Rumble is not available for your device.");
// m_cb_rumble->Disable(); // disable the rumble checkbox
// m_sl_rumble_intensity->Disable(); // disable the rumble intensity slider
// }
} else {
wxMessageBox(L"No gamepad detected.");
m_sl_joystick_sensibility->Disable(); // disable the joystick sensibility slider
m_cb_rumble->Disable(); // disable the rumble checkbox
m_sl_rumble_intensity->Disable(); // disable the rumble intensity slider
}
}
void GamepadConfiguration::OnOk(wxCommandEvent &event)
{
Destroy();
}
/**
* Slider event, called when the use release the slider button
* @FIXME The current solution can't change the joystick sensibility and the rumble intensity
* for a specific gamepad. The same value is used for both
*/
void GamepadConfiguration::OnSliderReleased(wxCommandEvent &event)
{
wxSlider *sl_tmp = (wxSlider *)event.GetEventObject();
int sl_id = sl_tmp->GetId();
if (sl_id == rumble_slider_id)
{
g_conf.set_ff_intensity(m_sl_rumble_intensity->GetValue());
// convert in a float value between 0 and 1, and run rumble feedback.
// 0 to 1 scales to 0x0 to 0x7FFF
s_vgamePad[m_pad_id]->TestForce(m_sl_rumble_intensity->GetValue() / 0x7FFF);
}
else if (sl_id == joy_slider_id)
{
g_conf.set_sensibility(m_sl_joystick_sensibility->GetValue());
}
}
/**
* Checkbox event, called when the value of the checkbox change
*/
void GamepadConfiguration::OnCheckboxChange(wxCommandEvent &event)
{
wxCheckBox *cb_tmp = (wxCheckBox *)event.GetEventObject(); // get the slider object
int cb_id = cb_tmp->GetId();
if (cb_id == enable_rumble_id)
{
g_conf.pad_options[m_pad_id].forcefeedback = (m_cb_rumble->GetValue()) ? (u32)1 : (u32)0;
if (m_cb_rumble->GetValue())
{
s_vgamePad[m_pad_id]->TestForce();
m_sl_rumble_intensity->Enable();
}
else
{
m_sl_rumble_intensity->Disable();
}
}
}
/*
* Checkbox event, called when the value of the choice box change
*/
void GamepadConfiguration::OnChoiceChange(wxCommandEvent &event)
{
wxChoice *choice_tmp = (wxChoice *)event.GetEventObject();
int id = choice_tmp->GetSelection();
if (id != wxNOT_FOUND)
{
g_conf.set_joy_uid(m_pad_id, GamePad::index_to_uid(id));
}
}
/****************************************/
/*********** Methods functions **********/
/****************************************/
// Set button values
void GamepadConfiguration::repopulate()
{
m_cb_rumble->SetValue(g_conf.pad_options[m_pad_id].forcefeedback);
m_sl_rumble_intensity->SetValue(g_conf.get_ff_intensity());
m_sl_joystick_sensibility->SetValue(g_conf.get_sensibility());
u32 joyid = GamePad::uid_to_index(m_pad_id);
if (joyid < m_joy_map->GetCount() && !m_joy_map->IsEmpty())
m_joy_map->SetSelection(joyid);
// enable rumble intensity slider if the checkbox is checked
m_sl_rumble_intensity->Enable(m_cb_rumble->GetValue());
}