From 823a37aed7b2762250a12199715d810b5f275a6b Mon Sep 17 00:00:00 2001 From: kust2708 Date: Sat, 17 Oct 2015 18:57:28 +0200 Subject: [PATCH] OnePad : New GUI based on gwWidget Buttons done, configuration initialization done. Still need to add Gamepad and Joysticks configuration frames. Require png file for the moment (the embedded picture will be fixed after). New Onepad GUI based on wxWidget (Main frame almost finish) Background picture is now embedded Button binding works Loading and saving works Need to add feedback and gamepad, joysticks configuration frame Modification of the onepad CMakeList.txt Automatic generation of images headers using perl script Modification of the test feedback function --- .../include/Utilities}/EmbeddedImage.h | 0 pcsx2/gui/AppRes.cpp | 2 +- pcsx2/gui/Dialogs/AboutBoxDialog.cpp | 2 +- plugins/onepad/CMakeLists.txt | 59 +- plugins/onepad/GamePad.h | 4 +- plugins/onepad/Linux/GamepadConfiguration.cpp | 284 +++++ plugins/onepad/Linux/GamepadConfiguration.h | 59 + .../onepad/Linux/JoystickConfiguration.cpp | 273 +++++ plugins/onepad/Linux/JoystickConfiguration.h | 59 + plugins/onepad/Linux/dialog.cpp | 1077 ++++++++--------- plugins/onepad/Linux/dialog.h | 102 ++ plugins/onepad/Linux/ini.cpp | 1 - plugins/onepad/Linux/opPanel.cpp | 204 ++++ plugins/onepad/Linux/opPanel.h | 70 ++ plugins/onepad/SDL/joystick.cpp | 13 +- plugins/onepad/SDL/joystick.h | 4 +- plugins/onepad/controller.h | 4 +- plugins/onepad/onepad.cpp | 2 +- plugins/onepad/onepad.h | 48 +- 19 files changed, 1672 insertions(+), 595 deletions(-) rename {pcsx2/gui/Resources => common/include/Utilities}/EmbeddedImage.h (100%) create mode 100644 plugins/onepad/Linux/GamepadConfiguration.cpp create mode 100644 plugins/onepad/Linux/GamepadConfiguration.h create mode 100644 plugins/onepad/Linux/JoystickConfiguration.cpp create mode 100644 plugins/onepad/Linux/JoystickConfiguration.h create mode 100644 plugins/onepad/Linux/dialog.h create mode 100644 plugins/onepad/Linux/opPanel.cpp create mode 100644 plugins/onepad/Linux/opPanel.h diff --git a/pcsx2/gui/Resources/EmbeddedImage.h b/common/include/Utilities/EmbeddedImage.h similarity index 100% rename from pcsx2/gui/Resources/EmbeddedImage.h rename to common/include/Utilities/EmbeddedImage.h diff --git a/pcsx2/gui/AppRes.cpp b/pcsx2/gui/AppRes.cpp index 1bb548ad1f..37899bd8c0 100644 --- a/pcsx2/gui/AppRes.cpp +++ b/pcsx2/gui/AppRes.cpp @@ -23,7 +23,7 @@ #include "MSWstuff.h" -#include "Resources/EmbeddedImage.h" +#include "Utilities/EmbeddedImage.h" #include "Resources/BackgroundLogo.h" #include "Resources/ButtonIcon_Camera.h" diff --git a/pcsx2/gui/Dialogs/AboutBoxDialog.cpp b/pcsx2/gui/Dialogs/AboutBoxDialog.cpp index bd03aef6f2..00d2cb18d9 100644 --- a/pcsx2/gui/Dialogs/AboutBoxDialog.cpp +++ b/pcsx2/gui/Dialogs/AboutBoxDialog.cpp @@ -19,7 +19,7 @@ #include "Dialogs/ModalPopups.h" -#include "Resources/EmbeddedImage.h" +#include "Utilities/EmbeddedImage.h" #include "Resources/Logo.h" #include diff --git a/plugins/onepad/CMakeLists.txt b/plugins/onepad/CMakeLists.txt index b0c93908c7..938f75ee09 100644 --- a/plugins/onepad/CMakeLists.txt +++ b/plugins/onepad/CMakeLists.txt @@ -5,9 +5,36 @@ if(NOT TOP_CMAKE_WAS_SOURCED) It is advice to delete all wrongly generated cmake stuff => CMakeFiles & CMakeCache.txt") endif() +set(compiled_images "${CMAKE_BINARY_DIR}/plugins/onepad/ImgHeader") +set(image_sources "${CMAKE_SOURCE_DIR}/plugins/onepad/Img") +set(linux_sources "Linux") +set(linux_headers "Linux") + + +set(onepadGuiResources + ${compiled_images}/analog.h + ${compiled_images}/circle.h + ${compiled_images}/cross.h + ${compiled_images}/dp_bottom.h + ${compiled_images}/dp_left.h + ${compiled_images}/dp_right.h + ${compiled_images}/dp_up.h + ${compiled_images}/dualshock2.h + ${compiled_images}/joystick_cursor.h + ${compiled_images}/l1.h + ${compiled_images}/r1.h + ${compiled_images}/l2.h + ${compiled_images}/r2.h + ${compiled_images}/l3.h + ${compiled_images}/r3.h + ${compiled_images}/select.h + ${compiled_images}/square.h + ${compiled_images}/start.h + ${compiled_images}/triangle.h + ) # plugin name -set(Output onepad-1.1.0) +set(Output onepad-1.2.0) set(onepadFinalFlags "") # onepad sources @@ -31,13 +58,19 @@ set(onepadHeaders # onepad Linux sources set(onepadLinuxSources - Linux/ini.cpp - Linux/dialog.cpp - Linux/linux.cpp) + ${linux_sources}/ini.cpp + ${linux_sources}/dialog.cpp + ${linux_sources}/linux.cpp + ${linux_sources}/opPanel.cpp + ${linux_sources}/GamepadConfiguration.cpp + ${linux_headers}/JoystickConfiguration.cpp) # onepad Linux headers set(onepadLinuxHeaders - Linux/linux.h) + ${linux_headers}/linux.h + ${linux_headers}/opPanel.h + ${linux_headers}/GamepadConfiguration.h + ${linux_headers}/JoystickConfiguration.h) # onepad Windows sources set(onepadWindowsSources @@ -70,6 +103,22 @@ set(onepadFinalSources ${onepadHeaders} ${onepadLinuxSources} ${onepadLinuxHeaders} + ${onepadGuiResources} ) +include_directories( + ${CMAKE_BINARY_DIR}/plugins/onepad/ +) + +### Generate the resources files +file(MAKE_DIRECTORY ${compiled_images}) + +foreach(result_file IN ITEMS + analog circle cross dp_bottom dp_left dp_right dp_up dualshock2 + joystick_cursor l1 r1 l2 r2 l3 r3 select square start triangle) + add_custom_command( + OUTPUT "${compiled_images}/${result_file}.h" + COMMAND perl ${CMAKE_SOURCE_DIR}/linux_various/hex2h.pl "${image_sources}/${result_file}.png" "${compiled_images}/${result_file}" ) +endforeach() + add_pcsx2_plugin(${Output} "${onepadFinalSources}" "${onepadFinalLibs}" "${onepadFinalFlags}") diff --git a/plugins/onepad/GamePad.h b/plugins/onepad/GamePad.h index 95ffbc8431..a3681bcf8c 100644 --- a/plugins/onepad/GamePad.h +++ b/plugins/onepad/GamePad.h @@ -38,7 +38,7 @@ class GamePad **/ static void UpdateGamePadState(); - /** + /** * Causes devices to rumble * Rumble will differ according to type which is either 0(small motor) or 1(big motor) **/ @@ -53,7 +53,7 @@ class GamePad /** * Used for GUI checkbox to give feedback to the user **/ - virtual void TestForce(){return;} + virtual bool TestForce(float strength = 0.6){return false;} virtual bool PollButtons(u32 &pkey){return false;} virtual bool PollAxes(u32 &pkey){return false;} diff --git a/plugins/onepad/Linux/GamepadConfiguration.cpp b/plugins/onepad/Linux/GamepadConfiguration.cpp new file mode 100644 index 0000000000..1b6ade04f0 --- /dev/null +++ b/plugins/onepad/Linux/GamepadConfiguration.cpp @@ -0,0 +1,284 @@ +/* OnePAD + * 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" + +// Construtor of GamepadConfiguration +GamepadConfiguration::GamepadConfiguration(int pad, wxWindow *parent) : wxFrame( + parent, // Parent + wxID_ANY, // ID + _T("Gamepad configuration"), // Title + wxDefaultPosition, // Position + wxSize(400, 200), // Width + Lenght + // Style + wxSYSTEM_MENU | + wxCAPTION | + wxCLOSE_BOX | + wxCLIP_CHILDREN + ) +{ + + this->pad_id = pad; + this->pan_gamepad_config = new wxPanel( + this, // Parent + wxID_ANY, // ID + wxDefaultPosition, // Prosition + wxSize(300, 200) // Size + ); + this->cb_rumble = new wxCheckBox( + this->pan_gamepad_config, // Parent + wxID_ANY, // ID + _T("&Enable rumble"), // Label + wxPoint(20, 20) // Position + ); + + this->cb_hack_sixaxis = new wxCheckBox( + this->pan_gamepad_config, // Parent + wxID_ANY, // ID + _T("&Hack Sixaxis/DS3 plugged in USB"), // Label + wxPoint(20, 40) // Position + ); + + wxString txt_rumble = wxT("Rumble intensity"); + this->lbl_rumble_intensity = new wxStaticText( + this->pan_gamepad_config, // Parent + wxID_ANY, // ID + txt_rumble, // Text which must be displayed + wxPoint(20, 70), // Position + wxDefaultSize // Size + ); + + this->sl_rumble_intensity = new wxSlider( + this->pan_gamepad_config, // Parent + wxID_ANY, // ID + 0, // value + 0, // min value 0x0000 + 0x7FFF, // max value 0x7FFF + wxPoint(150, 63), // Position + wxSize(200, 30) // Size + ); + + wxString txt_joystick = wxT("Joystick sensibility"); + this->lbl_rumble_intensity = new wxStaticText( + this->pan_gamepad_config, // Parent + wxID_ANY, // ID + txt_joystick, // Text which must be displayed + wxPoint(20, 100), // Position + wxDefaultSize // Size + ); + + this->sl_joystick_sensibility = new wxSlider( + this->pan_gamepad_config, // Parent + wxID_ANY, // ID + 0, // value + 0, // min value + 100, // max value + wxPoint(150, 93), // Position + wxSize(200, 30) // Size + ); + + this->bt_ok = new wxButton( + this->pan_gamepad_config, // Parent + wxID_ANY, // ID + _T("&OK"), // Label + wxPoint(250, 130), // Position + wxSize(60,25) // Size + ); + + this->bt_cancel = new wxButton( + this->pan_gamepad_config, // Parent + wxID_ANY, // ID + _T("&Cancel"), // Label + wxPoint(320, 130), // Position + wxSize(60,25) // Size + ); + + // Connect the buttons to the OnButtonClicked Event + this->Connect( + wxEVT_COMMAND_BUTTON_CLICKED, + wxCommandEventHandler(GamepadConfiguration::OnButtonClicked) + ); + // Connect the sliders to the OnSliderReleased Event + this->Connect( + wxEVT_SCROLL_THUMBRELEASE, + wxCommandEventHandler(GamepadConfiguration::OnSliderReleased) + ); + // Connect the checkboxes to the OnCheckboxClicked Event + this->Connect( + wxEVT_CHECKBOX, + wxCommandEventHandler(GamepadConfiguration::OnCheckboxChange) + ); +} + +/** + Initialize the frame + Check if a gamepad is detected + Check if the gamepad support rumbles +*/ +void GamepadConfiguration::InitGamepadConfiguration() +{ + this->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() >= this->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 + */ + + if(!s_vgamePad[this->pad_id]->TestForce(0.001f)) + { + wxMessageBox("Rumble is not available for your device."); + this->cb_rumble->Disable(); // disable the rumble checkbox + this->sl_rumble_intensity->Disable(); // disable the rumble intensity slider + } + } + else + { + wxMessageBox("No gamepad detected."); + this->sl_joystick_sensibility->Disable(); // disable the joystick sensibility slider + this->cb_rumble->Disable(); // disable the rumble checkbox + this->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 == this->bt_ok->GetId()) // If the button ID is equals to the Ok button ID + { + this->Close(); // Close the window + } + else if(bt_id == this->bt_cancel->GetId()) // If the button ID is equals to the cancel button ID + { + this->reset(); // reinitialize the value of each parameters + this->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 == this->sl_rumble_intensity->GetId()) // if this is the rumble intensity slider + { + u32 intensity = this->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 = this->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[this->pad_id]->TestForce(strength/0x7FFF); + } + else if(sl_id == this->sl_joystick_sensibility->GetId()) + { + u32 sensibility = this->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 == this->cb_rumble->GetId()) + { + conf->pad_options[this->pad_id].forcefeedback = (this->cb_rumble->GetValue())?(u32)1:(u32)0; + if(this->cb_rumble->GetValue()) + { + s_vgamePad[this->pad_id]->TestForce(); + this->sl_rumble_intensity->Enable(); + } + else + { + this->sl_rumble_intensity->Disable(); + } + } + else if(cb_id == this->cb_hack_sixaxis->GetId()) + { + conf->pad_options[this->pad_id].sixaxis_usb = (this->cb_hack_sixaxis->GetValue())?(u32)1:(u32)0; + } +} + +/****************************************/ +/*********** Methods functions **********/ +/****************************************/ + +// Reset checkbox and slider values +void GamepadConfiguration::reset() +{ + this->cb_rumble->SetValue(this->init_rumble); + this->cb_hack_sixaxis->SetValue(this->init_hack_sixaxis); + this->sl_rumble_intensity->SetValue(this->init_rumble_intensity); + this->sl_joystick_sensibility->SetValue(this->init_joystick_sensibility); +} + +// Set button values +void GamepadConfiguration::repopulate() +{ + bool val = conf->pad_options[this->pad_id].forcefeedback; + this->init_rumble = val; + this->cb_rumble->SetValue(val); + val = conf->pad_options[this->pad_id].sixaxis_usb; + this->init_hack_sixaxis = val; + this->cb_hack_sixaxis->SetValue(val); + int tmp = conf->get_ff_intensity(); + this->sl_rumble_intensity->SetValue(tmp); + this->init_rumble_intensity = tmp; + tmp = conf->get_sensibility(); + this->sl_joystick_sensibility->SetValue(tmp); + this->init_joystick_sensibility = tmp; + + // enable rumble intensity slider if the checkbox is checked + if(this->cb_rumble->GetValue()) + this->sl_rumble_intensity->Enable(); + else // disable otherwise + this->sl_rumble_intensity->Disable(); +} diff --git a/plugins/onepad/Linux/GamepadConfiguration.h b/plugins/onepad/Linux/GamepadConfiguration.h new file mode 100644 index 0000000000..dfdcca709e --- /dev/null +++ b/plugins/onepad/Linux/GamepadConfiguration.h @@ -0,0 +1,59 @@ +/* onepad.h + * 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 + */ + +#pragma once + +#ifndef __GAMEPADCONFIGURATION_H__ +#define __GAMEPADCONFIGURATION_H__ + +#include +#include +#include +#include +#include +#include +#include "GamePad.h" +#include "keyboard.h" +#include "onepad.h" + +class GamepadConfiguration : public wxFrame +{ + wxPanel* pan_gamepad_config; + wxCheckBox *cb_rumble, *cb_hack_sixaxis; + wxSlider *sl_rumble_intensity, *sl_joystick_sensibility; + wxButton *bt_ok, *bt_cancel; + wxStaticText *lbl_rumble_intensity, *lbl_joystick_sensibility; + + int pad_id; + u32 init_rumble_intensity, init_joystick_sensibility; + bool init_rumble, init_hack_sixaxis; + + // methods + void repopulate(); + void reset(); + // Events + void OnButtonClicked(wxCommandEvent&); + void OnSliderReleased(wxCommandEvent&); + void OnCheckboxChange(wxCommandEvent&); + +public: + GamepadConfiguration(int, wxWindow*); + void InitGamepadConfiguration(); +}; + +#endif // __GAMEPADCONFIGURATION_H__ diff --git a/plugins/onepad/Linux/JoystickConfiguration.cpp b/plugins/onepad/Linux/JoystickConfiguration.cpp new file mode 100644 index 0000000000..bb0d934293 --- /dev/null +++ b/plugins/onepad/Linux/JoystickConfiguration.cpp @@ -0,0 +1,273 @@ +/* OnePAD + * 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 "JoystickConfiguration.h" + +// Construtor of JoystickConfiguration +JoystickConfiguration::JoystickConfiguration(int pad, bool left, wxWindow *parent) : wxFrame( + parent, // Parent + wxID_ANY, // ID + _T("Gamepad configuration"), // Title + wxDefaultPosition, // Position + wxSize(400, 200), // Width + Lenght + // Style + wxSYSTEM_MENU | + wxCAPTION | + wxCLOSE_BOX | + wxCLIP_CHILDREN + ) +{ + + this->pad_id = pad; + this->isForLeftJoystick = left; + this->pan_joystick_config = new wxPanel( + this, // Parent + wxID_ANY, // ID + wxDefaultPosition, // Prosition + wxSize(300, 200) // Size + ); + + if(this->isForLeftJoystick) + { + this->cb_reverse_Lx = new wxCheckBox( + this->pan_joystick_config, // Parent + wxID_ANY, // ID + _T("Reverse Lx"), // Label + wxPoint(20, 20) // Position + ); + + this->cb_reverse_Ly = new wxCheckBox( + this->pan_joystick_config, // Parent + wxID_ANY, // ID + _T("Reverse Ly"), // Label + wxPoint(20, 40) // Position + ); + + this->cb_mouse_Ljoy = new wxCheckBox( + this->pan_joystick_config, // Parent + wxID_ANY, // ID + _T("Use mouse for left analog joystick"), // Label + wxPoint(20, 60) // Position + ); + } + else + { + this->cb_reverse_Rx = new wxCheckBox( + this->pan_joystick_config, // Parent + wxID_ANY, // ID + _T("Reverse Rx"), // Label + wxPoint(20, 20) // Position + ); + + this->cb_reverse_Ry = new wxCheckBox( + this->pan_joystick_config, // Parent + wxID_ANY, // ID + _T("Reverse Ry"), // Label + wxPoint(20, 40) // Position + ); + + this->cb_mouse_Rjoy = new wxCheckBox( + this->pan_joystick_config, // Parent + wxID_ANY, // ID + _T("Use mouse for right analog joystick"), // Label + wxPoint(20, 60) // Position + ); + } + + this->bt_ok = new wxButton( + this->pan_joystick_config, // Parent + wxID_ANY, // ID + _T("&OK"), // Label + wxPoint(250, 130), // Position + wxSize(60,25) // Size + ); + + this->bt_cancel = new wxButton( + this->pan_joystick_config, // Parent + wxID_ANY, // ID + _T("&Cancel"), // Label + wxPoint(320, 130), // Position + wxSize(60,25) // Size + ); + + // Connect the buttons to the OnButtonClicked Event + this->Connect( + wxEVT_COMMAND_BUTTON_CLICKED, + wxCommandEventHandler(JoystickConfiguration::OnButtonClicked) + ); + + // Connect the checkboxes to the OnCheckboxClicked Event + this->Connect( + wxEVT_CHECKBOX, + wxCommandEventHandler(JoystickConfiguration::OnCheckboxChange) + ); +} + +/** + Initialize the frame + Check if a gamepad is detected +*/ +void JoystickConfiguration::InitJoystickConfiguration() +{ + this->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() < this->pad_id+1) + { + wxMessageBox("No gamepad detected."); + // disable all checkbox + if(this->isForLeftJoystick) + { + this->cb_reverse_Lx->Disable(); + this->cb_reverse_Ly->Disable(); + } + else + { + this->cb_reverse_Rx->Disable(); + this->cb_reverse_Ry->Disable(); + } + } +} + +/****************************************/ +/*********** Events functions ***********/ +/****************************************/ + +/** + * Button event, called when a button is clicked +*/ +void JoystickConfiguration::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 == this->bt_ok->GetId()) // If the button ID is equals to the Ok button ID + { + this->Close(); // Close the window + } + else if(bt_id == this->bt_cancel->GetId()) // If the button ID is equals to the cancel button ID + { + this->reset(); // reinitialize the value of each parameters + this->Close(); // Close the window + } +} + +/** + * Checkbox event, called when the value of the checkbox change +*/ +void JoystickConfiguration::OnCheckboxChange(wxCommandEvent& event) +{ + wxCheckBox* cb_tmp = (wxCheckBox*) event.GetEventObject(); // get the slider object + int cb_id = cb_tmp->GetId(); + bool val; + if(this->isForLeftJoystick) + { + if(cb_id == this->cb_reverse_Ly->GetId()) + { + val = this->cb_reverse_Ly->GetValue(); + conf->pad_options[this->pad_id].reverse_ly = val; + } + else if(cb_id == this->cb_reverse_Lx->GetId()) + { + val = this->cb_reverse_Lx->GetValue(); + conf->pad_options[this->pad_id].reverse_lx = val; + } + else if(cb_id == this->cb_mouse_Ljoy->GetId()) + { + val = this->cb_mouse_Ljoy->GetValue(); + conf->pad_options[this->pad_id].mouse_l = val; + } + } + else + { + if(cb_id == this->cb_reverse_Ry->GetId()) + { + val = this->cb_reverse_Ry->GetValue(); + conf->pad_options[this->pad_id].reverse_ry = val; + } + else if(cb_id == this->cb_reverse_Rx->GetId()) + { + val = this->cb_reverse_Rx->GetValue(); + conf->pad_options[this->pad_id].reverse_rx = val; + } + else if(cb_id == this->cb_mouse_Rjoy->GetId()) + { + val = this->cb_mouse_Rjoy->GetValue(); + conf->pad_options[this->pad_id].mouse_r = val; + } + } +} + +/****************************************/ +/*********** Methods functions **********/ +/****************************************/ + +// Reset checkbox and slider values +void JoystickConfiguration::reset() +{ + if(this->isForLeftJoystick) + { + this->cb_reverse_Lx->SetValue(this->init_reverse_Lx); + this->cb_reverse_Ly->SetValue(this->init_reverse_Ly); + this->cb_mouse_Ljoy->SetValue(this->init_mouse_Ljoy); + } + else + { + this->cb_reverse_Rx->SetValue(this->init_reverse_Rx); + this->cb_reverse_Ry->SetValue(this->init_reverse_Ry); + this->cb_mouse_Rjoy->SetValue(this->init_mouse_Rjoy); + } +} + +// Set button values +void JoystickConfiguration::repopulate() +{ + bool val; + if(this->isForLeftJoystick) + { + val = conf->pad_options[this->pad_id].reverse_lx; + this->init_reverse_Lx = val; + this->cb_reverse_Lx->SetValue(val); + + val = conf->pad_options[this->pad_id].reverse_ly; + this->init_reverse_Ly = val; + this->cb_reverse_Ly->SetValue(val); + + val = conf->pad_options[this->pad_id].mouse_l; + this->init_mouse_Ljoy = val; + this->cb_mouse_Ljoy->SetValue(val); + } + else + { + val = conf->pad_options[this->pad_id].reverse_rx; + this->init_reverse_Rx = val; + this->cb_reverse_Rx->SetValue(val); + + val = conf->pad_options[this->pad_id].reverse_ry; + this->init_reverse_Ry = val; + this->cb_reverse_Ry->SetValue(val); + + val = conf->pad_options[this->pad_id].mouse_r; + this->init_mouse_Rjoy = val; + this->cb_mouse_Rjoy->SetValue(val); + } +} diff --git a/plugins/onepad/Linux/JoystickConfiguration.h b/plugins/onepad/Linux/JoystickConfiguration.h new file mode 100644 index 0000000000..6ad27ba9ff --- /dev/null +++ b/plugins/onepad/Linux/JoystickConfiguration.h @@ -0,0 +1,59 @@ +/* onepad.h + * 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 + */ + +#pragma once + +#ifndef __JOYSTICKCONFIGURATION_H__ +#define __JOYSTICKCONFIGURATION_H__ + +#include +#include +#include +#include +#include +#include +#include "GamePad.h" +#include "keyboard.h" +#include "onepad.h" + +class JoystickConfiguration : public wxFrame +{ + wxPanel* pan_joystick_config; + wxCheckBox *cb_reverse_Lx, *cb_reverse_Ly, *cb_reverse_Rx, *cb_reverse_Ry, + *cb_mouse_Ljoy, // Use mouse for left joystick + *cb_mouse_Rjoy; // Use mouse for right joystick + wxButton *bt_ok, *bt_cancel; + + int pad_id; + // isForLeftJoystick -> true is for Left Joystick, false is for Right Joystick + bool init_reverse_Lx, init_reverse_Ly, init_reverse_Rx, init_reverse_Ry, + init_mouse_Ljoy, init_mouse_Rjoy, isForLeftJoystick; + + // methods + void repopulate(); + void reset(); + // Events + void OnButtonClicked(wxCommandEvent&); + void OnCheckboxChange(wxCommandEvent&); + +public: + JoystickConfiguration(int, bool, wxWindow*); + void InitJoystickConfiguration(); +}; + +#endif // __JOYSTICKCONFIGURATION_H__ diff --git a/plugins/onepad/Linux/dialog.cpp b/plugins/onepad/Linux/dialog.cpp index 48b2bf4bfb..fc3b93595f 100644 --- a/plugins/onepad/Linux/dialog.cpp +++ b/plugins/onepad/Linux/dialog.cpp @@ -1,8 +1,5 @@ -/* OnePAD - author: arcum42(@gmail.com) - * Copyright (C) 2009 - * - * Based on ZeroPAD, author zerofrog@gmail.com - * Copyright (C) 2006-2007 +/* OnePAD + * 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 @@ -19,287 +16,475 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "GamePad.h" -#include "keyboard.h" -#include "onepad.h" -#include +#include "dialog.h" -void config_key(int pad, int key); -void on_conf_key(GtkButton *button, gpointer user_data); -void on_toggle_option(GtkToggleButton *togglebutton, gpointer user_data); - -static int current_pad = 0; -static GtkComboBoxText *joy_choose_cbox; - -const char* s_pGuiKeyMap[] = +// Construtor of Dialog +Dialog::Dialog() : wxFrame( NULL, // Parent + wxID_ANY, // ID + _T("OnePad configuration"), // Title + wxDefaultPosition, // Position + wxSize(1000, 760), // Width + Lenght + // Style + wxSYSTEM_MENU | + wxCAPTION | + wxCLOSE_BOX | + wxCLIP_CHILDREN + ) { - "L2", "R2", "L1", "R1", - "Triangle", "Circle", "Cross", "Square", - "Select", "L3", "R3", "Start", - "Up", "Right", "Down", "Left", - "L_Up", "L_Right", "L_Down", "L_Left", - "R_Up", "R_Right", "R_Down", "R_Left" -}; -enum -{ - COL_PAD = 0, - COL_BUTTON, - COL_KEY, - COL_PAD_NUM, - COL_VALUE, - COL_KEYSYM, - NUM_COLS -}; - -class keys_tree -{ - private: - GtkTreeStore *treestore; - GtkTreeModel *model; - GtkTreeView *view[2]; - bool has_columns; - int show_pad; - bool show_keyboard_key[2]; - bool show_joy_key[2]; + /* + * Define the size and the position of each button : + * padding[ButtonID][0] : Width + * padding[ButtonID][1] : Height + * padding[ButtonID][2] : x position + * padding[ButtonID][3] : y position + */ + int padding[BUTTONS_LENGHT][4]; - void repopulate() - { - GtkTreeIter toplevel; + // L1 + padding[PAD_L1][0] = 218; // Width + padding[PAD_L1][1] = 28; // Height + padding[PAD_L1][2] = 50; // X + padding[PAD_L1][3] = 174; // Y - gtk_tree_store_clear(treestore); + // L2 + padding[PAD_L2][0] = 218; // Width + padding[PAD_L2][1] = 28; // Height + padding[PAD_L2][2] = 50; // X + padding[PAD_L2][3] = 103; // Y - string pad_value; - switch(show_pad) { - case 0: pad_value = "Pad 1"; break; - case 1: pad_value = "Pad 2"; break; - default: pad_value = "Invalid"; break; - } + // R1 + padding[PAD_R1][0] = 218; // Width + padding[PAD_R1][1] = 28; // Height + padding[PAD_R1][2] = 726; // X + padding[PAD_R1][3] = 174; // Y - // joystick key - if (show_joy_key[show_pad]) { - for (int key = 0; key < MAX_KEYS; key++) - { - if (get_key(show_pad, key) != 0) - { - gtk_tree_store_append(treestore, &toplevel, NULL); - gtk_tree_store_set(treestore, &toplevel, - COL_PAD, pad_value.c_str(), - COL_BUTTON, s_pGuiKeyMap[key], - COL_KEY, KeyName(show_pad, key).c_str(), - COL_PAD_NUM, show_pad, - COL_VALUE, key, - COL_KEYSYM, 0, - -1); - } - } - } + // R2 + padding[PAD_R2][0] = 218; // Width + padding[PAD_R2][1] = 28; // Height + padding[PAD_R2][2] = 726; // X + padding[PAD_R2][3] = 103; // Y - // keyboard/mouse key - if (show_keyboard_key[show_pad]) { - map::iterator it; - for (it = conf->keysym_map[show_pad].begin(); it != conf->keysym_map[show_pad].end(); ++it) { - int keysym = it->first; - int key = it->second; - gtk_tree_store_append(treestore, &toplevel, NULL); - gtk_tree_store_set(treestore, &toplevel, - COL_PAD, pad_value.c_str(), - COL_BUTTON, s_pGuiKeyMap[key], - COL_KEY, KeyName(show_pad, key, keysym).c_str(), - COL_PAD_NUM, show_pad, - COL_VALUE, key, - COL_KEYSYM, keysym, - -1); - } - } - } + // Triangle + padding[PAD_TRIANGLE][0] = 218; // Width + padding[PAD_TRIANGLE][1] = 28; // Height + padding[PAD_TRIANGLE][2] = 726; // X + padding[PAD_TRIANGLE][3] = 244; // Y - void create_a_column(const char *name, int num, bool visible) - { - for (int i = 0; i < 2; i++) { - GtkCellRenderer *renderer; - GtkTreeViewColumn *col; + // Circle + padding[PAD_CIRCLE][0] = 218; // Width + padding[PAD_CIRCLE][1] = 28; // Height + padding[PAD_CIRCLE][2] = 726; // X + padding[PAD_CIRCLE][3] = 317; // Y - col = gtk_tree_view_column_new(); - gtk_tree_view_column_set_title(col, name); + // Cross + padding[PAD_CROSS][0] = 218; // Width + padding[PAD_CROSS][1] = 28; // Height + padding[PAD_CROSS][2] = 726; // X + padding[PAD_CROSS][3] = 389; // Y - /* pack tree view column into tree view */ - gtk_tree_view_append_column(view[i], col); + // Square + padding[PAD_SQUARE][0] = 218; // Width + padding[PAD_SQUARE][1] = 28; // Height + padding[PAD_SQUARE][2] = 726; // X + padding[PAD_SQUARE][3] = 461; // Y - renderer = gtk_cell_renderer_text_new(); + // Directional pad up + padding[PAD_UP][0] = 100; // Width + padding[PAD_UP][1] = 25; // Height + padding[PAD_UP][2] = 108; // X + padding[PAD_UP][3] = 288; // Y - /* pack cell renderer into tree view column */ - gtk_tree_view_column_pack_start(col, renderer, TRUE); + // Directional pad down + padding[PAD_DOWN][0] = 100; // Width + padding[PAD_DOWN][1] = 25; // Height + padding[PAD_DOWN][2] = 108; // X + padding[PAD_DOWN][3] = 338; // Y - /* connect 'text' property of the cell renderer to - * model column that contains the first name */ - gtk_tree_view_column_add_attribute(col, renderer, "text", num); - gtk_tree_view_column_set_visible(col, visible); - } - } + // Directional pad right + padding[PAD_RIGHT][0] = 109; // Width + padding[PAD_RIGHT][1] = 25; // Height + padding[PAD_RIGHT][2] = 159; // X + padding[PAD_RIGHT][3] = 313; // Y - void create_columns() - { - if (!has_columns) - { - create_a_column("Pad #", COL_PAD, true); - create_a_column("Pad Button", COL_BUTTON, true); - create_a_column("Key Value", COL_KEY, true); - create_a_column("Pad Num", COL_PAD_NUM, false); - create_a_column("Internal", COL_VALUE, false); - create_a_column("Keysym", COL_KEYSYM, false); - has_columns = true; - } - } - public: - GtkWidget *view_widget(int i) - { - return GTK_WIDGET(view[i]); - } + // Directional pad left + padding[PAD_LEFT][0] = 109; // Width + padding[PAD_LEFT][1] = 25; // Height + padding[PAD_LEFT][2] = 50; // X + padding[PAD_LEFT][3] = 313; // Y - void init() - { - show_pad = 0; - has_columns = false; - for (int i = 0; i < 2; i++) - show_keyboard_key[i] = show_joy_key[i] = true; + // Left Joystick up + padding[PAD_L_UP][0] = 100; // Width + padding[PAD_L_UP][1] = 25; // Height + padding[PAD_L_UP][2] = 330; // X + padding[PAD_L_UP][3] = 525; // Y - treestore = gtk_tree_store_new(NUM_COLS, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_UINT, - G_TYPE_UINT, - G_TYPE_UINT); + // Left Joystick down + padding[PAD_L_DOWN][0] = 100; // Width + padding[PAD_L_DOWN][1] = 25; // Height + padding[PAD_L_DOWN][2] = 330; // X + padding[PAD_L_DOWN][3] = 575; // Y - model = GTK_TREE_MODEL(treestore); + // Left Joystick right + padding[PAD_L_RIGHT][0] = 109; // Width + padding[PAD_L_RIGHT][1] = 25; // Height + padding[PAD_L_RIGHT][2] = 382; // X + padding[PAD_L_RIGHT][3] = 550; // Y - for (int i = 0; i < 2; i++) { - view[i] = GTK_TREE_VIEW(gtk_tree_view_new()); - gtk_tree_view_set_model(view[i], model); - gtk_tree_selection_set_mode(gtk_tree_view_get_selection(view[i]), GTK_SELECTION_SINGLE); - } - g_object_unref(model); /* destroy model automatically with view */ - } + // Left Joystick left + padding[PAD_L_LEFT][0] = 109; // Width + padding[PAD_L_LEFT][1] = 25; // Height + padding[PAD_L_LEFT][2] = 273; // X + padding[PAD_L_LEFT][3] = 550; // Y - void set_show_pad(int pad) { show_pad = pad; } + // L3 + padding[PAD_L3][0] = 218; // Width + padding[PAD_L3][1] = 28; // Height + padding[PAD_L3][2] = 273; // X + padding[PAD_L3][3] = 642; // Y - void set_show_joy(bool flag) { show_joy_key[show_pad] = flag; } + // Right Joystick up + padding[PAD_R_UP][0] = 100; // Width + padding[PAD_R_UP][1] = 25; // Height + padding[PAD_R_UP][2] = 560; // X + padding[PAD_R_UP][3] = 525; // Y - void set_show_key(bool flag) { show_keyboard_key[show_pad] = flag; } + // Right Joystick down + padding[PAD_R_DOWN][0] = 100; // Width + padding[PAD_R_DOWN][1] = 25; // Height + padding[PAD_R_DOWN][2] = 560; // X + padding[PAD_R_DOWN][3] = 575; // Y - void update() - { - create_columns(); - repopulate(); - } + // Right Joystick right + padding[PAD_R_RIGHT][0] = 109; // Width + padding[PAD_R_RIGHT][1] = 25; // Height + padding[PAD_R_RIGHT][2] = 612; // X + padding[PAD_R_RIGHT][3] = 550; // Y - void clear_all() - { - clearPAD(show_pad); - update(); - } + // Right Joystick left + padding[PAD_R_LEFT][0] = 109; // Width + padding[PAD_R_LEFT][1] = 25; // Height + padding[PAD_R_LEFT][2] = 503; // X + padding[PAD_R_LEFT][3] = 550; // Y - bool get_selected(int &pad, int &key, int &keysym) - { - GtkTreeSelection *selection; - GtkTreeIter iter; + // R3 + padding[PAD_R3][0] = 218; // Width + padding[PAD_R3][1] = 28; // Height + padding[PAD_R3][2] = 503; // X + padding[PAD_R3][3] = 642; // Y - selection = gtk_tree_view_get_selection(view[show_pad&1]); - if (gtk_tree_selection_get_selected(selection, &model, &iter)) - { - gtk_tree_model_get(model, &iter, COL_PAD_NUM, &pad, COL_VALUE, &key, COL_KEYSYM, &keysym,-1); - return true; - } - return false; - } + // Start + padding[PAD_START][0] = 218; // Width + padding[PAD_START][1] = 28; // Height + padding[PAD_START][2] = 503; // X + padding[PAD_START][3] = 32; // Y - void remove_selected() - { - int key, pad, keysym; - if (get_selected(pad, key, keysym)) - { - if (keysym) - conf->keysym_map[pad].erase(keysym); - else - set_key(pad, key, 0); - update(); - } - } + // Select + padding[PAD_SELECT][0] = 218; // Width + padding[PAD_SELECT][1] = 28; // Height + padding[PAD_SELECT][2] = 273; // X + padding[PAD_SELECT][3] = 32; // Y - void modify_selected() - { - int key, pad, keysym; - if (get_selected(pad, key, keysym)) - { - remove_selected(); - config_key(pad,key); - update(); - } - } -}; -keys_tree *key_tree_manager; + // Analog + padding[Analog][0] = 218; // Width + padding[Analog][1] = 28; // Height + padding[Analog][2] = 50; // X + padding[Analog][3] = 450; // Y -void populate_new_joysticks(GtkComboBoxText *box) -{ - char str[255]; - GamePad::EnumerateGamePads(s_vgamePad); + // Left Joystick Configuration + padding[JoyL_config][0] = 180; // Width + padding[JoyL_config][1] = 28; // Height + padding[JoyL_config][2] = 50; // X + padding[JoyL_config][3] = 550; // Y - gtk_combo_box_text_append_text(box, "Keyboard/mouse only"); - - vector::iterator it = s_vgamePad.begin(); + // Right Joystick Configuration + padding[JoyR_config][0] = 180; // Width + padding[JoyR_config][1] = 28; // Height + padding[JoyR_config][2] = 764; // X + padding[JoyR_config][3] = 550; // Y - // Get everything in the vector vjoysticks. - while (it != s_vgamePad.end()) - { - sprintf(str, "Keyboard/mouse and %s - but: %d, axes: %d, hats: %d", (*it)->GetName().c_str(), - (*it)->GetNumButtons(), (*it)->GetNumAxes(), (*it)->GetNumHats()); - gtk_combo_box_text_append_text(box, str); - it++; - } + // Gamepad Configuration + padding[Gamepad_config][0] = 180; // Width + padding[Gamepad_config][1] = 28; // Height + padding[Gamepad_config][2] = 50; // X + padding[Gamepad_config][3] = 585; // Y + + // Apply modifications without exit + padding[Apply][0] = 70; // Width + padding[Apply][1] = 28; // Height + padding[Apply][2] = 833; // X + padding[Apply][3] = 642; // Y + + // Ok button + padding[Ok][0] = 70; // Width + padding[Ok][1] = 28; // Height + padding[Ok][2] = 913; // X + padding[Ok][3] = 642; // Y + + // Cancel button + padding[Cancel][0] = 70; // Width + padding[Cancel][1] = 28; // Height + padding[Cancel][2] = 753; // X + padding[Cancel][3] = 642; // Y + + // create a new Notebook + this->tab_gamepad = new wxNotebook(this, wxID_ANY); + for(int i=0; ipan_tabs[i] = new opPanel( + this->tab_gamepad, + wxID_ANY, + wxDefaultPosition, + wxSize(1000, 760) + ); + // Add new page + // Define label + std::stringstream sstm; + std::string label = "Gamepad "; + sstm << label << i; + // New page creation + this->tab_gamepad->AddPage( + this->pan_tabs[i], // Parent + sstm.str(), // Title + 0, // select (if 1 the tab is selected, 0 otherwise) + wxEXPAND // Specifies the optional image index for the new page. + ); + + for(int j=0; jbt_gamepad[i][j] = new wxButton( + this->pan_tabs[i], // Parent + wxID_HIGHEST+j+1, // ID + _T("Undefined"), // Label + wxPoint(padding[j][2], padding[j][3]), // Position + wxSize(padding[j][0], padding[j][1]) // Size + ); + } + // Redefine others gui buttons label + this->bt_gamepad[i][JoyL_config]->SetLabel(_T("&Left Joystick Config")); + this->bt_gamepad[i][JoyR_config]->SetLabel(_T("&Right Joystick Config")); + this->bt_gamepad[i][Gamepad_config]->SetLabel(_T("&Gamepad Configuration")); + this->bt_gamepad[i][Cancel]->SetLabel(_T("&Cancel")); + this->bt_gamepad[i][Apply]->SetLabel(_T("&Apply")); + this->bt_gamepad[i][Ok]->SetLabel(_T("&Ok")); + + // Disable analog button (not yet supported) + this->bt_gamepad[i][Analog]->Disable(); + } + + // Connect the buttons to the OnButtonClicked Event + this->Connect( + wxEVT_COMMAND_BUTTON_CLICKED, + wxCommandEventHandler(Dialog::OnButtonClicked) + ); + + time_update_gui.SetOwner(this); + this->Connect( + wxEVT_TIMER, + wxCommandEventHandler(Dialog::JoystickEvent) + ); + time_update_gui.Start(UPDATE_TIME, wxTIMER_CONTINUOUS); + + for(int i=0; ipressed[i][j] = false; + } + } } -void set_current_joy() +void Dialog::InitDialog() { - u32 joyid = conf->get_joyid(current_pad); - if (GamePadIdWithinBounds(joyid)) - // 0 is special case for no gamepad. So you must increase of 1. - gtk_combo_box_set_active(GTK_COMBO_BOX(joy_choose_cbox), joyid+1); - else - gtk_combo_box_set_active(GTK_COMBO_BOX(joy_choose_cbox), 0); + GamePad::EnumerateGamePads(s_vgamePad); // activate gamepads + LoadConfig(); // Load configuration from the ini file + this->repopulate(); // Set label and fit simulated key array } -typedef struct +/****************************************/ +/*********** Events functions ***********/ +/****************************************/ + +void Dialog::OnButtonClicked(wxCommandEvent &event) { - GtkWidget *widget; - int index; - void put(const char* lbl, int i, GtkFixed *fix, int x, int y) - { - widget = gtk_button_new_with_label(lbl); - index = i; + // 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()-wxID_HIGHEST-1; // get the real ID + int gamepad_id = this->tab_gamepad->GetSelection(); // get the tab ID (equivalent to the gamepad id) + if(bt_id >= 0 && bt_id <= PAD_R_LEFT) // if the button ID is a gamepad button + { + bt_tmp->Disable(); // switch the button state to "Disable" + this->config_key(gamepad_id, bt_id); + bt_tmp->Enable(); // switch the button state to "Enable" + } + else if(bt_id == Gamepad_config) // If the button ID is equals to the Gamepad_config button ID + { + this->frm_gamepad_config = new GamepadConfiguration(gamepad_id, this); + this->frm_gamepad_config->InitGamepadConfiguration(); + this->frm_gamepad_config->Show(true); + } + else if(bt_id == JoyL_config) // If the button ID is equals to the JoyL_config button ID + { + this->frm_joystick_config = new JoystickConfiguration(gamepad_id, true, this); + this->frm_joystick_config->InitJoystickConfiguration(); + this->frm_joystick_config->Show(true); + } + else if(bt_id == JoyR_config) // If the button ID is equals to the JoyR_config button ID + { + this->frm_joystick_config = new JoystickConfiguration(gamepad_id, false, this); + this->frm_joystick_config->InitJoystickConfiguration(); + this->frm_joystick_config->Show(true); + } + else if(bt_id == Ok) // If the button ID is equals to the Ok button ID + { + SaveConfig(); // Save the configuration + Close(); // Close the window + } + else if(bt_id == Apply) // If the button ID is equals to the Apply button ID + { + SaveConfig(); // Save the configuration + } + else if(bt_id == Cancel) // If the button ID is equals to the cancel button ID + { + Close(); // Close the window + } +} - gtk_fixed_put(fix, widget, x, y); - gtk_widget_set_size_request(widget, 64, 24); - g_signal_connect(widget, "clicked", G_CALLBACK(on_conf_key), this); - } -} dialog_buttons; - -typedef struct +void Dialog::JoystickEvent(wxCommandEvent& event) { - GtkWidget *widget; - unsigned int mask; - void create(GtkWidget* area, const char* label, u32 x, u32 y, u32 mask_value) - { - widget = gtk_check_button_new_with_label(label); - mask = mask_value; +#ifdef SDL_BUILD + u32 key; + int map; + std::map::iterator it; + std::map::iterator it2; + SDL_JoystickEventState(SDL_ENABLE); + SDL_Event events; + while(SDL_PollEvent(&events)) + { + switch(events.type) + { + case SDL_KEYDOWN: + case SDL_KEYUP: + fprintf(stderr, "%d\n", events.key.keysym); + break; + case SDL_JOYAXISMOTION: + key = axis_to_key(false, (events.jaxis.value<0), events.jaxis.axis); + it=this->map_images[events.jaxis.which].find(key); + if(it != this->map_images[events.jaxis.which].end()) + { + map = this->map_images[events.jaxis.which][key]; + if(events.jaxis.value == 0) + { + if(map >= PAD_L_UP && map <= PAD_L_LEFT) + this->pan_tabs[events.jaxis.which]->HideImg(img_left_cursor); + else if(map >= PAD_R_UP && map <= PAD_R_LEFT) + this->pan_tabs[events.jaxis.which]->HideImg(img_right_cursor); + } + else + { + if(map >= PAD_L_UP && map <= PAD_L_LEFT) + { + this->pan_tabs[events.jaxis.which]->MoveJoystick(events.jaxis.axis, events.jaxis.value); + this->pan_tabs[events.jaxis.which]->ShowImg(img_left_cursor); + } + else if(map >= PAD_R_UP && map <= PAD_R_LEFT) + { + this->pan_tabs[events.jaxis.which]->MoveJoystick(events.jaxis.axis, events.jaxis.value); + this->pan_tabs[events.jaxis.which]->ShowImg(img_right_cursor); + } + else if(map < PAD_L_UP) // if this is not a joystick + { + this->pan_tabs[events.jaxis.which]->ShowImg(map); + } + } + break; + } + // Hack Dualshock 4 (L2, R2) + key = axis_to_key(false, (events.jaxis.value>0), events.jaxis.axis); + it2=this->map_images[events.jaxis.which].find(key); + if(it2 != this->map_images[events.jaxis.which].end()) + { + map = this->map_images[events.jaxis.which][key]; + if(map < PAD_L_UP) // if this is not a joystick + { + this->pan_tabs[events.jaxis.which]->HideImg(map); + } + break; + } + break; + case SDL_JOYBUTTONDOWN: + key = button_to_key(events.jbutton.button); + it=this->map_images[events.jaxis.which].find(key); + if(it != this->map_images[events.jaxis.which].end()) + { + map = this->map_images[events.jaxis.which][key]; + this->pan_tabs[events.jaxis.which]->ShowImg(map); + } + break; + case SDL_JOYBUTTONUP: + key = button_to_key(events.jbutton.button); + it=this->map_images[events.jaxis.which].find(key); + if(it != this->map_images[events.jaxis.which].end()) + { + map = this->map_images[events.jaxis.which][key]; + this->pan_tabs[events.jaxis.which]->HideImg(map); + } + case SDL_JOYHATMOTION: + switch(events.jhat.value) + { + case SDL_HAT_UP: + key = hat_to_key(events.jhat.value, events.jhat.hat); + it=this->map_images[events.jaxis.which].find(key); + if(it != this->map_images[events.jaxis.which].end()) + { + this->pan_tabs[events.jaxis.which]->ShowImg(img_dp_up); + } + break; + case SDL_HAT_DOWN: + key = hat_to_key(events.jhat.value, events.jhat.hat); + it=this->map_images[events.jaxis.which].find(key); + if(it != this->map_images[events.jaxis.which].end()) + { + this->pan_tabs[events.jaxis.which]->ShowImg(img_dp_bottom); + } + break; + case SDL_HAT_RIGHT: + key = hat_to_key(events.jhat.value, events.jhat.hat); + it=this->map_images[events.jaxis.which].find(key); + if(it != this->map_images[events.jaxis.which].end()) + { + this->pan_tabs[events.jaxis.which]->ShowImg(img_dp_right); + } + break; + case SDL_HAT_LEFT: + key = hat_to_key(events.jhat.value, events.jhat.hat); + it=this->map_images[events.jaxis.which].find(key); + if(it != this->map_images[events.jaxis.which].end()) + { + this->pan_tabs[events.jaxis.which]->ShowImg(img_dp_left); + } + break; + case SDL_HAT_CENTERED: + this->pan_tabs[events.jaxis.which]->HideImg(img_dp_up); + this->pan_tabs[events.jaxis.which]->HideImg(img_dp_bottom); + this->pan_tabs[events.jaxis.which]->HideImg(img_dp_right); + this->pan_tabs[events.jaxis.which]->HideImg(img_dp_left); + } + break; + default: + break; + } + } +#endif // SDL_BUILD +} - gtk_fixed_put(GTK_FIXED(area), widget, x, y); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), mask & conf->packed_options); - g_signal_connect(widget, "toggled", G_CALLBACK(on_toggle_option), this); - } -} dialog_checkbox; +/****************************************/ +/*********** Methods functions **********/ +/****************************************/ -void config_key(int pad, int key) +void Dialog::config_key(int pad, int key) { bool captured = false; u32 key_pressed = 0; @@ -309,333 +494,121 @@ void config_key(int pad, int key) while (!captured) { vector::iterator itjoy; - if (PollX11KeyboardMouseEvent(key_pressed)) { // special case for keyboard/mouse to handle multiple keys // Note: key_pressed == 0 when ESC is hit to abort the capture if (key_pressed > 0) + { + this->clear_key(pad, key); set_keyboad_key(pad, key_pressed, key); - + this->simulatedKeys[pad][key] = key_pressed; + this->map_images[pad][key_pressed] = key; + } captured = true; - break; } + else + { + GamePad::UpdateGamePadState(); - GamePad::UpdateGamePadState(); + itjoy = s_vgamePad.begin(); + while ((itjoy != s_vgamePad.end()) && (!captured)) + { + if ((*itjoy)->PollButtons(key_pressed)) + { + this->clear_key(pad, key); + set_key(pad, key, key_pressed); + this->map_images[pad][key_pressed] = key; + captured = true; + } + else if((*itjoy)->PollAxes(key_pressed)) + { - itjoy = s_vgamePad.begin(); - while ((itjoy != s_vgamePad.end()) && (!captured)) - { - if ((*itjoy)->PollButtons(key_pressed)) { - set_key(pad, key, key_pressed); - captured = true; - break; - } - - if ((*itjoy)->PollAxes(key_pressed)) { - set_key(pad, key, key_pressed); - captured = true; - break; - } - - if ((*itjoy)->PollHats(key_pressed)) { - set_key(pad, key, key_pressed); - captured = true; - break; - } - itjoy++; - } + this->clear_key(pad, key); + set_key(pad, key, key_pressed); + this->map_images[pad][key_pressed] = key; + captured = true; + } + else if((*itjoy)->PollHats(key_pressed)) + { + this->clear_key(pad, key); + set_key(pad, key, key_pressed); + this->map_images[pad][key_pressed] = key; + captured = true; + } + itjoy++; + } + } } - - PAD_LOG("%s\n", KeyName(pad, key).c_str()); + this->bt_gamepad[pad][key]->SetLabel( + KeyName(pad, key, this->simulatedKeys[pad][key]).c_str() + ); } -void on_conf_key(GtkButton *button, gpointer user_data) +void Dialog::clear_key(int pad, int key) { - dialog_buttons *btn = (dialog_buttons *)user_data; - int key = btn->index; + // Erase the keyboard binded key + u32 keysim = this->simulatedKeys[pad][key]; + this->simulatedKeys[pad][key] = 0; - if (key == -1) return; - - config_key(current_pad, key); - key_tree_manager->update(); + // erase gamepad entry (keysim map) + std::map::iterator it1; + it1=conf->keysym_map[pad].find(keysim); + if(it1 != conf->keysym_map[pad].end()) + conf->keysym_map[pad].erase(it1); + + // erase gamepad entry (image map) + int val = get_key(pad, key); + std::map::iterator it2; + it2=this->map_images[pad].find(val); + if(it2 != this->map_images[pad].end()) + { + this->map_images[pad].erase(it2); + } + + // Erase the keyboard image map + //this->map_images[pad].erase(keysim); + // Erase the Gamepad binded key + set_key(pad, key, 0); } -void on_remove_clicked(GtkButton *button, gpointer user_data) + +// Set button values +void Dialog::repopulate() { - key_tree_manager->remove_selected(); -} - -void on_clear_clicked(GtkButton *button, gpointer user_data) -{ - key_tree_manager->clear_all(); -} - -void on_modify_clicked(GtkButton *button, gpointer user_data) -{ - key_tree_manager->modify_selected(); -} - -void on_view_joy_clicked(GtkToggleButton *togglebutton, gpointer user_data) -{ - key_tree_manager->set_show_joy(gtk_toggle_button_get_active(togglebutton)); - key_tree_manager->update(); -} - -void on_view_key_clicked(GtkToggleButton *togglebutton, gpointer user_data) -{ - key_tree_manager->set_show_key(gtk_toggle_button_get_active(togglebutton)); - key_tree_manager->update(); -} - -void on_toggle_option(GtkToggleButton *togglebutton, gpointer user_data) -{ - dialog_checkbox *checkbox = (dialog_checkbox*)user_data; - - if (gtk_toggle_button_get_active(togglebutton)) - { - conf->packed_options |= checkbox->mask; - if(checkbox->mask == PADOPTION_FORCEFEEDBACK && (conf->get_joyid(current_pad)< s_vgamePad.size())) - s_vgamePad[conf->get_joyid(current_pad)]->TestForce(); - } - else - conf->packed_options &= ~checkbox->mask; -} - -void joy_changed(GtkComboBoxText *box, gpointer user_data) -{ - int joyid = gtk_combo_box_get_active(GTK_COMBO_BOX(box)); - // Note position 0 of the combo box is no gamepad - joyid--; - - // FIXME: might be a good idea to ask the user first ;) - // FIXME: do you need to clean the previous key association. or what the user want - // 1 : keep previous joy - // 2 : use new joy with old key binding - // 3 : use new joy with fresh key binding - - // unassign every joystick with this pad - for (u32 i = 0; i < 2; ++i) - if (joyid == (int)conf->get_joyid(i)) conf->set_joyid(i, -1); - - conf->set_joyid(current_pad, joyid); -} - -void pad_changed(GtkNotebook *notebook, void *notebook_page, int page, void *data) -{ - current_pad = page; - key_tree_manager->set_show_pad(current_pad&1); - key_tree_manager->update(); - - // update joy - set_current_joy(); -} - -struct button_positions -{ - const char* label; - u32 x,y; -}; - -// Warning position is important and must match the order of the gamePadValues structure -button_positions b_pos[MAX_KEYS] = -{ - { "L2", 64, 8}, - { "R2", 392, 8}, - { "L1", 64, 32}, - { "R1", 392, 32}, - - { "Triangle", 392, 80}, - { "Circle", 456, 104}, - { "Cross", 392, 128}, - { "Square", 328, 104}, - - { "Select", 200, 48}, - { "L3", 64, 224}, - { "R3", 392, 224}, - { "Start", 272, 48}, - - // Arrow pad - { "Up", 64, 80}, - { "Right", 128, 104}, - { "Down", 64, 128}, - { "Left", 0, 104}, - - // Left Analog joystick - { "Up", 64, 200}, - { "Right", 128, 224}, - { "Down", 64, 248}, - { "Left", 0, 224}, - - // Right Analog joystick - { "Up", 392, 200}, - { "Right", 456, 224}, - { "Down", 392, 248}, - { "Left", 328, 224} -}; - -// Warning position is important and must match the order of the PadOptions structure -#define CHECK_NBR 9 -button_positions check_pos[CHECK_NBR] = -{ - { "Enable force feedback", 40, 400}, - { "Reverse Lx", 40, 304}, - { "Reverse Ly", 40, 328}, - { "Reverse Rx", 368, 304}, - { "Reverse Ry", 368, 328}, - { "Use mouse for left analog joy", 40, 352}, - { "Use mouse for right analog joy", 368, 352}, - { "Hack: Sixaxis/DS3 plugged in USB", 368, 400}, - { "Hack: Sixaxis/DS3 pressure", 368, 424} -}; - -GtkWidget *create_notebook_page_dialog(int page, dialog_buttons btn[MAX_KEYS], dialog_checkbox checkbox[CHECK_NBR]) -{ - GtkWidget *main_box; - GtkWidget *joy_choose_frame, *joy_choose_box; - - GtkWidget *keys_frame, *keys_box; - - GtkWidget *keys_tree_box, *keys_tree_scroll; - GtkWidget *keys_tree_clear_btn, *keys_tree_remove_btn, *keys_tree_modify_btn, *keys_tree_show_key_btn, *keys_tree_show_joy_btn; - GtkWidget *keys_btn_box, *keys_filter_box; - - GtkWidget *keys_static_frame, *keys_static_box; - GtkWidget *keys_static_area; - - joy_choose_cbox = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new()); - populate_new_joysticks(joy_choose_cbox); - set_current_joy(); - g_signal_connect(joy_choose_cbox, "changed", G_CALLBACK(joy_changed), NULL); - - keys_tree_scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(keys_tree_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER(keys_tree_scroll), key_tree_manager->view_widget(page)); - gtk_widget_set_size_request(keys_tree_scroll, 300, 500); - - keys_tree_clear_btn = gtk_button_new_with_label("Clear All"); - g_signal_connect(keys_tree_clear_btn, "clicked", G_CALLBACK(on_clear_clicked), NULL); - gtk_widget_set_size_request(keys_tree_clear_btn, 70, 24); - - keys_tree_remove_btn = gtk_button_new_with_label("Remove"); - g_signal_connect(keys_tree_remove_btn, "clicked", G_CALLBACK(on_remove_clicked), NULL); - gtk_widget_set_size_request(keys_tree_remove_btn, 70, 24); - - keys_tree_modify_btn = gtk_button_new_with_label("Modify"); - g_signal_connect(keys_tree_modify_btn, "clicked", G_CALLBACK(on_modify_clicked), NULL); - gtk_widget_set_size_request(keys_tree_modify_btn, 70, 24); - - keys_tree_show_joy_btn = gtk_check_button_new_with_label("Show joy"); - g_signal_connect(keys_tree_show_joy_btn, "toggled", G_CALLBACK(on_view_joy_clicked), NULL); - gtk_widget_set_size_request(keys_tree_show_joy_btn, 100, 24); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(keys_tree_show_joy_btn), true); - - keys_tree_show_key_btn = gtk_check_button_new_with_label("Show key"); - g_signal_connect(keys_tree_show_key_btn, "toggled", G_CALLBACK(on_view_key_clicked), NULL); - gtk_widget_set_size_request(keys_tree_show_key_btn, 100, 24); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(keys_tree_show_key_btn), true); - - joy_choose_box = gtk_hbox_new(false, 5); - joy_choose_frame = gtk_frame_new ("Joystick to use for this pad"); - gtk_container_add (GTK_CONTAINER(joy_choose_frame), joy_choose_box); - - keys_btn_box = gtk_hbox_new(false, 5); - keys_filter_box = gtk_hbox_new(false, 5); - keys_tree_box = gtk_vbox_new(false, 5); - - keys_static_box = gtk_hbox_new(false, 5); - keys_static_frame = gtk_frame_new (""); - gtk_container_add (GTK_CONTAINER(keys_static_frame), keys_static_box); - - keys_static_area = gtk_fixed_new(); - - for(int i = 0; i < MAX_KEYS; i++) - { - btn[i].put(b_pos[i].label, i, GTK_FIXED(keys_static_area), b_pos[i].x, b_pos[i].y); - } - - u32 mask = 1 << (16*page); - for(int i = 0; i < CHECK_NBR; i++) { - checkbox[i].create(keys_static_area, check_pos[i].label, check_pos[i].x, check_pos[i].y, mask); - mask = mask << 1; - } - - keys_box = gtk_hbox_new(false, 5); - keys_frame = gtk_frame_new ("Key Settings"); - gtk_container_add (GTK_CONTAINER(keys_frame), keys_box); - - gtk_box_pack_start (GTK_BOX (keys_tree_box), keys_tree_scroll, true, true, 0); - gtk_box_pack_start (GTK_BOX (keys_tree_box), keys_btn_box, false, false, 0); - gtk_box_pack_start (GTK_BOX (keys_tree_box), keys_filter_box, false, false, 0); - - gtk_box_pack_start (GTK_BOX (keys_filter_box), keys_tree_show_joy_btn, false, false, 0); - gtk_box_pack_start (GTK_BOX (keys_filter_box), keys_tree_show_key_btn, false, false, 0); - - gtk_box_pack_start (GTK_BOX (keys_btn_box), keys_tree_clear_btn, false, false, 0); - gtk_box_pack_start (GTK_BOX (keys_btn_box), keys_tree_remove_btn, false, false, 0); - gtk_box_pack_start (GTK_BOX (keys_btn_box), keys_tree_modify_btn, false, false, 0); - - gtk_container_add(GTK_CONTAINER(joy_choose_box), GTK_WIDGET(joy_choose_cbox)); - gtk_box_pack_start(GTK_BOX (keys_box), keys_tree_box, false, false, 0); - gtk_container_add(GTK_CONTAINER(keys_box), keys_static_area); - - main_box = gtk_vbox_new(false, 5); - gtk_container_add(GTK_CONTAINER(main_box), joy_choose_frame); - gtk_container_add(GTK_CONTAINER(main_box), keys_frame); - - return main_box; + for(int gamepad_id=0; gamepad_idbt_gamepad[gamepad_id][key]->SetLabel( + KeyName(gamepad_id, key).c_str() + ); + this->map_images[gamepad_id][get_key(gamepad_id, key)] = key; + } + } + + // keyboard/mouse key + map::iterator it; + for (it = conf->keysym_map[gamepad_id].begin(); + it != conf->keysym_map[gamepad_id].end(); ++it) + { + int keysym = it->first; + int key = it->second; + this->bt_gamepad[gamepad_id][key]->SetLabel( + KeyName(gamepad_id, key, keysym).c_str() + ); + this->simulatedKeys[gamepad_id][key] = keysym; + this->map_images[gamepad_id][keysym] = key; + } + } } +// Main void DisplayDialog() { - int return_value; - - GtkWidget *dialog; - - GtkWidget *notebook, *page[2]; - GtkWidget *page_label[2]; - - dialog_buttons btn[2][MAX_KEYS]; - dialog_checkbox checkbox[2][CHECK_NBR]; - - LoadConfig(); - key_tree_manager = new keys_tree; - key_tree_manager->init(); - - /* Create the widgets */ - dialog = gtk_dialog_new_with_buttons ( - "OnePAD Config", - NULL, /* parent window*/ - (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), - "_OK", GTK_RESPONSE_ACCEPT, - "_Apply", GTK_RESPONSE_APPLY, - "_Cancel", GTK_RESPONSE_REJECT, - NULL); - - notebook = gtk_notebook_new(); - - page_label[0] = gtk_label_new("Pad 1"); - page_label[1] = gtk_label_new("Pad 2"); - for (int i = 0; i < 2; i++) { - page[i] = create_notebook_page_dialog(i, btn[i], checkbox[i]); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page[i], page_label[i]); - } - g_signal_connect(notebook, "switch-page", G_CALLBACK(pad_changed), NULL); - - gtk_container_add (GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), notebook); - - key_tree_manager->update(); - - gtk_widget_show_all (dialog); - - do { - return_value = gtk_dialog_run (GTK_DIALOG (dialog)); - if (return_value == GTK_RESPONSE_APPLY || return_value == GTK_RESPONSE_ACCEPT) { - SaveConfig(); - } - } while (return_value == GTK_RESPONSE_APPLY); - - LoadConfig(); - delete key_tree_manager; - gtk_widget_destroy (dialog); + Dialog* dialog = new Dialog(); + dialog->InitDialog(); + dialog->Show(true); } diff --git a/plugins/onepad/Linux/dialog.h b/plugins/onepad/Linux/dialog.h new file mode 100644 index 0000000000..ad923a9260 --- /dev/null +++ b/plugins/onepad/Linux/dialog.h @@ -0,0 +1,102 @@ +/* onepad.h + * 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 + */ + +#pragma once + +#ifndef __DIALOG_H__ +#define __DIALOG_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "GamePad.h" +#include "keyboard.h" +#include "onepad.h" +#include "opPanel.h" + +#include "GamepadConfiguration.h" +#include "JoystickConfiguration.h" +#include + +// Allow to found quickly button id +// e.g L2 → 0, triangle → 4, ... +// see onepad.h for more details about gamepad button id + +enum gui_buttons { + Analog = PAD_R_LEFT+1, // Analog button (not yet supported ?) + JoyL_config, // Left Joystick Configuration + JoyR_config, // Right Joystick Configuration + Gamepad_config, // Gamepad Configuration + Apply, // Apply modifications without exit + Ok, // Apply modifications and exit + Cancel // Exit without apply modificatons +}; + +#define BUTTONS_LENGHT 31 // numbers of buttons on the gamepad +#define GAMEPAD_NUMBER 2 // numbers of gamepad +#define UPDATE_TIME 5 + +class Dialog : public wxFrame +{ + // Panels + opPanel* pan_tabs[GAMEPAD_NUMBER]; // Gamepad Tabs box + // Notebooks + wxNotebook* tab_gamepad; // Joysticks Tabs + // Buttons + wxButton* bt_gamepad[GAMEPAD_NUMBER][BUTTONS_LENGHT]; // Joystick button use to modify the button mapping + // Contain all simulated key + u32 simulatedKeys[GAMEPAD_NUMBER][MAX_KEYS]; + // Timer + wxTimer time_update_gui; + // Check if the gui must display feddback image + bool pressed[GAMEPAD_NUMBER][NB_IMG]; + // Map the key pressed with the feedback image id + std::map map_images[GAMEPAD_NUMBER]; + + // Frame + GamepadConfiguration* frm_gamepad_config; // Gamepad Configuration frame + JoystickConfiguration* frm_joystick_config; // Joystick Configuration frame + + // methods + void config_key(int, int); + void clear_key(int, int); + void repopulate(); + + // Events + void OnButtonClicked(wxCommandEvent&); + void JoystickEvent(wxCommandEvent&); + +public: + Dialog(); + void InitDialog(); + void show(); +}; + +extern void DisplayDialog(); // Main function + +#endif // __DIALOG_H__ diff --git a/plugins/onepad/Linux/ini.cpp b/plugins/onepad/Linux/ini.cpp index c494b80c08..98a45da8d0 100644 --- a/plugins/onepad/Linux/ini.cpp +++ b/plugins/onepad/Linux/ini.cpp @@ -20,7 +20,6 @@ */ #include -#include #include "GamePad.h" #include "keyboard.h" diff --git a/plugins/onepad/Linux/opPanel.cpp b/plugins/onepad/Linux/opPanel.cpp new file mode 100644 index 0000000000..af97e3bf41 --- /dev/null +++ b/plugins/onepad/Linux/opPanel.cpp @@ -0,0 +1,204 @@ +/* opPanel.cpp + * 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 "opPanel.h" +#include "ImgHeader/dualshock2.h" +#include "ImgHeader/cross.h" +#include "ImgHeader/circle.h" +#include "ImgHeader/square.h" +#include "ImgHeader/triangle.h" +#include "ImgHeader/dp_left.h" +#include "ImgHeader/dp_right.h" +#include "ImgHeader/dp_up.h" +#include "ImgHeader/dp_bottom.h" +#include "ImgHeader/l1.h" +#include "ImgHeader/r1.h" +#include "ImgHeader/l2.h" +#include "ImgHeader/l3.h" +#include "ImgHeader/r2.h" +#include "ImgHeader/r3.h" +#include "ImgHeader/start.h" +#include "ImgHeader/select.h" +#include "ImgHeader/analog.h" +#include "ImgHeader/joystick_cursor.h" + +opPanel::opPanel(wxWindow *parent, + wxWindowID id=wxID_ANY, + const wxPoint &pos=wxDefaultPosition, + const wxSize &size=wxDefaultSize + ): wxPanel( parent, id, pos, size) +{ + this->picture[img_background] = EmbeddedImage().GetIcon(); + + this->picture[img_start] = EmbeddedImage().GetIcon(); + this->picture[img_select] = EmbeddedImage().GetIcon(); + this->picture[img_analog] = EmbeddedImage().GetIcon(); + + this->picture[img_dp_left] = EmbeddedImage().GetIcon(); + this->picture[img_dp_right] = EmbeddedImage().GetIcon(); + this->picture[img_dp_up] = EmbeddedImage().GetIcon(); + this->picture[img_dp_bottom] = EmbeddedImage().GetIcon(); + + this->picture[img_square] = EmbeddedImage().GetIcon(); + this->picture[img_circle] = EmbeddedImage().GetIcon(); + this->picture[img_cross] = EmbeddedImage().GetIcon(); + this->picture[img_triangle] = EmbeddedImage().GetIcon(); + + this->picture[img_l1] = EmbeddedImage().GetIcon(); + this->picture[img_l3] = EmbeddedImage().GetIcon(); + this->picture[img_l2] = EmbeddedImage().GetIcon(); + + this->picture[img_r1] = EmbeddedImage().GetIcon(); + this->picture[img_r3] = EmbeddedImage().GetIcon(); + this->picture[img_r2] = EmbeddedImage().GetIcon(); + + this->picture[img_left_cursor] = EmbeddedImage().GetIcon(); + this->picture[img_right_cursor] = EmbeddedImage().GetIcon(); + + for(int i=0; ishow_image[i] = false; + this->SaveSize(i); + this->HideImg(i); + } + this->ShowImg(img_background); + this->show_image[img_background] = true; + + this->left_cursor_x = 0; + this->left_cursor_y = 0; + this->right_cursor_x = 0; + this->right_cursor_y = 0; +} + +void opPanel::SaveSize(int id) +{ + this->img_size[id][0] = this->picture[id].GetWidth(); + this->img_size[id][1] = this->picture[id].GetHeight(); +} + +void opPanel::HideImg(int id) +{ + this->show_image[id] = false; + this->Refresh(); +} + +void opPanel::ShowImg(int id) +{ + this->show_image[id] = true; + this->Refresh(); +} + +void opPanel::MoveJoystick(int axe,int value) +{ + if(axe == 0) + { + this->left_cursor_x = value*30/40000; + } + else if(axe == 1) + { + this->left_cursor_y = value*30/40000; + } + else if( axe == 2) + { + this->right_cursor_x = value*30/40000; + } + else + { + this->right_cursor_y = value*30/40000; + } +} + +BEGIN_EVENT_TABLE(opPanel, wxPanel) + EVT_PAINT(opPanel::OnPaint) +END_EVENT_TABLE() + +void opPanel::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + wxSize sz = GetClientSize(); + + wxMemoryDC temp_background, temp_start, temp_select, temp_analog, temp_dp_left, + temp_dp_right, temp_dp_up, temp_dp_bottom, temp_l1, temp_r1, temp_L3, temp_l2_2, + temp_R3, temp_r2_2, temp_square, temp_circle, temp_cross, temp_triangle, + temp_left_cursor, temp_right_cursor; + + temp_background.SelectObject(this->picture[img_background]); + temp_start.SelectObject(this->picture[img_start]); + temp_select.SelectObject(this->picture[img_select]); + temp_analog.SelectObject(this->picture[img_analog]); + temp_dp_left.SelectObject(this->picture[img_dp_left]); + + temp_dp_right.SelectObject(this->picture[img_dp_right]); + temp_dp_up.SelectObject(this->picture[img_dp_up]); + temp_dp_bottom.SelectObject(this->picture[img_dp_bottom]); + temp_l1.SelectObject(this->picture[img_l1]); + temp_r1.SelectObject(this->picture[img_r1]); + temp_L3.SelectObject(this->picture[img_l3]); + temp_l2_2.SelectObject(this->picture[img_l2]); + + temp_R3.SelectObject(this->picture[img_r3]); + temp_r2_2.SelectObject(this->picture[img_r2]); + temp_square.SelectObject(this->picture[img_square]); + temp_circle.SelectObject(this->picture[img_circle]); + temp_cross.SelectObject(this->picture[img_cross]); + temp_triangle.SelectObject(this->picture[img_triangle]); + + temp_left_cursor.SelectObject(this->picture[img_left_cursor]); + temp_right_cursor.SelectObject(this->picture[img_right_cursor]); + + if(this->show_image[img_background]) + dc.Blit(wxPoint(0, 0), temp_background.GetSize(), &temp_background, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_start]) + dc.Blit(wxPoint(526, 296), temp_start.GetSize(), &temp_start, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_select]) + dc.Blit(wxPoint(450, 297), temp_select.GetSize(), &temp_select, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_analog]) + dc.Blit(wxPoint(489, 358), temp_analog.GetSize(), &temp_analog, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_dp_left]) + dc.Blit(wxPoint(335, 292), temp_dp_left.GetSize(), &temp_dp_left, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_dp_right]) + dc.Blit(wxPoint(378, 292), temp_dp_right.GetSize(), &temp_dp_right, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_dp_up]) + dc.Blit(wxPoint(358, 269), temp_dp_up.GetSize(), &temp_dp_up, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_dp_bottom]) + dc.Blit(wxPoint(358, 312), temp_dp_bottom.GetSize(), &temp_dp_bottom, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_l1]) + dc.Blit(wxPoint(343, 186), temp_l1.GetSize(), &temp_l1, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_r1]) + dc.Blit(wxPoint(594, 186), temp_r1.GetSize(), &temp_r1, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_l3]) + dc.Blit(wxPoint(409, 344), temp_L3.GetSize(), &temp_L3, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_l2]) + dc.Blit(wxPoint(347, 158), temp_l2_2.GetSize(), &temp_l2_2, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_r3]) + dc.Blit(wxPoint(525, 344), temp_R3.GetSize(), &temp_R3, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_r2]) + dc.Blit(wxPoint(581, 158), temp_r2_2.GetSize(), &temp_r2_2, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_square]) + dc.Blit(wxPoint(573, 287), temp_square.GetSize(), &temp_square, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_circle]) + dc.Blit(wxPoint(647, 287), temp_circle.GetSize(), &temp_circle, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_cross]) + dc.Blit(wxPoint(610, 324), temp_cross.GetSize(), &temp_cross, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_triangle]) + dc.Blit(wxPoint(610, 250), temp_triangle.GetSize(), &temp_triangle, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_left_cursor]) + dc.Blit(wxPoint(439+this->left_cursor_x, 374+this->left_cursor_y), temp_left_cursor.GetSize(), &temp_left_cursor, wxPoint(0, 0), wxCOPY, true); + if(this->show_image[img_right_cursor]) + dc.Blit(wxPoint(555+this->right_cursor_x, 374+this->right_cursor_y), temp_right_cursor.GetSize(), &temp_right_cursor, wxPoint(0, 0), wxCOPY, true); +} diff --git a/plugins/onepad/Linux/opPanel.h b/plugins/onepad/Linux/opPanel.h new file mode 100644 index 0000000000..3c9321e859 --- /dev/null +++ b/plugins/onepad/Linux/opPanel.h @@ -0,0 +1,70 @@ +/* opPanel.h + * 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 + */ + +#pragma once + +#ifndef __OPPANEL_H__ +#define __OPPANEL_H__ + +#include + +#include "EmbeddedImage.h" + +enum gui_img { + img_l2, + img_r2, + img_l1, + img_r1, + img_triangle, + img_circle, + img_cross, + img_square, + img_select, + img_l3, + img_r3, + img_start, + img_dp_up, + img_dp_right, + img_dp_bottom, + img_dp_left, + img_left_cursor, + img_right_cursor, + img_analog, + img_background // background pic +}; + +#define NB_IMG 20 + +class opPanel : public wxPanel +{ + wxBitmap picture[NB_IMG]; + int img_size[NB_IMG][2]; + bool show_image[NB_IMG]; + int left_cursor_x, left_cursor_y, right_cursor_x, right_cursor_y; + void SaveSize(int); + DECLARE_EVENT_TABLE() + void OnPaint(wxPaintEvent& event); + +public: + opPanel(wxWindow*, wxWindowID, const wxPoint&, const wxSize&); + void HideImg(int); + void ShowImg(int); + void MoveJoystick(int, int); +}; + +#endif // __OPPANEL_H__ diff --git a/plugins/onepad/SDL/joystick.cpp b/plugins/onepad/SDL/joystick.cpp index 5b5db01900..d8be8679a7 100644 --- a/plugins/onepad/SDL/joystick.cpp +++ b/plugins/onepad/SDL/joystick.cpp @@ -130,7 +130,7 @@ void JoystickInfo::Rumble(int type, int pad) { fprintf(stderr,"ERROR: Effect is not uploaded! %s, id is %d\n",SDL_GetError(),effects_id[0]); } - + /** Effect for big motor **/ effects[1].type = SDL_HAPTIC_TRIANGLE; effects_id[1] = SDL_HapticNewEffect(haptic, &effects[1]); @@ -236,18 +236,23 @@ void JoystickInfo::SaveState() SetHatState(i, SDL_JoystickGetHat(joy, i)); } -void JoystickInfo::TestForce() +bool JoystickInfo::TestForce(float strength=0.60) { #if SDL_MAJOR_VERSION >= 2 // This code just use standard rumble to check that SDL handles the pad correctly! --3kinox - if(haptic == NULL) return; // Otherwise, core dump! + if(haptic == NULL) + return false; // Otherwise, core dump! SDL_HapticRumbleInit( haptic ); // Make the haptic pad rumble 60% strength for half a second, shoudld be enough for user to see if it works or not - if( SDL_HapticRumblePlay( haptic, 0.60, 400 ) != 0) + if( SDL_HapticRumblePlay( haptic, strength, 400 ) != 0) { fprintf(stderr,"ERROR: Rumble is not working! %s\n",SDL_GetError()); + return false; } + #endif + + return true; } bool JoystickInfo::PollButtons(u32 &pkey) diff --git a/plugins/onepad/SDL/joystick.h b/plugins/onepad/SDL/joystick.h index 6ec6187d07..5fe9ece548 100644 --- a/plugins/onepad/SDL/joystick.h +++ b/plugins/onepad/SDL/joystick.h @@ -52,7 +52,7 @@ class JoystickInfo : GamePad JoystickInfo(const JoystickInfo&); // copy constructor JoystickInfo& operator=(const JoystickInfo&); // assignment - + void Destroy(); // opens handles to all possible joysticks static void EnumerateJoysticks(vector& vjoysticks); @@ -61,7 +61,7 @@ class JoystickInfo : GamePad bool Init(int id); // opens a handle and gets information - void TestForce(); + bool TestForce(float); bool PollButtons(u32 &pkey); bool PollAxes(u32 &pkey); diff --git a/plugins/onepad/controller.h b/plugins/onepad/controller.h index 4f05078f62..55ca2d6796 100644 --- a/plugins/onepad/controller.h +++ b/plugins/onepad/controller.h @@ -101,7 +101,7 @@ class PADconf int shift = 8 * pad; return ((joyid_map >> shift) & 0xFF); } - + /** * Return (a copy of) private memner ff_instensity **/ @@ -116,7 +116,7 @@ class PADconf **/ void set_ff_intensity(u32 new_intensity) { - if(new_intensity < 0x7FFF && new_intensity >= 0) + if(new_intensity <= 0x7FFF && new_intensity >= 0) { ff_intensity = new_intensity; } diff --git a/plugins/onepad/onepad.cpp b/plugins/onepad/onepad.cpp index 62cfaa1547..64e5d48275 100644 --- a/plugins/onepad/onepad.cpp +++ b/plugins/onepad/onepad.cpp @@ -47,7 +47,7 @@ bool toggleAutoRepeat = false; const u32 version = PS2E_PAD_VERSION; const u32 revision = 1; -const u32 build = 1; // increase that with each version +const u32 build = 2; // increase that with each version int PadEnum[2][2] = {{0, 2}, {1, 3}}; diff --git a/plugins/onepad/onepad.h b/plugins/onepad/onepad.h index d19da64482..81acf5a575 100644 --- a/plugins/onepad/onepad.h +++ b/plugins/onepad/onepad.h @@ -97,30 +97,30 @@ enum PadCommands enum gamePadValues { - PAD_L2 = 0, - PAD_R2, - PAD_L1, - PAD_R1, - PAD_TRIANGLE, - PAD_CIRCLE, - PAD_CROSS, - PAD_SQUARE, - PAD_SELECT, - PAD_L3, - PAD_R3, - PAD_START, - PAD_UP, - PAD_RIGHT, - PAD_DOWN, - PAD_LEFT, - PAD_L_UP, - PAD_L_RIGHT, - PAD_L_DOWN, - PAD_L_LEFT, - PAD_R_UP, - PAD_R_RIGHT, - PAD_R_DOWN, - PAD_R_LEFT + PAD_L2 = 0, // L2 button + PAD_R2, // R2 button + PAD_L1, // L1 button + PAD_R1, // R1 button + PAD_TRIANGLE, // Triangle button ▲ + PAD_CIRCLE, // Circle button ● + PAD_CROSS, // Cross button ✖ + PAD_SQUARE, // Square button ■ + PAD_SELECT, // Select button + PAD_L3, // Left joystick button (L3) + PAD_R3, // Right joystick button (R3) + PAD_START, // Start button + PAD_UP, // Directional pad ↑ + PAD_RIGHT, // Directional pad → + PAD_DOWN, // Directional pad ↓ + PAD_LEFT, // Directional pad ← + PAD_L_UP, // Left joystick (Up) ↑ + PAD_L_RIGHT, // Left joystick (Right) → + PAD_L_DOWN, // Left joystick (Down) ↓ + PAD_L_LEFT, // Left joystick (Left) ← + PAD_R_UP, // Right joystick (Up) ↑ + PAD_R_RIGHT, // Right joystick (Right) → + PAD_R_DOWN, // Right joystick (Down) ↓ + PAD_R_LEFT // Right joystick (Left) ← }; extern keyEvent event;