Add toggle: SDL GameController mode for joysticks

Add a toggle for SDL GameController Mode in the game key configuration
dialog, default enabled.

On check or uncheck, change the option and reinitialize joysticks, not
using GameController mode if it is disabled.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
Rafael Kitover 2024-04-02 04:20:24 +00:00
parent 8576733c0d
commit cc9a03ce48
8 changed files with 46 additions and 2 deletions

View File

@ -211,6 +211,7 @@ std::array<Option, kNbOptions>& Option::All() {
/// Joypad /// Joypad
uint32_t default_stick = 1; uint32_t default_stick = 1;
bool sdl_game_controller_mode = true;
/// Geometry /// Geometry
bool fullscreen = false; bool fullscreen = false;
@ -293,6 +294,7 @@ std::array<Option, kNbOptions>& Option::All() {
Option(OptionID::kJoy), Option(OptionID::kJoy),
Option(OptionID::kJoyAutofireThrottle, &gopts.autofire_rate, 1, 1000), Option(OptionID::kJoyAutofireThrottle, &gopts.autofire_rate, 1, 1000),
Option(OptionID::kJoyDefault, &g_owned_opts.default_stick, 1, 4), Option(OptionID::kJoyDefault, &g_owned_opts.default_stick, 1, 4),
Option(OptionID::kSDLGameControllerMode, &g_owned_opts.sdl_game_controller_mode),
/// Keyboard /// Keyboard
Option(OptionID::kKeyboard), Option(OptionID::kKeyboard),
@ -478,6 +480,8 @@ const std::array<OptionData, kNbOptions + 1> kAllOptionsData = {
_("The autofire toggle period, in frames (1/60 s)")}, _("The autofire toggle period, in frames (1/60 s)")},
OptionData{"Joypad/Default", "", OptionData{"Joypad/Default", "",
_("The number of the stick to use in single-player mode")}, _("The number of the stick to use in single-player mode")},
OptionData{"Joypad/SDLGameControllerMode", "SDLGameControllerMode",
_("Whether to enable SDL GameController mode")},
/// Keyboard /// Keyboard
OptionData{"Keyboard/*", "", OptionData{"Keyboard/*", "",

View File

@ -61,6 +61,7 @@ enum class OptionID {
kJoy, kJoy,
kJoyAutofireThrottle, kJoyAutofireThrottle,
kJoyDefault, kJoyDefault,
kSDLGameControllerMode,
/// Keyboard /// Keyboard
kKeyboard, kKeyboard,

View File

@ -65,6 +65,7 @@ static constexpr std::array<Option::Type, kNbOptions> kOptionsTypes = {
/*kJoy*/ Option::Type::kNone, /*kJoy*/ Option::Type::kNone,
/*kJoyAutofireThrottle*/ Option::Type::kInt, /*kJoyAutofireThrottle*/ Option::Type::kInt,
/*kJoyDefault*/ Option::Type::kUnsigned, /*kJoyDefault*/ Option::Type::kUnsigned,
/*kSDLGameControllerMode*/ Option::Type::kBool,
/// Keyboard /// Keyboard
/*kKeyboard*/ Option::Type::kNone, /*kKeyboard*/ Option::Type::kNone,

View File

@ -3,9 +3,11 @@
#include <wx/xrc/xmlres.h> #include <wx/xrc/xmlres.h>
#include "wx/dialogs/validated-child.h" #include "wx/dialogs/validated-child.h"
#include "wx/opts.h" #include "wx/config/option-proxy.h"
#include "wx/config/option.h"
#include "wx/widgets/option-validator.h" #include "wx/widgets/option-validator.h"
#include "wx/widgets/user-input-ctrl.h" #include "wx/widgets/user-input-ctrl.h"
#include "wx/wxvbam.h"
namespace dialogs { namespace dialogs {
@ -23,6 +25,11 @@ JoypadConfig::JoypadConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(t
#endif #endif
wxXmlResource::Get()->LoadDialog(this, parent, "JoypadConfig"); wxXmlResource::Get()->LoadDialog(this, parent, "JoypadConfig");
this->Bind(wxEVT_CHECKBOX, std::bind(&JoypadConfig::ToggleSDLGameControllerMode, this),
XRCID("SDLGameControllerMode"));
GetValidatedChild<wxCheckBox>(this, "SDLGameControllerMode")->SetValue(OPTION(kSDLGameControllerMode));
for (int joypad = 0; joypad < 4; joypad++) { for (int joypad = 0; joypad < 4; joypad++) {
wxWindow* panel = GetValidatedChild(this, wxString::Format("joy%d", joypad + 1)); wxWindow* panel = GetValidatedChild(this, wxString::Format("joy%d", joypad + 1));
@ -82,4 +89,19 @@ void JoypadConfig::ClearJoypad(wxWindow* panel) {
} }
} }
void JoypadConfig::ToggleSDLGameControllerMode() {
OPTION(kSDLGameControllerMode) = GetValidatedChild<wxCheckBox>(this, "SDLGameControllerMode")
->IsChecked();
ClearAllJoypads();
wxGetApp().frame->PollAllJoysticks();
}
void JoypadConfig::ClearAllJoypads() {
for (unsigned joypad = 0; joypad < 4; joypad++) {
wxWindow* panel = GetValidatedChild(this, wxString::Format("joy%d", joypad + 1));
ClearJoypad(panel);
}
}
} // namespace dialogs } // namespace dialogs

View File

@ -25,6 +25,12 @@ private:
// Clears all Joypad controls. // Clears all Joypad controls.
void ClearJoypad(wxWindow* panel); void ClearJoypad(wxWindow* panel);
// Clears all Joypad controls for all Joypads.
void ClearAllJoypads();
// Toggle SDL GameController mode for all joysticks.
void ToggleSDLGameControllerMode();
const widgets::KeepOnTopStyler keep_on_top_styler_; const widgets::KeepOnTopStyler keep_on_top_styler_;
}; };

View File

@ -3,6 +3,8 @@
#include <wx/timer.h> #include <wx/timer.h>
#include <SDL.h> #include <SDL.h>
#include "wx/config/option-proxy.h"
#include "wx/config/option.h"
#include "wx/wxvbam.h" #include "wx/wxvbam.h"
namespace { namespace {
@ -171,7 +173,7 @@ wxSDLJoyState::wxSDLJoyState(int sdl_index)
wxSDLJoyState::wxSDLJoyState(wxJoystick joystick) : wx_joystick_(joystick) { wxSDLJoyState::wxSDLJoyState(wxJoystick joystick) : wx_joystick_(joystick) {
int sdl_index = wx_joystick_.sdl_index_; int sdl_index = wx_joystick_.sdl_index_;
if (SDL_IsGameController(sdl_index)) { if (OPTION(kSDLGameControllerMode) && SDL_IsGameController(sdl_index)) {
game_controller_ = SDL_GameControllerOpen(sdl_index); game_controller_ = SDL_GameControllerOpen(sdl_index);
if (game_controller_) if (game_controller_)
sdl_joystick_ = SDL_GameControllerGetJoystick(game_controller_); sdl_joystick_ = SDL_GameControllerGetJoystick(game_controller_);

View File

@ -314,6 +314,8 @@ public:
} }
void PollJoysticks() { joy.Poll(); } void PollJoysticks() { joy.Poll(); }
void PollAllJoysticks() { joy.PollAllJoysticks(); }
// Poll joysticks with timer. // Poll joysticks with timer.
void StartJoyPollTimer(); void StartJoyPollTimer();

View File

@ -4,6 +4,12 @@
<title>Joypad Configuration</title> <title>Joypad Configuration</title>
<object class="wxBoxSizer"> <object class="wxBoxSizer">
<orient>wxVERTICAL</orient> <orient>wxVERTICAL</orient>
<object class="sizeritem">
<flag>wxALIGN_CENTRE_HORIZONTAL</flag>
<object class="wxCheckBox" name="SDLGameControllerMode">
<label>SDL GameController Mode</label>
</object>
</object>
<object class="sizeritem"> <object class="sizeritem">
<object class="wxNotebook"> <object class="wxNotebook">
<object class="notebookpage"> <object class="notebookpage">