[dialogs] Move JoypadConfig to its own class.
This commit is contained in:
parent
5f421b53c0
commit
14a4b6f820
|
@ -773,6 +773,7 @@ set(
|
||||||
dialogs/game-boy-config.cpp
|
dialogs/game-boy-config.cpp
|
||||||
dialogs/game-maker.cpp
|
dialogs/game-maker.cpp
|
||||||
dialogs/gb-rom-info.cpp
|
dialogs/gb-rom-info.cpp
|
||||||
|
dialogs/joypad-config.cpp
|
||||||
widgets/group-check-box.cpp
|
widgets/group-check-box.cpp
|
||||||
widgets/keep-on-top-styler.cpp
|
widgets/keep-on-top-styler.cpp
|
||||||
widgets/option-validator.cpp
|
widgets/option-validator.cpp
|
||||||
|
@ -826,6 +827,7 @@ set(
|
||||||
dialogs/game-boy-config.h
|
dialogs/game-boy-config.h
|
||||||
dialogs/game-maker.h
|
dialogs/game-maker.h
|
||||||
dialogs/gb-rom-info.h
|
dialogs/gb-rom-info.h
|
||||||
|
dialogs/joypad-config.h
|
||||||
dialogs/validated-child.h
|
dialogs/validated-child.h
|
||||||
widgets/dpi-support.h
|
widgets/dpi-support.h
|
||||||
widgets/group-check-box.h
|
widgets/group-check-box.h
|
||||||
|
|
|
@ -2227,18 +2227,22 @@ EVT_HANDLER(EmulatorDirectories, "Directories...")
|
||||||
|
|
||||||
EVT_HANDLER(JoypadConfigure, "Joypad options...")
|
EVT_HANDLER(JoypadConfigure, "Joypad options...")
|
||||||
{
|
{
|
||||||
wxDialog* dlg = GetXRCDialog("JoypadConfig");
|
|
||||||
joy.PollAllJoysticks();
|
joy.PollAllJoysticks();
|
||||||
|
|
||||||
auto frame = wxGetApp().frame;
|
auto frame = wxGetApp().frame;
|
||||||
bool joy_timer = frame->IsJoyPollTimerRunning();
|
bool joy_timer = frame->IsJoyPollTimerRunning();
|
||||||
|
|
||||||
if (!joy_timer) frame->StartJoyPollTimer();
|
if (!joy_timer) {
|
||||||
|
frame->StartJoyPollTimer();
|
||||||
|
}
|
||||||
|
|
||||||
if (ShowModal(dlg) == wxID_OK)
|
if (ShowModal(GetXRCDialog("JoypadConfig")) == wxID_OK) {
|
||||||
update_opts();
|
update_joypad_opts();
|
||||||
|
}
|
||||||
|
|
||||||
if (!joy_timer) frame->StopJoyPollTimer();
|
if (!joy_timer) {
|
||||||
|
frame->StopJoyPollTimer();
|
||||||
|
}
|
||||||
|
|
||||||
SetJoystick();
|
SetJoystick();
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,6 +209,9 @@ std::array<Option, kNbOptions>& Option::All() {
|
||||||
bool statusbar = false;
|
bool statusbar = false;
|
||||||
uint32_t ini_version = kIniLatestVersion;
|
uint32_t ini_version = kIniLatestVersion;
|
||||||
|
|
||||||
|
/// Joypad
|
||||||
|
uint32_t default_stick = 1;
|
||||||
|
|
||||||
/// Geometry
|
/// Geometry
|
||||||
bool fullscreen = false;
|
bool fullscreen = false;
|
||||||
bool window_maximized = false;
|
bool window_maximized = false;
|
||||||
|
@ -289,7 +292,7 @@ std::array<Option, kNbOptions>& Option::All() {
|
||||||
/// Joypad
|
/// Joypad
|
||||||
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, &gopts.default_stick, 1, 4),
|
Option(OptionID::kJoyDefault, &g_owned_opts.default_stick, 1, 4),
|
||||||
|
|
||||||
/// Keyboard
|
/// Keyboard
|
||||||
Option(OptionID::kKeyboard),
|
Option(OptionID::kKeyboard),
|
||||||
|
|
|
@ -64,7 +64,7 @@ static constexpr std::array<Option::Type, kNbOptions> kOptionsTypes = {
|
||||||
/// Joypad
|
/// Joypad
|
||||||
/*kJoy*/ Option::Type::kNone,
|
/*kJoy*/ Option::Type::kNone,
|
||||||
/*kJoyAutofireThrottle*/ Option::Type::kInt,
|
/*kJoyAutofireThrottle*/ Option::Type::kInt,
|
||||||
/*kJoyDefault*/ Option::Type::kInt,
|
/*kJoyDefault*/ Option::Type::kUnsigned,
|
||||||
|
|
||||||
/// Keyboard
|
/// Keyboard
|
||||||
/*kKeyboard*/ Option::Type::kNone,
|
/*kKeyboard*/ Option::Type::kNone,
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "dialogs/joypad-config.h"
|
||||||
|
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
|
||||||
|
#include "dialogs/validated-child.h"
|
||||||
|
#include "opts.h"
|
||||||
|
#include "widgets/option-validator.h"
|
||||||
|
#include "widgets/user-input-ctrl.h"
|
||||||
|
|
||||||
|
namespace dialogs {
|
||||||
|
|
||||||
|
// static
|
||||||
|
JoypadConfig* JoypadConfig::NewInstance(wxWindow* parent) {
|
||||||
|
assert(parent);
|
||||||
|
return new JoypadConfig(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
JoypadConfig::JoypadConfig(wxWindow* parent) : wxDialog(), keep_on_top_styler_(this) {
|
||||||
|
#if !wxCHECK_VERSION(3, 1, 0)
|
||||||
|
// This needs to be set before loading any element on the window. This also
|
||||||
|
// has no effect since wx 3.1.0, where it became the default.
|
||||||
|
this->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
|
||||||
|
#endif
|
||||||
|
wxXmlResource::Get()->LoadDialog(this, parent, "JoypadConfig");
|
||||||
|
|
||||||
|
for (int joypad = 0; joypad < 4; joypad++) {
|
||||||
|
wxWindow* panel = GetValidatedChild(this, wxString::Format("joy%d", joypad + 1));
|
||||||
|
|
||||||
|
GetValidatedChild(panel, "DefaultConfig")
|
||||||
|
->SetValidator(
|
||||||
|
widgets::OptionSelectedValidator(config::OptionID::kJoyDefault, joypad + 1));
|
||||||
|
|
||||||
|
// Set up tab order so input is easy to configure. Note that there are
|
||||||
|
// two tabs for each panel, so we must check for the parent before
|
||||||
|
// setting up the tab order.
|
||||||
|
wxWindow* prev = nullptr;
|
||||||
|
wxWindow* prev_parent = nullptr;
|
||||||
|
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||||
|
const wxString game_key_name = config::GameKeyToString(game_key);
|
||||||
|
widgets::UserInputCtrl* game_key_control =
|
||||||
|
GetValidatedChild<widgets::UserInputCtrl>(panel, game_key_name);
|
||||||
|
wxWindow* current_parent = game_key_control->GetParent();
|
||||||
|
|
||||||
|
game_key_control->SetValidator(
|
||||||
|
widgets::UserInputCtrlValidator(config::GameControl(joypad, game_key)));
|
||||||
|
|
||||||
|
if (current_parent == prev_parent) {
|
||||||
|
// The first control will be skipped here, but that's fine since
|
||||||
|
// we don't care where it fits in the tab order.
|
||||||
|
assert(prev);
|
||||||
|
game_key_control->MoveAfterInTabOrder(prev);
|
||||||
|
}
|
||||||
|
prev = game_key_control;
|
||||||
|
prev_parent = current_parent;
|
||||||
|
|
||||||
|
// Bind the individual "Clear" key event.
|
||||||
|
panel->Bind(wxEVT_BUTTON, std::bind(&widgets::UserInputCtrl::Clear, game_key_control),
|
||||||
|
XRCID(wxString("Clear" + config::GameKeyToString(game_key)).c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, bind the per-joypad "Defaults" and "Clear" events.
|
||||||
|
panel->Bind(wxEVT_BUTTON, std::bind(&JoypadConfig::ResetToDefaults, this, panel),
|
||||||
|
XRCID("Defaults"));
|
||||||
|
panel->Bind(wxEVT_BUTTON, std::bind(&JoypadConfig::ClearJoypad, this, panel),
|
||||||
|
XRCID("Clear"));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->Fit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoypadConfig::ResetToDefaults(wxWindow* panel) {
|
||||||
|
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||||
|
GetValidatedChild<widgets::UserInputCtrl>(panel, config::GameKeyToString(game_key))
|
||||||
|
->SetInputs(kDefaultBindings.find(config::GameControl(0, game_key))->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JoypadConfig::ClearJoypad(wxWindow* panel) {
|
||||||
|
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
||||||
|
GetValidatedChild<widgets::UserInputCtrl>(panel, config::GameKeyToString(game_key))
|
||||||
|
->Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dialogs
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_
|
||||||
|
#define VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_
|
||||||
|
|
||||||
|
#include <wx/dialog.h>
|
||||||
|
|
||||||
|
#include "widgets/keep-on-top-styler.h"
|
||||||
|
|
||||||
|
namespace dialogs {
|
||||||
|
|
||||||
|
// Manages the Joypad configuration dialog.
|
||||||
|
class JoypadConfig : public wxDialog {
|
||||||
|
public:
|
||||||
|
static JoypadConfig* NewInstance(wxWindow* parent);
|
||||||
|
~JoypadConfig() override = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The constructor is private so initialization has to be done via the
|
||||||
|
// static method. This is because this class is destroyed when its
|
||||||
|
// owner, `parent` is destroyed. This prevents accidental deletion.
|
||||||
|
JoypadConfig(wxWindow* parent);
|
||||||
|
|
||||||
|
// Resets all Joypad controls for `panel` to defaults.
|
||||||
|
void ResetToDefaults(wxWindow* panel);
|
||||||
|
|
||||||
|
// Clears all Joypad controls.
|
||||||
|
void ClearJoypad(wxWindow* panel);
|
||||||
|
|
||||||
|
const widgets::KeepOnTopStyler keep_on_top_styler_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dialogs
|
||||||
|
|
||||||
|
#endif // VBAM_WX_DIALOGS_JOYPAD_CONFIG_H_
|
|
@ -43,6 +43,7 @@
|
||||||
#include "dialogs/display-config.h"
|
#include "dialogs/display-config.h"
|
||||||
#include "dialogs/game-boy-config.h"
|
#include "dialogs/game-boy-config.h"
|
||||||
#include "dialogs/gb-rom-info.h"
|
#include "dialogs/gb-rom-info.h"
|
||||||
|
#include "dialogs/joypad-config.h"
|
||||||
#include "opts.h"
|
#include "opts.h"
|
||||||
#include "widgets/option-validator.h"
|
#include "widgets/option-validator.h"
|
||||||
#include "widgets/user-input-ctrl.h"
|
#include "widgets/user-input-ctrl.h"
|
||||||
|
@ -1604,40 +1605,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// manage the joypad prefs' per-panel default/clear buttons
|
|
||||||
static class JoyPadConfig_t : public wxEvtHandler {
|
|
||||||
public:
|
|
||||||
wxWindow* p;
|
|
||||||
void JoypadConfigButtons(wxCommandEvent& ev)
|
|
||||||
{
|
|
||||||
bool clear = ev.GetId() == XRCID("Clear");
|
|
||||||
|
|
||||||
// For the individual clear buttons, we assume their name is
|
|
||||||
// "Clear" + control_name
|
|
||||||
// ClearUp for Up; ClearR for R etc
|
|
||||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
|
||||||
const wxString control_name = config::GameKeyToString(game_key);
|
|
||||||
widgets::UserInputCtrl* tc = XRCCTRL_D(*p, control_name, widgets::UserInputCtrl);
|
|
||||||
wxString singleClearButton("Clear" + control_name);
|
|
||||||
if (ev.GetId() == XRCID(singleClearButton.c_str())) {
|
|
||||||
tc->Clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
|
||||||
widgets::UserInputCtrl* tc =
|
|
||||||
XRCCTRL_D(*p, config::GameKeyToString(game_key), widgets::UserInputCtrl);
|
|
||||||
|
|
||||||
if (clear) {
|
|
||||||
tc->Clear();
|
|
||||||
} else {
|
|
||||||
tc->SetInputs(kDefaultBindings.find(config::GameControl(0, game_key))->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} JoyPadConfigHandler[4];
|
|
||||||
|
|
||||||
// manage throttle spinctrl/canned setting choice interaction
|
// manage throttle spinctrl/canned setting choice interaction
|
||||||
static class ThrottleCtrl_t : public wxEvtHandler {
|
static class ThrottleCtrl_t : public wxEvtHandler {
|
||||||
public:
|
public:
|
||||||
|
@ -2775,54 +2742,7 @@ bool MainFrame::BindControls()
|
||||||
d->Fit();
|
d->Fit();
|
||||||
}
|
}
|
||||||
dialogs::DirectoriesConfig::NewInstance(this);
|
dialogs::DirectoriesConfig::NewInstance(this);
|
||||||
wxDialog* joyDialog = LoadXRCropertySheetDialog("JoypadConfig");
|
dialogs::JoypadConfig::NewInstance(this);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
wxString pn;
|
|
||||||
// NOTE: wx2.9.1 behaves differently for referenced nodes
|
|
||||||
// than 2.8! Unless there is an actual child node, the ID field
|
|
||||||
// will not be overwritten. This means that there should be a
|
|
||||||
// dummy child node (e.g. position=(0,0)). If you get
|
|
||||||
// "Unable to load dialog JoypadConfig from resources", this is
|
|
||||||
// probably the reason.
|
|
||||||
pn.Printf(wxT("joy%d"), i + 1);
|
|
||||||
wxWindow* w = SafeXRCCTRL<wxWindow>(joyDialog, pn);
|
|
||||||
|
|
||||||
w->FindWindow("DefaultConfig")
|
|
||||||
->SetValidator(wxBoolIntValidator(&gopts.default_stick, i + 1));
|
|
||||||
wxWindow *prev = NULL, *prevp = NULL;
|
|
||||||
|
|
||||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
|
||||||
const wxString control_name = config::GameKeyToString(game_key);
|
|
||||||
widgets::UserInputCtrl* tc = XRCCTRL_D(*w, control_name, widgets::UserInputCtrl);
|
|
||||||
CheckThrowXRCError(tc, control_name);
|
|
||||||
wxWindow* p = tc->GetParent();
|
|
||||||
|
|
||||||
if (p == prevp)
|
|
||||||
tc->MoveAfterInTabOrder(prev);
|
|
||||||
|
|
||||||
prev = tc;
|
|
||||||
prevp = p;
|
|
||||||
tc->SetValidator(widgets::UserInputCtrlValidator(config::GameControl(i, game_key)));
|
|
||||||
}
|
|
||||||
|
|
||||||
JoyPadConfigHandler[i].p = w;
|
|
||||||
w->Connect(XRCID("Defaults"), wxEVT_COMMAND_BUTTON_CLICKED,
|
|
||||||
wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons),
|
|
||||||
NULL, &JoyPadConfigHandler[i]);
|
|
||||||
w->Connect(XRCID("Clear"), wxEVT_COMMAND_BUTTON_CLICKED,
|
|
||||||
wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons),
|
|
||||||
NULL, &JoyPadConfigHandler[i]);
|
|
||||||
for (const config::GameKey& game_key : config::kAllGameKeys) {
|
|
||||||
const wxString control_name = config::GameKeyToString(game_key);
|
|
||||||
w->Connect(XRCID(wxString("Clear" + control_name).c_str()),
|
|
||||||
wxEVT_COMMAND_BUTTON_CLICKED,
|
|
||||||
wxCommandEventHandler(JoyPadConfig_t::JoypadConfigButtons),
|
|
||||||
NULL, &JoyPadConfigHandler[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
joyDialog->Fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NO_LINK
|
#ifndef NO_LINK
|
||||||
d = LoadXRCDialog("LinkConfig");
|
d = LoadXRCDialog("LinkConfig");
|
||||||
|
|
|
@ -531,11 +531,13 @@ void load_opts(bool first_time_launch) {
|
||||||
|
|
||||||
// Note: run load_opts() first to guarantee all config opts exist
|
// Note: run load_opts() first to guarantee all config opts exist
|
||||||
void update_opts() {
|
void update_opts() {
|
||||||
wxConfigBase* cfg = wxConfigBase::Get();
|
|
||||||
|
|
||||||
for (config::Option& opt : config::Option::All()) {
|
for (config::Option& opt : config::Option::All()) {
|
||||||
SaveOption(&opt);
|
SaveOption(&opt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_joypad_opts() {
|
||||||
|
wxConfigBase* cfg = wxConfigBase::Get();
|
||||||
|
|
||||||
// For joypad, compare the UserInput sets. Since UserInput guarantees a
|
// For joypad, compare the UserInput sets. Since UserInput guarantees a
|
||||||
// certain ordering, it is possible that the user control in the panel shows
|
// certain ordering, it is possible that the user control in the panel shows
|
||||||
|
@ -551,6 +553,7 @@ void update_opts() {
|
||||||
cfg->Write(option_name, config::UserInput::SpanToConfigString(iter.second));
|
cfg->Write(option_name, config::UserInput::SpanToConfigString(iter.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game_bindings_changed) {
|
if (game_bindings_changed) {
|
||||||
config::GameControlState::Instance().OnGameBindingsChanged();
|
config::GameControlState::Instance().OnGameBindingsChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ extern struct opts_t {
|
||||||
std::map<config::GameControl, std::set<config::UserInput>>
|
std::map<config::GameControl, std::set<config::UserInput>>
|
||||||
game_control_bindings;
|
game_control_bindings;
|
||||||
int autofire_rate = 1;
|
int autofire_rate = 1;
|
||||||
int default_stick = 1;
|
|
||||||
|
|
||||||
/// Keyboard
|
/// Keyboard
|
||||||
config::Shortcuts shortcuts;
|
config::Shortcuts shortcuts;
|
||||||
|
@ -85,6 +84,8 @@ void load_opts(bool first_time_launch);
|
||||||
// call whenever opt vars change
|
// call whenever opt vars change
|
||||||
// will detect changes and write config if necessary
|
// will detect changes and write config if necessary
|
||||||
void update_opts();
|
void update_opts();
|
||||||
|
// Updates the joypad options.
|
||||||
|
void update_joypad_opts();
|
||||||
// Updates the shortcut options.
|
// Updates the shortcut options.
|
||||||
void update_shortcut_opts();
|
void update_shortcut_opts();
|
||||||
// returns true if option name correct; prints error if val invalid
|
// returns true if option name correct; prints error if val invalid
|
||||||
|
|
|
@ -334,7 +334,7 @@ bool systemReadJoypads()
|
||||||
uint32_t systemReadJoypad(int joy)
|
uint32_t systemReadJoypad(int joy)
|
||||||
{
|
{
|
||||||
if (joy < 0 || joy > 3)
|
if (joy < 0 || joy > 3)
|
||||||
joy = gopts.default_stick - 1;
|
joy = OPTION(kJoyDefault) - 1;
|
||||||
|
|
||||||
uint32_t ret = config::GameControlState::Instance().GetJoypad(joy);
|
uint32_t ret = config::GameControlState::Instance().GetJoypad(joy);
|
||||||
|
|
||||||
|
@ -772,17 +772,17 @@ void systemUpdateMotionSensor()
|
||||||
|
|
||||||
int systemGetSensorX()
|
int systemGetSensorX()
|
||||||
{
|
{
|
||||||
return sensorx[gopts.default_stick - 1];
|
return sensorx[OPTION(kJoyDefault) - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
int systemGetSensorY()
|
int systemGetSensorY()
|
||||||
{
|
{
|
||||||
return sensory[gopts.default_stick - 1];
|
return sensory[OPTION(kJoyDefault) - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
int systemGetSensorZ()
|
int systemGetSensorZ()
|
||||||
{
|
{
|
||||||
return sensorz[gopts.default_stick - 1] / 10;
|
return sensorz[OPTION(kJoyDefault) - 1] / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrintDialog : public wxEvtHandler, public wxPrintout {
|
class PrintDialog : public wxEvtHandler, public wxPrintout {
|
||||||
|
|
Loading…
Reference in New Issue