/* 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" // Constructor of GamepadConfiguration GamepadConfiguration::GamepadConfiguration(int pad, wxWindow *parent) : wxDialog( parent, // Parent wxID_ANY, // ID _T("Gamepad configuration"), // Title wxDefaultPosition, // Position wxSize(400, 270), // Width + Length // Style wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN) { m_pad_id = pad; m_pan_gamepad_config = new wxPanel( this, // Parent wxID_ANY, // ID wxDefaultPosition, // Position wxSize(300, 230) // Size ); m_cb_rumble = new wxCheckBox( m_pan_gamepad_config, // Parent wxID_ANY, // ID _T("&Enable rumble"), // Label wxPoint(20, 20) // Position ); m_cb_hack_sixaxis_usb = new wxCheckBox( m_pan_gamepad_config, // Parent wxID_ANY, // ID _T("&Hack: Sixaxis/DS3 plugged in USB"), // Label wxPoint(20, 40) // Position ); m_cb_hack_sixaxis_pressure = new wxCheckBox( m_pan_gamepad_config, // Parent wxID_ANY, // ID _T("&Hack: Sixaxis/DS3 pressure"), // Label wxPoint(20, 60) // Position ); wxString txt_rumble = wxT("Rumble intensity"); m_lbl_rumble_intensity = new wxStaticText( m_pan_gamepad_config, // Parent wxID_ANY, // ID txt_rumble, // Text which must be displayed wxPoint(20, 90), // Position wxDefaultSize // Size ); m_sl_rumble_intensity = new wxSlider( m_pan_gamepad_config, // Parent wxID_ANY, // ID 0, // value 0, // min value 0x0000 0x7FFF, // max value 0x7FFF wxPoint(150, 83), // Position wxSize(200, 50), // Size wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM ); wxString txt_joystick = wxT("Joystick sensibility"); m_lbl_rumble_intensity = new wxStaticText( m_pan_gamepad_config, // Parent wxID_ANY, // ID txt_joystick, // Text which must be displayed wxPoint(20, 150), // Position wxDefaultSize // Size ); m_sl_joystick_sensibility = new wxSlider( m_pan_gamepad_config, // Parent wxID_ANY, // ID 0, // value 0, // min value 200, // max value wxPoint(150, 143), // Position wxSize(200, 50), // Size wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM ); m_bt_cancel = new wxButton( m_pan_gamepad_config, // Parent wxID_ANY, // ID _T("&Cancel"), // Label wxPoint(250, 210), // Position wxSize(60, 25) // Size ); m_bt_ok = new wxButton( m_pan_gamepad_config, // Parent wxID_ANY, // ID _T("&OK"), // Label wxPoint(320, 210), // Position wxSize(60, 25) // Size ); Bind(wxEVT_BUTTON, &GamepadConfiguration::OnButtonClicked, this); Bind(wxEVT_SCROLL_THUMBRELEASE, &GamepadConfiguration::OnSliderReleased, this); Bind(wxEVT_CHECKBOX, &GamepadConfiguration::OnCheckboxChange, this); repopulate(); } /** 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 gamepad 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 } } /****************************************/ /*********** Events functions ***********/ /****************************************/ /** * Button event, called when a button is clicked */ void GamepadConfiguration::OnButtonClicked(wxCommandEvent &event) { // Affichage d'un message à chaque clic sur le bouton wxButton *bt_tmp = (wxButton *)event.GetEventObject(); // get the button object int bt_id = bt_tmp->GetId(); // get the real ID if (bt_id == m_bt_ok->GetId()) // If the button ID is equals to the Ok button ID { Close(); // Close the window } else if (bt_id == m_bt_cancel->GetId()) // If the button ID is equals to the cancel button ID { reset(); // reinitialize the value of each parameters Close(); // Close the window } } /** * 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(); // get the slider object int sl_id = sl_tmp->GetId(); // slider id if (sl_id == m_sl_rumble_intensity->GetId()) // if this is the rumble intensity slider { u32 intensity = m_sl_rumble_intensity->GetValue(); // get the new value conf->set_ff_intensity(intensity); // and set the force feedback intensity value with it // get the rumble intensity float strength = m_sl_rumble_intensity->GetValue(); /* * convert in a float value between 0 and 1, and run rumble feedback * 1 -> 0x7FFF * 0 -> 0x0000 * x -> ? * * formula : strength = x*1/0x7FFF * x : intensity variable * 0x7FFF : maximum intensity * 1 : maximum value of the intensity for the sdl rumble test */ s_vgamePad[m_pad_id]->TestForce(strength / 0x7FFF); } else if (sl_id == m_sl_joystick_sensibility->GetId()) { u32 sensibility = m_sl_joystick_sensibility->GetValue(); // get the new value conf->set_sensibility(sensibility); // and set the joystick sensibility } } /** * 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 == m_cb_rumble->GetId()) { 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(); } } else if (cb_id == m_cb_hack_sixaxis_usb->GetId()) { conf->pad_options[m_pad_id].sixaxis_usb = (m_cb_hack_sixaxis_usb->GetValue()) ? (u32)1 : (u32)0; } else if (cb_id == m_cb_hack_sixaxis_pressure->GetId()) { conf->pad_options[m_pad_id].sixaxis_pressure = (m_cb_hack_sixaxis_pressure->GetValue()) ? (u32)1 : (u32)0; } } /****************************************/ /*********** Methods functions **********/ /****************************************/ // Reset checkbox and slider values void GamepadConfiguration::reset() { m_cb_rumble->SetValue(m_init_rumble); m_cb_hack_sixaxis_usb->SetValue(m_init_hack_sixaxis); m_cb_hack_sixaxis_pressure->SetValue(m_init_hack_sixaxis_pressure); m_sl_rumble_intensity->SetValue(m_init_rumble_intensity); m_sl_joystick_sensibility->SetValue(m_init_joystick_sensibility); } // Set button values void GamepadConfiguration::repopulate() { bool val = conf->pad_options[m_pad_id].forcefeedback; m_init_rumble = val; m_cb_rumble->SetValue(val); val = conf->pad_options[m_pad_id].sixaxis_usb; m_init_hack_sixaxis = val; m_cb_hack_sixaxis_usb->SetValue(val); val = conf->pad_options[m_pad_id].sixaxis_pressure; m_init_hack_sixaxis_pressure = val; m_cb_hack_sixaxis_pressure->SetValue(val); int tmp = conf->get_ff_intensity(); m_sl_rumble_intensity->SetValue(tmp); m_init_rumble_intensity = tmp; tmp = conf->get_sensibility(); m_sl_joystick_sensibility->SetValue(tmp); m_init_joystick_sensibility = tmp; // enable rumble intensity slider if the checkbox is checked if (m_cb_rumble->GetValue()) m_sl_rumble_intensity->Enable(); else // disable otherwise m_sl_rumble_intensity->Disable(); }