From 00bca8d8074df8aef58d3075af43251521f828b6 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Tue, 20 Jan 2009 05:28:30 +0000 Subject: [PATCH] nJoy: Fixed the analog shoulder buttons for the XBox 360 pad git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1944 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp | 5 +- .../Src/GUI/ConfigAdvanced.cpp | 71 ++++++--- .../Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp | 149 +++++++++++------- .../Plugin_nJoy_SDL/Src/GUI/ConfigBox.h | 29 ++-- .../Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp | 41 ++--- Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp | 80 +++++++--- Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h | 13 +- 7 files changed, 259 insertions(+), 129 deletions(-) diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp index 3676b44e2d..7f49bda16f 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp @@ -221,6 +221,7 @@ void Config::Save(bool CheckedForDuplicates) file.Set(SectionName.c_str(), "halfpress", joysticks[i].halfpress); file.Set(SectionName.c_str(), "controllertype", joysticks[i].controllertype); + file.Set(SectionName.c_str(), "TriggerType", joysticks[i].triggertype); file.Set(SectionName.c_str(), "eventnum", joysticks[i].eventnum); file.Set(SectionName.c_str(), "Diagonal", g_Config.SDiagonal); @@ -291,9 +292,11 @@ void Config::Load(bool config) file.Get(SectionName.c_str(), "main_y", &joysticks[i].axis[CTL_MAIN_Y], 1); file.Get(SectionName.c_str(), "sub_x", &joysticks[i].axis[CTL_SUB_X], 2); file.Get(SectionName.c_str(), "sub_y", &joysticks[i].axis[CTL_SUB_Y], 3); - file.Get(SectionName.c_str(), "deadzone", &joysticks[i].deadzone, 9); + + file.Get(SectionName.c_str(), "deadzone", &joysticks[i].deadzone, 9); file.Get(SectionName.c_str(), "halfpress", &joysticks[i].halfpress, 6); file.Get(SectionName.c_str(), "controllertype", &joysticks[i].controllertype, 0); + file.Get(SectionName.c_str(), "TriggerType", &joysticks[i].triggertype, 0); file.Get(SectionName.c_str(), "eventnum", &joysticks[i].eventnum, 0); file.Get(SectionName.c_str(), "Diagonal", &g_Config.SDiagonal, "100%"); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp index 8686c1b9e2..bc7c6afcd5 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp @@ -54,6 +54,7 @@ void ConfigBox::PadGetStatus() { m_TStatusIn[notebookpage]->SetLabel(wxT("Not connected")); m_TStatusOut[notebookpage]->SetLabel(wxT("Not connected")); + m_TStatusTriggers[notebookpage]->SetLabel(wxT("Not connected")); return; } @@ -62,12 +63,20 @@ void ConfigBox::PadGetStatus() { m_TStatusIn[notebookpage]->SetLabel(wxT("Not enabled")); m_TStatusOut[notebookpage]->SetLabel(wxT("Not enabled")); + m_TStatusTriggers[notebookpage]->SetLabel(wxT("Not enabled")); return; } + // Get physical device status + int PhysicalDevice = joysticks[notebookpage].ID; + int TriggerType = joysticks[notebookpage].triggertype; + // Get pad status GetJoyState(notebookpage); + ////////////////////////////////////// + // Analog stick + // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ // Set Deadzones perhaps out of function //int deadzone = (int)(((float)(128.00/100.00)) * (float)(joysticks[_numPAD].deadzone+1)); //int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(joysticks[_numPAD].deadzone+1)); @@ -93,16 +102,6 @@ void ConfigBox::PadGetStatus() float f_x_aft = main_x_after / 32767.0; float f_y_aft = main_y_after / 32767.0; - /* - m_pStatusBar->SetLabel(wxString::Format( - "ID:%i | %i %i = %1.2f %1.2f | %i %i = %1.2f %1.2f", - ID, - main_x, main_y, - f_x, f_y, - main_x_after, main_y_after, - f_x_aft, f_y_aft - ));*/ - m_TStatusIn[notebookpage]->SetLabel(wxString::Format( wxT("x:%1.2f y:%1.2f"), f_x, f_y @@ -125,25 +124,54 @@ void ConfigBox::PadGetStatus() // Adjust the dot m_bmpDot[notebookpage]->SetPosition(wxPoint(main_x, main_y)); m_bmpDotOut[notebookpage]->SetPosition(wxPoint(main_x_out, main_y_out)); - + ///////////////////// Analog stick + + + ////////////////////////////////////// + // Triggers + // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ + int SDLTriggerLeft = joystate[notebookpage].axis[CTL_L_SHOULDER]; + int SDLTriggerRight = joystate[notebookpage].axis[CTL_R_SHOULDER]; + + // Convert the triggers values + u8 TriggerLeft = Pad_Convert(SDLTriggerLeft, TriggerType); + u8 TriggerRight = Pad_Convert(SDLTriggerRight, TriggerType); + + m_TStatusTriggers[notebookpage]->SetLabel(wxString::Format( + wxT("Left:%03i Right:%03i"), + TriggerLeft, TriggerRight + )); + ///////////////////// Triggers } // Show the current pad status // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -std::string ShowStatus(int Controller) +std::string ShowStatus(int VirtualController) { + // Check if it's enabled + if (!joysticks[VirtualController].enabled) return "Disabled"; + + // Save the physical device + int PhysicalDevice = joysticks[VirtualController].ID; + // Make local shortcut - SDL_Joystick *joy = joystate[joysticks[Controller].ID].joy; + SDL_Joystick *joy = joystate[VirtualController].joy; + + // Make shortcuts for all pads + SDL_Joystick *joy0 = joystate[joysticks[0].ID].joy; + SDL_Joystick *joy1 = joystate[joysticks[1].ID].joy; + SDL_Joystick *joy2 = joystate[joysticks[2].ID].joy; + SDL_Joystick *joy3 = joystate[joysticks[3].ID].joy; // Temporary storage std::string StrAxes, StrHats, StrBut; int value; // Get status - int Axes = joyinfo[joysticks[Controller].ID].NumAxes; - int Balls = joyinfo[joysticks[Controller].ID].NumBalls; - int Hats = joyinfo[joysticks[Controller].ID].NumHats; - int Buttons = joyinfo[joysticks[Controller].ID].NumButtons; + int Axes = joyinfo[PhysicalDevice].NumAxes; + int Balls = joyinfo[PhysicalDevice].NumBalls; + int Hats = joyinfo[PhysicalDevice].NumHats; + int Buttons = joyinfo[PhysicalDevice].NumButtons; // Update the internal values SDL_JoystickUpdate(); @@ -166,7 +194,14 @@ std::string ShowStatus(int Controller) } return StringFromFormat( - "Axes: %s\nHats: %s\nBut: %s\nDevice: Ax: %i Balls:%i But:%i Hats:%i", + "joysticks.ID: %i %i %i %i\n" + "Handles: %i %i %i %i\n" + "Axes: %s\n" + "Hats: %s\n" + "But: %s\n" + "Device: Ax: %i Balls:%i But:%i Hats:%i", + joysticks[0].ID, joysticks[1].ID, joysticks[2].ID, joysticks[3].ID, + (int)joy0, (int)joy1, (int)joy2, (int)joy3, StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(), Axes, Balls, Hats, Buttons ); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp index 05a6a11221..db5936a1e8 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp @@ -43,11 +43,19 @@ extern CONTROLLER_INFO *joyinfo; //extern CONTROLLER_MAPPING joysticks[4]; extern bool emulator_running; +// D-Pad type static const char* DPadType[] = { "Hat", "Custom", }; + +// Trigger type +static const char* TriggerType[] = +{ + "Half", // 0x0000 to 0x8000 + "Full", // -0x8000 to 0x8000 +}; //////////////////////// @@ -59,16 +67,20 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog) EVT_BUTTON(ID_ABOUT, ConfigBox::AboutClick) EVT_BUTTON(ID_OK, ConfigBox::OKClick) EVT_BUTTON(ID_CANCEL, ConfigBox::CancelClick) - EVT_COMBOBOX(IDC_JOYNAME, ConfigBox::ChangeJoystick) - EVT_COMBOBOX(IDC_CONTROLTYPE, ConfigBox::ChangeControllertype) - EVT_CHECKBOX(IDC_JOYATTACH, ConfigBox::EnableDisable) EVT_NOTEBOOK_PAGE_CHANGED(ID_NOTEBOOK, ConfigBox::NotebookPageChanged) - EVT_CHECKBOX(IDC_SAVEBYID, ConfigBox::ChangeSettings) // Settings + // Change and enable or disable gamepad + EVT_COMBOBOX(IDC_JOYNAME, ConfigBox::ChangeJoystick) + EVT_CHECKBOX(IDC_JOYATTACH, ConfigBox::EnableDisable) + + // Settings + EVT_CHECKBOX(IDC_SAVEBYID, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDC_SAVEBYIDNOTICE, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDC_SHOWADVANCED, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDCB_MAINSTICK_S_TO_C, ConfigBox::ChangeSettings) + EVT_COMBOBOX(IDC_CONTROLTYPE, ConfigBox::ChangeControllertype) + EVT_COMBOBOX(IDC_TRIGGERTYPE, ConfigBox::ChangeControllertype) EVT_BUTTON(IDB_SHOULDER_L, ConfigBox::GetButtons) EVT_BUTTON(IDB_SHOULDER_R, ConfigBox::GetButtons) @@ -242,6 +254,8 @@ void ConfigBox::EnableDisable(wxCommandEvent& event) // Update the enable / disable status UpdateGUI(notebookpage); + // Update the status + SaveButtonMapping(notebookpage); } // Update GUI @@ -254,20 +268,20 @@ void ConfigBox::UpdateGUI(int _notebookpage) // Controller type settings bool Hat = (joysticks[_notebookpage].controllertype == CTL_DPAD_HAT); + m_JoyDpadUp[_notebookpage]->Show(!Hat); m_JoyDpadLeft[_notebookpage]->Show(!Hat); m_JoyDpadRight[_notebookpage]->Show(!Hat); - m_JoyDpadDown[_notebookpage]->Show(!Hat); + m_bJoyDpadUp[_notebookpage]->Show(!Hat); m_bJoyDpadLeft[_notebookpage]->Show(!Hat); m_bJoyDpadRight[_notebookpage]->Show(!Hat); - m_bJoyDpadDown[_notebookpage]->Show(!Hat); - - m_textDpadDown[_notebookpage]->Show(!Hat); + + m_textDpadUp[_notebookpage]->Show(!Hat); m_textDpadLeft[_notebookpage]->Show(!Hat); m_textDpadRight[_notebookpage]->Show(!Hat); - m_textDpadUp[_notebookpage]->SetLabel(Hat ? wxT("Select hat") : wxT("Up")); - m_bJoyDpadUp[_notebookpage]->SetToolTip(Hat ? + m_textDpadDown[_notebookpage]->SetLabel(Hat ? wxT("Select hat") : wxT("Up")); + m_bJoyDpadDown[_notebookpage]->SetToolTip(Hat ? wxT("Select a hat by pressing the hat in any direction") : wxT("")); // General settings @@ -289,7 +303,6 @@ void ConfigBox::UpdateGUI(int _notebookpage) // Controller type settings m_Controller[_notebookpage]->FindItem(IDC_DEADZONE)->Enable(joysticks[_notebookpage].enabled); - //m_Controller[_notebookpage]->FindItem(IDC_CONTROLTYPE)->Enable(joysticks[_notebookpage].enabled); #endif // Repaint the background @@ -305,29 +318,21 @@ void ConfigBox::NotebookPageChanged(wxNotebookEvent& event) } -// Change Joystick. +// Change Joystick // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ /* Function: When changing the joystick we save and load the settings and update the joysticks and joystate array */ void ConfigBox::ChangeJoystick(wxCommandEvent& event) { // Before chaning the pad we save potential changes (to support SaveByID) - int TmpID = joysticks[notebookpage].ID; // Don't update the ID - SaveButtonMapping(notebookpage); + int TmpID = joysticks[notebookpage].ID; // Don't update the ID before saving + SaveButtonMapping(notebookpage); // Update the ID among other things joysticks[notebookpage].ID = TmpID; g_Config.Save(); - //PanicAlert("%i", m_Joyname[notebookpage]->GetSelection()); - - // Update the ID for the virtual device to a new physical device + // Update the physical device ID for the virtual device joysticks[notebookpage].ID = m_Joyname[notebookpage]->GetSelection(); - // Update the controller type - if(joyinfo[joysticks[notebookpage].ID].NumHats > 0) - joysticks[notebookpage].controllertype = CTL_DPAD_HAT; - - //PanicAlert("%i %i", joysticks[notebookpage].ID, notebookpage); - // Load device settings to support SaveByID g_Config.Load(true); // Then load the current UpdateGUIKeys(notebookpage); // Update joystick dialog items @@ -336,10 +341,10 @@ void ConfigBox::ChangeJoystick(wxCommandEvent& event) // Remap the controller if (joysticks[notebookpage].enabled) { - return; - if (SDL_JoystickOpened(notebookpage)) SDL_JoystickClose(joystate[notebookpage].joy); + //Console::Print("Id: %i\n", joysticks[notebookpage].ID); + + if (SDL_JoystickOpened(joysticks[notebookpage].ID)) SDL_JoystickClose(joystate[notebookpage].joy); joystate[notebookpage].joy = SDL_JoystickOpen(joysticks[notebookpage].ID); - PanicAlert(""); } } @@ -426,12 +431,15 @@ void ConfigBox::CreateGUIControls() } // -------------------------------------------------------------------- - // Populate the controller type list + // Populate the DPad type and Trigger type list // ----------------------------- - wxArrayString arrayStringFor_Controltype; - arrayStringFor_Controltype.Add(wxString::FromAscii(DPadType[CTL_DPAD_HAT])); - arrayStringFor_Controltype.Add(wxString::FromAscii(DPadType[CTL_DPAD_CUSTOM])); + wxArrayString wxAS_DPadType; + wxAS_DPadType.Add(wxString::FromAscii(DPadType[CTL_DPAD_HAT])); + wxAS_DPadType.Add(wxString::FromAscii(DPadType[CTL_DPAD_CUSTOM])); + wxArrayString wxAS_TriggerType; + wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_HALF])); + wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_WHOLE])); // -------------------------------------------------------------------- // Populate the deadzone list @@ -580,54 +588,70 @@ void ConfigBox::CreateGUIControls() m_Joyname[i]->SetToolTip(wxT("Save your settings and configure another joypad")); - // -------------------------------------------------------------------- - // Populate settings sizer - // ----------------------------- + //////////////////////////////////////////// + // General settings + // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ - // Extra settings members - m_gGBExtrasettings[i] = new wxGridBagSizer(0, 0); + // General settings 1 m_JoyButtonHalfpress[i] = new wxTextCtrl(m_Controller[i], ID_BUTTONHALFPRESS, wxT("0"), wxDefaultPosition, wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); m_JoyButtonHalfpress[i]->Enable(false); - m_bJoyButtonHalfpress[i] = new wxButton(m_Controller[i], IDB_BUTTONHALFPRESS, wxEmptyString, wxPoint(231, 426), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyButtonHalfpress[i] = new wxButton(m_Controller[i], IDB_BUTTONHALFPRESS, wxEmptyString, wxDefaultPosition, wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); #ifdef _WIN32 m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxDefaultPosition, wxSize(59, 21), arrayStringFor_Deadzone, wxCB_READONLY, wxDefaultValidator, wxT("m_Deadzone")); - m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone"), wxDefaultPosition, wxDefaultSize, 0, wxT("Deadzone")); - m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press"), wxDefaultPosition, wxDefaultSize, 0, wxT("Half press")); + m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone")); + m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press")); #else m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxPoint(167, 398), wxSize(80, 25), arrayStringFor_Deadzone, wxCB_READONLY, wxDefaultValidator, wxT("m_Deadzone")); m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone"), wxPoint(105, 404), wxDefaultSize, 0, wxT("Deadzone")); m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press"), wxPoint(105, 428), wxDefaultSize, 0, wxT("Half press")); #endif - // Populate extra settings + // Populate general settings 1 m_gExtrasettings[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Extra settings")); - m_gGBExtrasettings[i]->Add(m_textDeadzone[i], wxGBPosition(0, 0), wxGBSpan(1, 1), (wxRIGHT | wxTOP), 2); + m_gGBExtrasettings[i] = new wxGridBagSizer(0, 0); + m_gGBExtrasettings[i]->Add(m_textDeadzone[i], wxGBPosition(0, 0), wxGBSpan(1, 1), (wxRIGHT | wxTOP), 3); m_gGBExtrasettings[i]->Add(m_Deadzone[i], wxGBPosition(0, 1), wxGBSpan(1, 1), (wxBOTTOM), 2); - m_gGBExtrasettings[i]->Add(m_textHalfpress[i], wxGBPosition(1, 0), wxGBSpan(1, 1), (wxRIGHT | wxTOP), 2); - m_gGBExtrasettings[i]->Add(m_JoyButtonHalfpress[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxALL, 0); + m_gGBExtrasettings[i]->Add(m_textHalfpress[i], wxGBPosition(1, 0), wxGBSpan(1, 1), (wxRIGHT | wxTOP), 3); + m_gGBExtrasettings[i]->Add(m_JoyButtonHalfpress[i], wxGBPosition(1, 1), wxGBSpan(1, 1), (wxALL), 0); m_gGBExtrasettings[i]->Add(m_bJoyButtonHalfpress[i], wxGBPosition(1, 2), wxGBSpan(1, 1), (wxLEFT | wxTOP), 2); m_gExtrasettings[i]->Add(m_gGBExtrasettings[i], 0, wxEXPAND | wxALL, 3); - // Populate controller typ - m_gControllertype[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("D-Pad")); - m_Controltype[i] = new wxComboBox(m_Controller[i], IDC_CONTROLTYPE, arrayStringFor_Controltype[0], wxDefaultPosition, wxDefaultSize, arrayStringFor_Controltype, wxCB_READONLY); - m_gControllertype[i]->Add(m_Controltype[i], 0, wxEXPAND | wxALL, 3); - m_Controltype[i]->SetToolTip(wxT("Use a 'hat' on your gamepad or configure a custom button for each direction.")); + // Create general settings 2 (controller typ) + m_TSControltype[i] = new wxStaticText(m_Controller[i], IDT_DPADTYPE, wxT("D-Pad")); + m_TSTriggerType[i] = new wxStaticText(m_Controller[i], IDT_TRIGGERTYPE, wxT("Trigger")); + m_ControlType[i] = new wxComboBox(m_Controller[i], IDC_CONTROLTYPE, wxAS_DPadType[0], wxDefaultPosition, wxDefaultSize, wxAS_DPadType, wxCB_READONLY); + m_TriggerType[i] = new wxComboBox(m_Controller[i], IDC_TRIGGERTYPE, wxAS_TriggerType[0], wxDefaultPosition, wxDefaultSize, wxAS_TriggerType, wxCB_READONLY); - // Create objects for general settings - m_gGenSettings[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Settings") ); + // Populate general settings 2 (controller typ) + m_gGenSettings[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("D-Pad and Trigger")); + m_gGBGenSettings[i] = new wxGridBagSizer(0, 0); + m_gGBGenSettings[i]->Add(m_TSControltype[i], wxGBPosition(0, 0), wxGBSpan(1, 1), (wxTOP), 4); + m_gGBGenSettings[i]->Add(m_ControlType[i], wxGBPosition(0, 1), wxGBSpan(1, 1), (wxBOTTOM | wxLEFT), 2); + m_gGBGenSettings[i]->Add(m_TSTriggerType[i], wxGBPosition(1, 0), wxGBSpan(1, 1), (wxTOP), 4); + m_gGBGenSettings[i]->Add(m_TriggerType[i], wxGBPosition(1, 1), wxGBSpan(1, 1), (wxLEFT), 2); + m_gGenSettings[i]->Add(m_gGBGenSettings[i], 0, wxEXPAND | wxALL, 3); + + // Create objects for general settings 3 + m_gGenSettingsID[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Settings") ); m_CBSaveByID[i] = new wxCheckBox(m_Controller[i], IDC_SAVEBYID, wxT("Save by ID"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_CBSaveByIDNotice[i] = new wxCheckBox(m_Controller[i], IDC_SAVEBYIDNOTICE, wxT("Notify"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_CBShowAdvanced[i] = new wxCheckBox(m_Controller[i], IDC_SHOWADVANCED, wxT("Show advanced settings"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - // Populate general settings + // Populate general settings 3 m_sSaveByID[i] = new wxBoxSizer(wxHORIZONTAL); m_sSaveByID[i]->Add(m_CBSaveByID[i], 0, wxEXPAND | wxALL, 0); m_sSaveByID[i]->Add(m_CBSaveByIDNotice[i], 0, wxEXPAND | wxLEFT, 2); - m_gGenSettings[i]->Add(m_sSaveByID[i], 0, wxEXPAND | wxALL, 3); - m_gGenSettings[i]->Add(m_CBShowAdvanced[i], 0, wxEXPAND | wxALL, 3); + m_gGenSettingsID[i]->Add(m_sSaveByID[i], 0, wxEXPAND | wxALL, 3); + m_gGenSettingsID[i]->Add(m_CBShowAdvanced[i], 0, wxEXPAND | wxALL, 3); // Create tooltips + m_ControlType[i]->SetToolTip(wxT( + "Use a 'hat' on your gamepad or configure a custom button for each direction." + )); + m_TriggerType[i]->SetToolTip(wxT( + "You can look under 'Trigger values' in the advanced settings to see which of these modes work for your gamepad." + " If it works the unpressed to pressed range should be 0 - 255." + )); m_CBSaveByID[i]->SetToolTip(wxString::Format(wxT( "Map these settings to the selected controller device instead of to the" "\nselected controller number (%i). This may be a more convenient way" @@ -636,17 +660,20 @@ void ConfigBox::CreateGUIControls() )); m_CBSaveByIDNotice[i]->SetToolTip(wxString::Format(wxT( "Show a notification message if you have selected this option for multiple identical joypads.") - )); + )); // Populate settings m_sSettings[i] = new wxBoxSizer ( wxHORIZONTAL ); m_sSettings[i]->Add(m_gExtrasettings[i], 0, wxEXPAND | wxALL, 0); - m_sSettings[i]->Add(m_gControllertype[i], 0, wxEXPAND | wxLEFT, 5); m_sSettings[i]->Add(m_gGenSettings[i], 0, wxEXPAND | wxLEFT, 5); + m_sSettings[i]->Add(m_gGenSettingsID[i], 0, wxEXPAND | wxLEFT, 5); + // ------------------------- + + //////////////////////////// General settings - ////////////////////////////////////// - // Populate advanced settings + //////////////////////////////////////////// + // Advanced settings // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ // Populate input status @@ -694,7 +721,12 @@ void ConfigBox::CreateGUIControls() m_gStatusInSettingsH[i]->Add(m_STDiagonal[i], 0, wxTOP, 3); m_gStatusInSettingsH[i]->Add(m_CoBDiagonal[i], 0, wxLEFT, 3); - + + // The trigger values + m_gStatusTriggers[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Trigger values")); + m_TStatusTriggers[i] = new wxStaticText(m_Controller[i], IDT_TRIGGERS, wxT("Left: Right:")); + m_gStatusTriggers[i]->Add(m_TStatusTriggers[i], 0, (wxALL), 4); + ////////////////////////// Advanced settings ////////////////////////////////////// @@ -715,6 +747,7 @@ void ConfigBox::CreateGUIControls() m_sMainRight[i] = new wxBoxSizer(wxVERTICAL); m_sMainRight[i]->Add(m_gStatusIn[i], 0, wxEXPAND | (wxLEFT), 2); m_sMainRight[i]->Add(m_gStatusInSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2); + m_sMainRight[i]->Add(m_gStatusTriggers[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2); // -------------------------------------------------------------------- // Populate main sizer @@ -732,7 +765,7 @@ void ConfigBox::CreateGUIControls() { m_Joyname[i]->Enable(false); m_Joyattach[i]->Enable(false); - m_Controltype[i]->Enable(false); + m_ControlType[i]->Enable(false); } // Set dialog items from saved values diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h index b3132f48ef..3cc3bc464c 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h @@ -95,26 +95,32 @@ class ConfigBox : public wxDialog // ŻŻŻŻŻŻŻŻŻ wxComboBox *m_Joyname[4]; - wxComboBox *m_Controltype[4]; + wxComboBox *m_ControlType[4], *m_TriggerType[4]; wxComboBox *m_Deadzone[4]; - wxCheckBox *m_Joyattach[4]; + wxCheckBox *m_Joyattach[4]; // Attached pad wxStaticBoxSizer *m_gJoyname[4]; - wxBoxSizer* m_sSettings[4]; // Settings - - wxStaticBoxSizer *m_gExtrasettings[4]; wxGridBagSizer * m_gGBExtrasettings[4]; // Extra settings - wxStaticBoxSizer *m_gControllertype[4]; + wxStaticBoxSizer *m_gExtrasettings[4]; // Extra settings + wxGridBagSizer * m_gGBExtrasettings[4]; - wxBoxSizer *m_sSaveByID[4]; wxStaticBoxSizer *m_gGenSettings[4]; // General settings + wxBoxSizer* m_sSettings[4]; // General settings 2 + wxStaticBoxSizer *m_gGenSettings[4]; + + wxBoxSizer *m_sSaveByID[4]; + wxStaticBoxSizer *m_gGenSettingsID[4]; + wxGridBagSizer * m_gGBGenSettings[4]; wxCheckBox *m_CBSaveByID[4], *m_CBSaveByIDNotice[4], *m_CBShowAdvanced[4]; + wxStaticText *m_TSControltype[4], *m_TSTriggerType[4]; wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4]; // Advanced settings wxBoxSizer *m_gStatusInSettingsH[4]; wxGridBagSizer * m_GBAdvancedMainStick[4]; - wxStaticText *m_TStatusIn[4], *m_TStatusOut[4]; - wxComboBox *m_CoBDiagonal[4]; wxCheckBox *m_CBS_to_C[4]; wxStaticText *m_STDiagonal[4]; + wxStaticText *m_TStatusIn[4], *m_TStatusOut[4], *m_STDiagonal[4]; + wxComboBox *m_CoBDiagonal[4]; wxCheckBox *m_CBS_to_C[4]; + wxStaticBoxSizer *m_gStatusTriggers[4]; // Triggers + wxStaticText *m_TStatusTriggers[4]; ///////////////////////////// // Keys @@ -199,7 +205,7 @@ class ConfigBox : public wxDialog IDG_EXTRASETTINGS, IDC_DEADZONE, // Extra settings - IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, // Controller type + IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, IDC_TRIGGERTYPE, // Controller type IDC_SAVEBYID, IDC_SAVEBYIDNOTICE, IDC_SHOWADVANCED, // Settings @@ -209,7 +215,7 @@ class ConfigBox : public wxDialog IDT_STATUS_IN, IDT_STATUS_OUT, // Advaced settings - IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, + IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, // Timers IDTM_CONSTANT, IDTM_BUTTON, @@ -275,6 +281,7 @@ class ConfigBox : public wxDialog IDT_DPAD_RIGHT, IDT_DEADZONE, IDT_BUTTONHALFPRESS, + IDT_DPADTYPE, IDT_TRIGGERTYPE, IDT_ANALOG_SUB_X, IDT_ANALOG_SUB_Y, IDT_WEBSITE, diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp index bf17a8efea..c8f6efdaeb 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp @@ -77,7 +77,8 @@ void ConfigBox::UpdateGUIKeys(int controller) m_Joyattach[controller]->SetValue(FALSE); // Update the deadzone and controller type controls - m_Controltype[controller]->SetSelection(joysticks[controller].controllertype); + m_ControlType[controller]->SetSelection(joysticks[controller].controllertype); + m_TriggerType[controller]->SetSelection(joysticks[controller].triggertype); m_Deadzone[controller]->SetSelection(joysticks[controller].deadzone); UpdateGUI(controller); @@ -141,21 +142,18 @@ void ConfigBox::SaveButtonMapping(int controller) // Set enabled or disable status and other settings joysticks[controller].enabled = m_Joyattach[controller]->GetValue(); - joysticks[controller].controllertype = m_Controltype[controller]->GetSelection(); - joysticks[controller].deadzone = m_Deadzone[controller]->GetSelection(); + joysticks[controller].controllertype = m_ControlType[controller]->GetSelection(); + joysticks[controller].triggertype = m_TriggerType[controller]->GetSelection(); + joysticks[controller].deadzone = m_Deadzone[controller]->GetSelection(); } // Change controller type // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +// Called from: When the controller type is changed void ConfigBox::ChangeControllertype(wxCommandEvent& event) { - joysticks[0].controllertype = m_Controltype[0]->GetSelection(); - joysticks[1].controllertype = m_Controltype[1]->GetSelection(); - joysticks[2].controllertype = m_Controltype[2]->GetSelection(); - joysticks[3].controllertype = m_Controltype[3]->GetSelection(); - - for(int i=0; i<4 ;i++) UpdateGUI(i); + SaveButtonMapping(notebookpage); } @@ -224,8 +222,8 @@ void ConfigBox::SetButtonText(int id, char text[128]) bool AvoidValues(int value) { // Avoid detecting very small or very big (for triggers) values - if( (value > -0x1000 && value < 0x1000) // Small values - || (value < -0x7000 || value > 0x7000)) // Big values + if( (value > -0x2000 && value < 0x2000) // Small values + || (value < -0x6000 || value > 0x6000)) // Big values return true; // Avoid else return false; // Keep @@ -375,14 +373,9 @@ void ConfigBox::DoGetButtons(int GetId) } else { - wxMessageBox(wxString::Format(wxT( - "You selected a key with a to low key code (%i), please" - " select another key with a higher key code."), g_Pressed) - , wxT("Notice"), wxICON_INFORMATION); - pressed = g_Pressed; - Succeed = false; - g_Pressed = 0; + g_Pressed = -1; + Stop = true; } } @@ -429,6 +422,18 @@ void ConfigBox::DoGetButtons(int GetId) GetButtonWaitingTimer = 0; } + // If we got a bad button + if(g_Pressed == -1) + { + SetButtonText(GetId, ""); // Update text + + // Notify the user + wxMessageBox(wxString::Format(wxT( + "You selected a key with a to low key code (%i), please" + " select another key with a higher key code."), pressed) + , wxT("Notice"), wxICON_INFORMATION); + } + // We don't need this gamepad handle any more if(SDL_JoystickOpened(joysticks[Controller].ID)) SDL_JoystickClose(joy); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp index 3aaa8559cc..112373a3b1 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp @@ -422,6 +422,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) // Update the pad status GetJoyState(_numPAD); + // Get type + int TriggerType = joysticks[_numPAD].triggertype; /////////////////////////////////////////////////// // The analog controls @@ -432,10 +434,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) int i_main_stick_y = -joystate[_numPAD].axis[CTL_MAIN_Y]; int i_sub_stick_x = joystate[_numPAD].axis[CTL_SUB_X]; int i_sub_stick_y = -joystate[_numPAD].axis[CTL_SUB_Y]; - - // This assumes the trigger is -0x8000 when unpressed - int SDLTriggerLeft = joystate[_numPAD].axis[CTL_L_SHOULDER]; - int SDLTriggerRight = joystate[_numPAD].axis[CTL_R_SHOULDER]; + int SDLTriggerLeft = -joystate[_numPAD].axis[CTL_L_SHOULDER]; + int SDLTriggerRight = -joystate[_numPAD].axis[CTL_R_SHOULDER]; // Check if we should make adjustments if(g_Config.bSquareToCircle.at(_numPAD)) @@ -445,13 +445,15 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) i_main_stick_y = main_xy.at(1); } - // Convert axis values from 0xffff to 0xff + // Convert axis values u8 main_stick_x = Pad_Convert(i_main_stick_x); u8 main_stick_y = Pad_Convert(i_main_stick_y); u8 sub_stick_x = Pad_Convert(i_sub_stick_x); u8 sub_stick_y = Pad_Convert(i_sub_stick_y); - u8 TriggerLeft = Pad_Convert(SDLTriggerLeft); - u8 TriggerRight = Pad_Convert(SDLTriggerRight); + + // Convert the triggers values + u8 TriggerLeft = Pad_Convert(SDLTriggerLeft, TriggerType); + u8 TriggerRight = Pad_Convert(SDLTriggerRight, TriggerType); // Set Deadzones (perhaps out of function?) int deadzone = (int)(((float)(128.00/100.00)) * (float)(joysticks[_numPAD].deadzone + 1)); @@ -539,11 +541,12 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) // Use rumble Pad_Use_Rumble(_numPAD, _pPADStatus); - /* Debugging + /* Debugging Console::ClearScreen(); Console::Print( - "Left:%04x Right:%04x Value:%i\n" + "Trigger type: %s Left:%04x Right:%04x Value:%i\n" "D-Pad type: %s L:%i R:%i U:%i D:%i", + (joysticks[_numPAD].triggertype ? "CTL_TRIGGER_WHOLE" : "CTL_TRIGGER_HALF"), TriggerLeft, TriggerRight, triggervalue, (joysticks[_numPAD].controllertype ? "CTL_DPAD_CUSTOM" : "CTL_DPAD_HAT"), 0, 0, 0, 0 @@ -572,7 +575,7 @@ unsigned int PAD_GetAttachedPads() ////////////////////////////////////////////////////////////////////////////////////////// -// Convert stick values, for example from circle to square analog stick radius +// Convert stick values // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ /* Convert stick values. @@ -580,21 +583,44 @@ unsigned int PAD_GetAttachedPads() The value returned by SDL_JoystickGetAxis is a signed integer s16 (-32768 to 32767). The value used for the gamecube controller is an unsigned char u8 (0 to 255) with neutral at 0x80 (128), so that it's equivalent to a signed - -128 to 127. */ + -128 to 127. + + type = CTL_TRIGGER_WHOLE, !type = CTL_TRIGGER_HALF + */ // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -u8 Pad_Convert(int _val) +u8 Pad_Convert(int _val, int _type) { /* If the limits on joystate[].axis[] actually is a u16 then we don't need this but if it's not actually limited to that we need to apply these limits */ if(_val > 32767) _val = 32767; // upper limit if(_val < -32768) _val = -32768; // lower limit - // Convert (-32768 to 32767) to (-128 to 127) + /* The XBox 360 pad only goes to 0x7f80 instead of 0x8000 (0x80 below the regular maximum) + so I add the extra distance here */ + if (_val >= 0x7f7f ) _val = 0x7fff; + if (_val <= -0x7f80 ) _val = -0x8000; + + //Console::Print("0x%04x %06i\n", _val, _val); + + // Convert (-0x8000 to 0x7fff) + if(!_type && _val < 0) _val = -_val - 1; + + //Console::Print("0x%04x %06i\n", _val, _val); + + // Convert (0x7fff to 0xfffe to 0xffff) + if(!_type) _val = (_val * 2) + 1; + + //Console::Print("0x%04x %06i\n", _val, _val); + + // Convert the range (-0x8000 to 0x7fff) to (0 to 0xffff) + if(_type) _val = 0x8000 +_val; + + // Convert the range (-32768 to 32767) to (-128 to 127) _val = _val >> 8; - // Convert (-128 to 127) to (0 to 255) - u8 val = 0x80 + _val; + //Console::Print("0x%04x %06i\n\n", _val, _val); + u8 val = _val; return val; } @@ -703,8 +729,9 @@ void ReadButton(int controller, int button) // Request joystick state. // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -// Called from: PAD_GetStatus() -/* Function: Updates the joystate struct with the current pad status. The input value "controller" is +/* Called from: PAD_GetStatus() + Input: The virtual device 0, 1, 2 or 3 + Function: Updates the joystate struct with the current pad status. The input value "controller" is for a virtual controller 0 to 3. */ void GetJoyState(int controller) { @@ -722,11 +749,22 @@ void GetJoyState(int controller) joystate[controller].axis[CTL_L_SHOULDER] = SDL_JoystickGetAxis(joystate[controller].joy, joysticks[controller].buttons[CTL_L_SHOULDER] - 1000); joystate[controller].axis[CTL_R_SHOULDER] = SDL_JoystickGetAxis(joystate[controller].joy, joysticks[controller].buttons[CTL_R_SHOULDER] - 1000); - // Debugging - /* - Console::Print("Controller:%i %i\n", + // Adjust for the half value variant (for example the 360 pad) + if (joysticks[controller].triggertype == CTL_TRIGGER_HALF) + { + if (joystate[controller].axis[CTL_L_SHOULDER] < 0) joystate[controller].axis[CTL_L_SHOULDER] = 0; + if (joystate[controller].axis[CTL_R_SHOULDER] > 0) joystate[controller].axis[CTL_R_SHOULDER] = 0; + } + + /* Debugging + Console::Print( + "Controller and handle: %i %i\n" + "Triggers:%i %i %i %i %i\n", + controller, (int)joystate[controller].joy, + joysticks[controller].triggertype, + joysticks[controller].buttons[CTL_L_SHOULDER], joysticks[controller].buttons[CTL_R_SHOULDER], joystate[controller].axis[CTL_L_SHOULDER], joystate[controller].axis[CTL_R_SHOULDER] - ); */ + ); */ ReadButton(controller, CTL_L_SHOULDER); ReadButton(controller, CTL_R_SHOULDER); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h index 1803d4c229..cf261e5ab2 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h @@ -131,7 +131,8 @@ struct CONTROLLER_MAPPING // GC PAD MAPPING int enabled; // Pad attached? int deadzone; // Deadzone... what else? int ID; // SDL joystick device ID - int controllertype; // Joystick, Joystick with no hat or a keyboard (perhaps a mouse later) + int controllertype; // Hat: Hat or custom buttons + int triggertype; // Triggers range int eventnum; // Linux Event Number, Can't be found dynamically yet }; @@ -167,12 +168,20 @@ enum CTL_START }; +// DPad Type enum { CTL_DPAD_HAT = 0, // Automatically use the first hat that SDL finds CTL_DPAD_CUSTOM // Custom directional pad settings }; +// Trigger Type +enum +{ + CTL_TRIGGER_HALF = 0, // XBox 360 + CTL_TRIGGER_WHOLE // Other pads +}; + enum { CTL_D_PAD_UP = 0, @@ -224,7 +233,7 @@ void DEBUG_INIT(); void DEBUG_QUIT(); void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus); // Rumble -u8 Pad_Convert(int _val); // Value conversion +u8 Pad_Convert(int _val, int _type = 1); // Value conversion std::vector Pad_Square_to_Circle(int _x, int _y); // Value conversion //void SaveConfig();