Refactor the network link dialogs
* Unifies the network link options into a single dialog by removing the separate dialog for the timeout option. * Cleans up the logic related to starting the network link. * Moves more options to g_owned_opts. * Separates the server and client port into 2 separate options. Test: Locally with Mario Kart with 2 instances.
This commit is contained in:
parent
86bef62faf
commit
7a76a70aed
File diff suppressed because it is too large
Load Diff
|
@ -623,7 +623,6 @@ set(
|
|||
xrc/IOViewer.xrc
|
||||
xrc/JoyPanel.xrc
|
||||
xrc/JoypadConfig.xrc
|
||||
xrc/LinkConfig.xrc
|
||||
xrc/Logging.xrc
|
||||
xrc/MainFrame.xrc
|
||||
xrc/MainIcon.xrc
|
||||
|
@ -631,6 +630,8 @@ set(
|
|||
xrc/MapViewer.xrc
|
||||
xrc/MemSelRegion.xrc
|
||||
xrc/MemViewer.xrc
|
||||
xrc/NetLinkClientPanel.xrc
|
||||
xrc/NetLinkServerPanel.xrc
|
||||
xrc/NetLink.xrc
|
||||
xrc/OAMViewer.xrc
|
||||
xrc/PaletteViewer.xrc
|
||||
|
@ -768,6 +769,7 @@ set(
|
|||
dialogs/directories-config.cpp
|
||||
dialogs/display-config.cpp
|
||||
dialogs/game-boy-config.cpp
|
||||
dialogs/net-link.cpp
|
||||
widgets/group-check-box.cpp
|
||||
widgets/keep-on-top-styler.cpp
|
||||
widgets/keyedit.cpp
|
||||
|
@ -817,6 +819,7 @@ set(
|
|||
dialogs/directories-config.h
|
||||
dialogs/display-config.h
|
||||
dialogs/game-boy-config.h
|
||||
dialogs/net-link.h
|
||||
dialogs/validated-child.h
|
||||
widgets/dpi-support.h
|
||||
widgets/group-check-box.h
|
||||
|
|
|
@ -3032,8 +3032,7 @@ EVT_HANDLER_MASK(LanLink, "Start Network link", CMDEN_LINK_ANY)
|
|||
return;
|
||||
}
|
||||
|
||||
wxDialog* dlg = GetXRCDialog("NetLink");
|
||||
ShowModal(dlg);
|
||||
ShowModal(GetXRCDialog("NetLink"));
|
||||
panel->SetFrameTitle();
|
||||
#endif
|
||||
}
|
||||
|
@ -3075,21 +3074,8 @@ EVT_HANDLER(SpeedOn, "Enable faster network protocol by default")
|
|||
|
||||
EVT_HANDLER(LinkProto, "Local host IPC")
|
||||
{
|
||||
GetMenuOptionConfig("LinkProto", config::OptionID::kGBALinkHost);
|
||||
}
|
||||
|
||||
EVT_HANDLER(LinkConfigure, "Link options...")
|
||||
{
|
||||
#ifndef NO_LINK
|
||||
wxDialog* dlg = GetXRCDialog("LinkConfig");
|
||||
|
||||
if (ShowModal(dlg) != wxID_OK)
|
||||
return;
|
||||
|
||||
SetLinkTimeout(gopts.link_timeout);
|
||||
update_opts();
|
||||
GetMenuOptionConfig("LinkProto", config::OptionID::kGBALinkProto);
|
||||
EnableNetworkMenu();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Dummy for disabling system key bindings
|
||||
|
|
|
@ -177,7 +177,12 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
bool gba_lcd_filter = false;
|
||||
bool link_auto = false;
|
||||
bool link_hacks = true;
|
||||
wxString link_host = "127.0.0.1"; // quick fix for issues #48 and #445
|
||||
wxString server_ip = "*";
|
||||
int32_t link_port = 5738;
|
||||
int32_t server_port = 5738;
|
||||
bool link_proto = false;
|
||||
int32_t link_timeout = 500;
|
||||
wxString gba_rom_dir;
|
||||
|
||||
/// Core
|
||||
|
@ -190,6 +195,9 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
uint32_t flash_size = 0;
|
||||
int32_t frame_skip = 0;
|
||||
bool gdb_break_on_load = false;
|
||||
#ifndef NO_LINK
|
||||
int32_t link_num_players = 2;
|
||||
#endif
|
||||
bool pause_when_inactive = false;
|
||||
uint32_t show_speed = 0;
|
||||
bool show_speed_transparent = false;
|
||||
|
@ -265,11 +273,12 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
#ifndef NO_LINK
|
||||
Option(OptionID::kGBALinkAuto, &g_owned_opts.link_auto),
|
||||
Option(OptionID::kGBALinkFast, &g_owned_opts.link_hacks),
|
||||
Option(OptionID::kGBALinkHost, &gopts.link_host),
|
||||
Option(OptionID::kGBAServerIP, &gopts.server_ip),
|
||||
Option(OptionID::kGBALinkPort, &gopts.link_port, 0, 65535),
|
||||
Option(OptionID::kGBALinkHost, &g_owned_opts.link_host),
|
||||
Option(OptionID::kGBAServerIP, &g_owned_opts.server_ip),
|
||||
Option(OptionID::kGBALinkPort, &g_owned_opts.link_port, 0, 65535),
|
||||
Option(OptionID::kGBAServerPort, &g_owned_opts.server_port, 0, 65535),
|
||||
Option(OptionID::kGBALinkProto, &g_owned_opts.link_proto),
|
||||
Option(OptionID::kGBALinkTimeout, &gopts.link_timeout, 0, 9999999),
|
||||
Option(OptionID::kGBALinkTimeout, &g_owned_opts.link_timeout, 0, 9999999),
|
||||
Option(OptionID::kGBALinkType, &gopts.gba_link_type, 0, 5),
|
||||
#endif
|
||||
Option(OptionID::kGBAROMDir, &g_owned_opts.gba_rom_dir),
|
||||
|
@ -311,7 +320,7 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
Option(OptionID::kPrefGDBBreakOnLoad, &g_owned_opts.gdb_break_on_load),
|
||||
Option(OptionID::kPrefGDBPort, &gopts.gdb_port, 0, 65535),
|
||||
#ifndef NO_LINK
|
||||
Option(OptionID::kPrefLinkNumPlayers, &gopts.link_num_players, 2, 4),
|
||||
Option(OptionID::kPrefLinkNumPlayers, &g_owned_opts.link_num_players, 2, 4),
|
||||
#endif
|
||||
Option(OptionID::kPrefMaxScale, &gopts.max_scale, 0, 100),
|
||||
Option(OptionID::kPrefPauseWhenInactive, &g_owned_opts.pause_when_inactive),
|
||||
|
@ -434,8 +443,8 @@ const std::array<OptionData, kNbOptions + 1> kAllOptionsData = {
|
|||
},
|
||||
OptionData{"GBA/LinkHost", "", _("Default network link client host")},
|
||||
OptionData{"GBA/ServerIP", "", _("Default network link server IP to bind")},
|
||||
OptionData{"GBA/LinkPort", "",
|
||||
_("Default network link port (server and client)")},
|
||||
OptionData{"GBA/LinkPort", "", _("Default network link port (client)")},
|
||||
OptionData{"GBA/ServerPort", "", _("Default network link port (server)")},
|
||||
OptionData{"GBA/LinkProto", "LinkProto", _("Default network protocol")},
|
||||
OptionData{"GBA/LinkTimeout", "LinkTimeout", _("Link timeout (ms)")},
|
||||
OptionData{"GBA/LinkType", "LinkType", _("Link cable type")},
|
||||
|
@ -571,7 +580,8 @@ const std::array<OptionData, kNbOptions + 1> kAllOptionsData = {
|
|||
"AllowJoystickBackgroundInput",
|
||||
_("Capture joy events while on background")},
|
||||
OptionData{"ui/hideMenuBar", "", _("Hide menu bar when mouse is inactive")},
|
||||
OptionData{"ui/suspendScreenSaver", "", _("Suspend screensaver when game is running")},
|
||||
OptionData{"ui/suspendScreenSaver", "",
|
||||
_("Suspend screensaver when game is running")},
|
||||
|
||||
/// Sound
|
||||
OptionData{"Sound/AudioAPI", "",
|
||||
|
|
|
@ -40,6 +40,7 @@ enum class OptionID {
|
|||
kGBALinkHost,
|
||||
kGBAServerIP,
|
||||
kGBALinkPort,
|
||||
kGBAServerPort,
|
||||
kGBALinkProto,
|
||||
kGBALinkTimeout,
|
||||
kGBALinkType,
|
||||
|
|
|
@ -43,7 +43,8 @@ static constexpr std::array<Option::Type, kNbOptions> kOptionsTypes = {
|
|||
/*kGBALinkFast*/ Option::Type::kBool,
|
||||
/*kGBALinkHost*/ Option::Type::kString,
|
||||
/*kGBAServerIP*/ Option::Type::kString,
|
||||
/*kGBALinkPort*/ Option::Type::kUnsigned,
|
||||
/*kGBALinkPort*/ Option::Type::kInt,
|
||||
/*kGBAServerPort*/ Option::Type::kInt,
|
||||
/*kGBALinkProto*/ Option::Type::kBool,
|
||||
/*kGBALinkTimeout*/ Option::Type::kInt,
|
||||
/*kGBALinkType*/ Option::Type::kInt,
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
#include "net-link.h"
|
||||
|
||||
#if !defined(NO_LINK)
|
||||
|
||||
#include <wx/log.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/progdlg.h>
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/valnum.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
#include "../System.h"
|
||||
#include "config/option-proxy.h"
|
||||
#include "dialogs/validated-child.h"
|
||||
#include "widgets/option-validator.h"
|
||||
|
||||
namespace dialogs {
|
||||
|
||||
LinkMode GetConfiguredLinkMode() {
|
||||
switch (OPTION(kGBALinkType)) {
|
||||
case 0:
|
||||
return LINK_DISCONNECTED;
|
||||
|
||||
case 1:
|
||||
if (OPTION(kGBALinkProto))
|
||||
return LINK_CABLE_IPC;
|
||||
else
|
||||
return LINK_CABLE_SOCKET;
|
||||
|
||||
case 2:
|
||||
if (OPTION(kGBALinkProto))
|
||||
return LINK_RFU_IPC;
|
||||
else
|
||||
return LINK_RFU_SOCKET;
|
||||
|
||||
case 3:
|
||||
return LINK_GAMECUBE_DOLPHIN;
|
||||
|
||||
case 4:
|
||||
if (OPTION(kGBALinkProto))
|
||||
return LINK_GAMEBOY_IPC;
|
||||
else
|
||||
return LINK_GAMEBOY_SOCKET;
|
||||
|
||||
default:
|
||||
return LINK_DISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
NetLink* NetLink::NewInstance(wxWindow* parent) {
|
||||
assert(parent);
|
||||
return new NetLink(parent);
|
||||
}
|
||||
|
||||
NetLink::NetLink(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
|
||||
assert(wxXmlResource::Get()->LoadDialog(this, parent, "NetLink"));
|
||||
|
||||
server_panel_ = GetValidatedChild(this, "NetLinkServerPanel");
|
||||
client_panel_ = GetValidatedChild(this, "NetLinkClientPanel");
|
||||
ok_button_ = this->FindWindow(wxID_OK);
|
||||
assert(ok_button_);
|
||||
|
||||
wxWindow* server_button = GetValidatedChild(this, "Server");
|
||||
server_button->Bind(
|
||||
wxEVT_RADIOBUTTON,
|
||||
std::bind(&NetLink::OnServerSelected, this, std::placeholders::_1),
|
||||
server_button->GetId());
|
||||
wxWindow* client_button = GetValidatedChild(this, "Client");
|
||||
client_button->Bind(
|
||||
wxEVT_RADIOBUTTON,
|
||||
std::bind(&NetLink::OnClientSelected, this, std::placeholders::_1),
|
||||
client_button->GetId());
|
||||
|
||||
// Server panel.
|
||||
GetValidatedChild(this, "Link2P")
|
||||
->SetValidator(widgets::OptionIntValidator(
|
||||
config::OptionID::kPrefLinkNumPlayers, 2));
|
||||
GetValidatedChild(this, "Link3P")
|
||||
->SetValidator(widgets::OptionIntValidator(
|
||||
config::OptionID::kPrefLinkNumPlayers, 3));
|
||||
GetValidatedChild(this, "Link4P")
|
||||
->SetValidator(widgets::OptionIntValidator(
|
||||
config::OptionID::kPrefLinkNumPlayers, 4));
|
||||
GetValidatedChild(this, "ServerIP")
|
||||
->SetValidator(
|
||||
widgets::OptionStringValidator(config::OptionID::kGBAServerIP));
|
||||
GetValidatedChild(this, "ServerPort")
|
||||
->SetValidator(
|
||||
widgets::OptionSpinCtrlValidator(config::OptionID::kGBAServerPort));
|
||||
GetValidatedChild(this, "LinkTimeout")
|
||||
->SetValidator(widgets::OptionSpinCtrlValidator(
|
||||
config::OptionID::kGBALinkTimeout));
|
||||
|
||||
// Client panel.
|
||||
GetValidatedChild(this, "LinkHost")
|
||||
->SetValidator(
|
||||
widgets::OptionStringValidator(config::OptionID::kGBALinkHost));
|
||||
GetValidatedChild(this, "LinkPort")
|
||||
->SetValidator(
|
||||
widgets::OptionSpinCtrlValidator(config::OptionID::kGBALinkPort));
|
||||
|
||||
// This should intercept wxID_OK before the dialog handler gets it.
|
||||
ok_button_->Bind(
|
||||
wxEVT_BUTTON,
|
||||
std::bind(&NetLink::OnValidate, this, std::placeholders::_1),
|
||||
ok_button_->GetId());
|
||||
|
||||
this->Fit();
|
||||
}
|
||||
|
||||
void NetLink::OnServerSelected(wxCommandEvent& event) {
|
||||
server_panel_->Enable(true);
|
||||
client_panel_->Enable(false);
|
||||
ok_button_->SetLabel(_("Start!"));
|
||||
|
||||
// Let the event propagate.
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void NetLink::OnClientSelected(wxCommandEvent& event) {
|
||||
server_panel_->Enable(false);
|
||||
client_panel_->Enable(true);
|
||||
ok_button_->SetLabel(_("Connect"));
|
||||
|
||||
// Let the event propagate.
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void NetLink::OnValidate(wxCommandEvent& event) {
|
||||
static const int kHostLength = 256;
|
||||
if (!Validate() || !TransferDataFromWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_server_mode = server_panel_->IsEnabled();
|
||||
if (!is_server_mode) {
|
||||
const bool valid =
|
||||
SetLinkServerHost(OPTION(kGBALinkHost).Get().utf8_str());
|
||||
if (!valid) {
|
||||
wxMessageBox(_("You must enter a valid host name"),
|
||||
_("Host name invalid"), wxICON_ERROR | wxOK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Close any previous link.
|
||||
CloseLink();
|
||||
wxString connection_message;
|
||||
wxString title;
|
||||
SetLinkTimeout(OPTION(kGBALinkTimeout));
|
||||
EnableSpeedHacks(OPTION(kGBALinkFast));
|
||||
EnableLinkServer(is_server_mode, OPTION(kPrefLinkNumPlayers) - 1);
|
||||
|
||||
if (is_server_mode) {
|
||||
// Server mode.
|
||||
IP_LINK_PORT = OPTION(kGBAServerPort);
|
||||
IP_LINK_BIND_ADDRESS = OPTION(kGBAServerIP).Get();
|
||||
|
||||
std::array<char, kHostLength> host;
|
||||
GetLinkServerHost(host.data(), kHostLength);
|
||||
title.Printf(_("Waiting for clients..."));
|
||||
connection_message.Printf(_("Server IP address is: %s\n"),
|
||||
wxString(host.data(), wxConvLibc).c_str());
|
||||
} else {
|
||||
// Client mode.
|
||||
title.Printf(_("Waiting for connection..."));
|
||||
connection_message.Printf(_("Connecting to %s\n"), OPTION(kGBALinkHost).Get());
|
||||
}
|
||||
|
||||
ConnectionState state = InitLink(GetConfiguredLinkMode());
|
||||
|
||||
// Display a progress dialog while the connection is establishing
|
||||
if (state == LINK_NEEDS_UPDATE) {
|
||||
wxProgressDialog pdlg(
|
||||
title, connection_message, 100, this,
|
||||
wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME);
|
||||
|
||||
while (state == LINK_NEEDS_UPDATE) {
|
||||
// Ask the core for updates
|
||||
std::array<char, kHostLength> message;
|
||||
state = ConnectLinkUpdate(message.data(), kHostLength);
|
||||
connection_message = wxString(message.data(), wxConvLibc);
|
||||
|
||||
// Does the user want to abort?
|
||||
if (!pdlg.Pulse(connection_message)) {
|
||||
state = LINK_ABORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The user cancelled the connection attempt.
|
||||
if (state == LINK_ABORT) {
|
||||
CloseLink();
|
||||
}
|
||||
|
||||
// Something failed during init.
|
||||
if (state == LINK_ERROR) {
|
||||
CloseLink();
|
||||
wxLogError(_("Error occurred.\nPlease try again."));
|
||||
}
|
||||
|
||||
if (GetLinkMode() != LINK_DISCONNECTED) {
|
||||
connection_message.Replace("\n", " ");
|
||||
systemScreenMessage(connection_message);
|
||||
event.Skip(); // all OK
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
||||
|
||||
#endif // !defined(NO_LINK)
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef VBAM_WX_DIALOGS_NET_LINK_H_
|
||||
#define VBAM_WX_DIALOGS_NET_LINK_H_
|
||||
|
||||
#if !defined(NO_LINK)
|
||||
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#include "../gba/GBALink.h"
|
||||
#include "widgets/keep-on-top-styler.h"
|
||||
|
||||
namespace dialogs {
|
||||
|
||||
// Helper function to get the current LinkMode.
|
||||
LinkMode GetConfiguredLinkMode();
|
||||
|
||||
// Manages the Network Link dialog.
|
||||
class NetLink : public wxDialog {
|
||||
public:
|
||||
static NetLink* NewInstance(wxWindow* parent);
|
||||
~NetLink() 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.
|
||||
NetLink(wxWindow* parent);
|
||||
|
||||
// Modifies the dialog when the server option is selected.
|
||||
void OnServerSelected(wxCommandEvent& event);
|
||||
|
||||
// Modifies the dialog when the client option is selected.
|
||||
void OnClientSelected(wxCommandEvent& event);
|
||||
|
||||
// Custom validation for this dialog.
|
||||
void OnValidate(wxCommandEvent& event);
|
||||
|
||||
wxWindow* server_panel_;
|
||||
wxWindow* client_panel_;
|
||||
wxWindow* ok_button_;
|
||||
const widgets::KeepOnTopStyler keep_on_top_styler_;
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
||||
#endif // !defined(NO_LINK)
|
||||
|
||||
#endif // VBAM_WX_DIALOGS_NET_LINK_H_
|
|
@ -34,6 +34,10 @@
|
|||
#include "opts.h"
|
||||
#include "widgets/option-validator.h"
|
||||
|
||||
#ifndef NO_LINK
|
||||
#include "dialogs/net-link.h"
|
||||
#endif
|
||||
|
||||
#if defined(__WXGTK__)
|
||||
#include "wayland.h"
|
||||
#endif
|
||||
|
@ -70,126 +74,6 @@ const
|
|||
|
||||
// Event handlers must be methods of wxEvtHandler-derived objects
|
||||
|
||||
// manage the network link dialog
|
||||
#ifndef NO_LINK
|
||||
static class NetLink_t : public wxEvtHandler {
|
||||
public:
|
||||
wxDialog* dlg;
|
||||
int n_players;
|
||||
bool server;
|
||||
NetLink_t()
|
||||
: n_players(2)
|
||||
, server(false)
|
||||
{
|
||||
}
|
||||
wxButton* okb;
|
||||
void ServerOKButton(wxCommandEvent& ev)
|
||||
{
|
||||
(void)ev; // unused params
|
||||
okb->SetLabel(_("Start!"));
|
||||
}
|
||||
void BindServerIP(wxCommandEvent& ev)
|
||||
{
|
||||
(void)ev; // unused param
|
||||
auto *tc = XRCCTRL(*dlg, "ServerIP", wxTextCtrl);
|
||||
tc->SetValidator(wxTextValidator(wxFILTER_NONE, &gopts.server_ip));
|
||||
tc->SetValue(gopts.server_ip);
|
||||
}
|
||||
void BindLinkHost(wxCommandEvent& ev)
|
||||
{
|
||||
(void)ev; // unused param
|
||||
auto *tc = XRCCTRL(*dlg, "ServerIP", wxTextCtrl);
|
||||
tc->SetValidator(wxTextValidator(wxFILTER_NONE, &gopts.link_host));
|
||||
tc->SetValue(gopts.link_host);
|
||||
}
|
||||
void ClientOKButton(wxCommandEvent& ev)
|
||||
{
|
||||
(void)ev; // unused params
|
||||
okb->SetLabel(_("Connect"));
|
||||
}
|
||||
// attached to OK, so skip when OK
|
||||
void NetConnect(wxCommandEvent& ev)
|
||||
{
|
||||
static const int length = 256;
|
||||
|
||||
if (!dlg->Validate() || !dlg->TransferDataFromWindow())
|
||||
return;
|
||||
|
||||
IP_LINK_PORT = gopts.link_port;
|
||||
IP_LINK_BIND_ADDRESS = gopts.server_ip;
|
||||
|
||||
if (!server) {
|
||||
bool valid = SetLinkServerHost(gopts.link_host.utf8_str());
|
||||
|
||||
if (!valid) {
|
||||
wxMessageBox(_("You must enter a valid host name"),
|
||||
_("Host name invalid"), wxICON_ERROR | wxOK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gopts.link_num_players = n_players;
|
||||
update_opts(); // save fast flag and client host
|
||||
// Close any previous link
|
||||
CloseLink();
|
||||
wxString connmsg;
|
||||
wxString title;
|
||||
SetLinkTimeout(gopts.link_timeout);
|
||||
EnableSpeedHacks(OPTION(kGBALinkFast));
|
||||
EnableLinkServer(server, gopts.link_num_players - 1);
|
||||
|
||||
if (server) {
|
||||
char host[length];
|
||||
GetLinkServerHost(host, length);
|
||||
title.Printf(_("Waiting for clients..."));
|
||||
connmsg.Printf(_("Server IP address is: %s\n"), wxString(host, wxConvLibc).c_str());
|
||||
} else {
|
||||
title.Printf(_("Waiting for connection..."));
|
||||
connmsg.Printf(_("Connecting to %s\n"), gopts.link_host.c_str());
|
||||
}
|
||||
|
||||
// Init link
|
||||
MainFrame* mf = wxGetApp().frame;
|
||||
ConnectionState state = InitLink(mf->GetConfiguredLinkMode());
|
||||
|
||||
// Display a progress dialog while the connection is establishing
|
||||
if (state == LINK_NEEDS_UPDATE) {
|
||||
wxProgressDialog pdlg(title, connmsg,
|
||||
100, dlg, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME);
|
||||
|
||||
while (state == LINK_NEEDS_UPDATE) {
|
||||
// Ask the core for updates
|
||||
char message[length];
|
||||
state = ConnectLinkUpdate(message, length);
|
||||
connmsg = wxString(message, wxConvLibc);
|
||||
|
||||
// Does the user want to abort?
|
||||
if (!pdlg.Pulse(connmsg)) {
|
||||
state = LINK_ABORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The user canceled the connection attempt
|
||||
if (state == LINK_ABORT) {
|
||||
CloseLink();
|
||||
}
|
||||
|
||||
// Something failed during init
|
||||
if (state == LINK_ERROR) {
|
||||
CloseLink();
|
||||
wxLogError(_("Error occurred.\nPlease try again."));
|
||||
}
|
||||
|
||||
if (GetLinkMode() != LINK_DISCONNECTED) {
|
||||
connmsg.Replace(wxT("\n"), wxT(" "));
|
||||
systemScreenMessage(connmsg);
|
||||
ev.Skip(); // all OK
|
||||
}
|
||||
}
|
||||
} net_link_handler;
|
||||
#endif
|
||||
|
||||
// manage the cheat list dialog
|
||||
static class CheatList_t : public wxEvtHandler {
|
||||
public:
|
||||
|
@ -2528,7 +2412,7 @@ bool MainFrame::BindControls()
|
|||
#endif
|
||||
#ifdef NO_LINK
|
||||
|
||||
if (cmdtab[i].cmd_id == XRCID("LanLink") || cmdtab[i].cmd_id == XRCID("LinkType0Nothing") || cmdtab[i].cmd_id == XRCID("LinkType1Cable") || cmdtab[i].cmd_id == XRCID("LinkType2Wireless") || cmdtab[i].cmd_id == XRCID("LinkType3GameCube") || cmdtab[i].cmd_id == XRCID("LinkType4Gameboy") || cmdtab[i].cmd_id == XRCID("LinkAuto") || cmdtab[i].cmd_id == XRCID("SpeedOn") || cmdtab[i].cmd_id == XRCID("LinkProto") || cmdtab[i].cmd_id == XRCID("LinkConfigure")) {
|
||||
if (cmdtab[i].cmd_id == XRCID("LanLink") || cmdtab[i].cmd_id == XRCID("LinkType0Nothing") || cmdtab[i].cmd_id == XRCID("LinkType1Cable") || cmdtab[i].cmd_id == XRCID("LinkType2Wireless") || cmdtab[i].cmd_id == XRCID("LinkType3GameCube") || cmdtab[i].cmd_id == XRCID("LinkType4Gameboy") || cmdtab[i].cmd_id == XRCID("LinkAuto") || cmdtab[i].cmd_id == XRCID("SpeedOn") || cmdtab[i].cmd_id == XRCID("LinkProto")) {
|
||||
if (mi)
|
||||
mi->GetMenu()->Remove(mi);
|
||||
|
||||
|
@ -2819,7 +2703,7 @@ bool MainFrame::BindControls()
|
|||
d->Fit();
|
||||
//// Emulation menu
|
||||
#ifndef NO_LINK
|
||||
d = LoadXRCDialog("NetLink");
|
||||
dialogs::NetLink::NewInstance(this);
|
||||
#endif
|
||||
wxRadioButton* rb;
|
||||
#define getrbo(name, option_id, value) \
|
||||
|
@ -2833,109 +2717,12 @@ bool MainFrame::BindControls()
|
|||
rb = SafeXRCCTRL<wxRadioButton>(d, n); \
|
||||
rb->SetValidator(wxBoolIntValidator(&o, v)); \
|
||||
} while (0)
|
||||
wxBoolEnValidator* benval;
|
||||
wxBoolEnHandler* ben;
|
||||
#define getbe(n, o, cv, t, wt) \
|
||||
do { \
|
||||
cv = SafeXRCCTRL<t>(d, n); \
|
||||
cv->SetValidator(wxBoolEnValidator(&o)); \
|
||||
benval = wxStaticCast(cv->GetValidator(), wxBoolEnValidator); \
|
||||
static wxBoolEnHandler _ben; \
|
||||
ben = &_ben; \
|
||||
wx##wt##BoolEnHandlerConnect(cv, wxID_ANY, _ben); \
|
||||
} while (0)
|
||||
// brenval & friends are here just to allow yes/no radioboxes in place
|
||||
// of checkboxes. A lot of work for little benefit.
|
||||
wxBoolRevEnValidator* brenval;
|
||||
#define getbre(n, o, cv, t, wt) \
|
||||
do { \
|
||||
cv = SafeXRCCTRL<t>(d, n); \
|
||||
cv->SetValidator(wxBoolRevEnValidator(&o)); \
|
||||
brenval = wxStaticCast(cv->GetValidator(), wxBoolRevEnValidator); \
|
||||
wx##wt##BoolEnHandlerConnect(rb, wxID_ANY, *ben); \
|
||||
} while (0)
|
||||
#define addbe(n) \
|
||||
do { \
|
||||
ben->controls.push_back(n); \
|
||||
benval->controls.push_back(n); \
|
||||
} while (0)
|
||||
#define addrbe(n) \
|
||||
do { \
|
||||
addbe(n); \
|
||||
brenval->controls.push_back(n); \
|
||||
} while (0)
|
||||
#define addber(n, r) \
|
||||
do { \
|
||||
ben->controls.push_back(n); \
|
||||
ben->reverse.push_back(r); \
|
||||
benval->controls.push_back(n); \
|
||||
benval->reverse.push_back(r); \
|
||||
} while (0)
|
||||
#define addrber(n, r) \
|
||||
do { \
|
||||
addber(n, r); \
|
||||
brenval->controls.push_back(n); \
|
||||
brenval->reverse.push_back(r); \
|
||||
} while (0)
|
||||
#define getrbbe(n, o) getbe(n, o, rb, wxRadioButton, RBE)
|
||||
#define getrbbd(n, o) getbre(n, o, rb, wxRadioButton, RBD)
|
||||
wxTextCtrl* tc;
|
||||
#define gettc(n, o) \
|
||||
do { \
|
||||
tc = SafeXRCCTRL<wxTextCtrl>(d, n); \
|
||||
tc->SetValidator(wxTextValidator(wxFILTER_NONE, &o)); \
|
||||
} while (0)
|
||||
#define getutc(n, o) \
|
||||
do { \
|
||||
tc = SafeXRCCTRL<wxTextCtrl>(d, n); \
|
||||
tc->SetValidator(wxUIntValidator(&o)); \
|
||||
} while (0)
|
||||
#ifndef NO_LINK
|
||||
{
|
||||
net_link_handler.dlg = d;
|
||||
net_link_handler.n_players = gopts.link_num_players;
|
||||
getrbbe("Server", net_link_handler.server);
|
||||
getrbbd("Client", net_link_handler.server);
|
||||
getlab("PlayersLab");
|
||||
addrber(lab, false);
|
||||
getrbi("Link2P", net_link_handler.n_players, 2);
|
||||
addrber(rb, false);
|
||||
getrbi("Link3P", net_link_handler.n_players, 3);
|
||||
addrber(rb, false);
|
||||
getrbi("Link4P", net_link_handler.n_players, 4);
|
||||
addrber(rb, false);
|
||||
getlab("ServerIPLab");
|
||||
gettc("ServerIP", gopts.link_host);
|
||||
getutc("ServerPort", gopts.link_port);
|
||||
wxWindow* okb = d->FindWindow(wxID_OK);
|
||||
|
||||
if (okb) // may be gone if style guidlines removed it
|
||||
{
|
||||
net_link_handler.okb = wxStaticCast(okb, wxButton);
|
||||
d->Connect(XRCID("Server"), wxEVT_COMMAND_RADIOBUTTON_SELECTED,
|
||||
wxCommandEventHandler(NetLink_t::ServerOKButton),
|
||||
NULL, &net_link_handler);
|
||||
d->Connect(XRCID("Client"), wxEVT_COMMAND_RADIOBUTTON_SELECTED,
|
||||
wxCommandEventHandler(NetLink_t::ClientOKButton),
|
||||
NULL, &net_link_handler);
|
||||
}
|
||||
|
||||
// Bind server IP when the server radio button is selected.
|
||||
d->Connect(XRCID("Server"), wxEVT_COMMAND_RADIOBUTTON_SELECTED,
|
||||
wxCommandEventHandler(NetLink_t::BindServerIP),
|
||||
NULL, &net_link_handler);
|
||||
// Bind client link_host when client radio button is selected.
|
||||
d->Connect(XRCID("Client"), wxEVT_COMMAND_RADIOBUTTON_SELECTED,
|
||||
wxCommandEventHandler(NetLink_t::BindLinkHost),
|
||||
NULL, &net_link_handler);
|
||||
|
||||
// this should intercept wxID_OK before the dialog handler gets it
|
||||
d->Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(NetLink_t::NetConnect),
|
||||
NULL, &net_link_handler);
|
||||
d->Fit();
|
||||
}
|
||||
#endif
|
||||
d = LoadXRCDialog("CheatList");
|
||||
{
|
||||
cheat_list_handler.dlg = d;
|
||||
|
@ -3363,16 +3150,6 @@ bool MainFrame::BindControls()
|
|||
joyDialog->Fit();
|
||||
}
|
||||
|
||||
#ifndef NO_LINK
|
||||
d = LoadXRCDialog("LinkConfig");
|
||||
{
|
||||
getlab("LinkTimeoutLab");
|
||||
addbe(lab);
|
||||
getsc("LinkTimeout", gopts.link_timeout);
|
||||
addbe(sc);
|
||||
d->Fit();
|
||||
}
|
||||
#endif
|
||||
d = LoadXRCDialog("AccelConfig");
|
||||
{
|
||||
wxTreeCtrl* tc;
|
||||
|
@ -3504,36 +3281,31 @@ bool MainFrame::BindControls()
|
|||
}
|
||||
|
||||
#ifndef NO_LINK
|
||||
LinkMode link_mode = GetConfiguredLinkMode();
|
||||
|
||||
LinkMode link_mode = dialogs::GetConfiguredLinkMode();
|
||||
if (link_mode == LINK_GAMECUBE_DOLPHIN) {
|
||||
bool isv = !gopts.link_host.empty();
|
||||
|
||||
if (isv) {
|
||||
isv = SetLinkServerHost(gopts.link_host.utf8_str());
|
||||
}
|
||||
|
||||
if (!isv) {
|
||||
const wxString& link_host = OPTION(kGBALinkHost).Get();
|
||||
if (link_host.empty()) {
|
||||
wxLogError(_("JoyBus host invalid; disabling"));
|
||||
} else {
|
||||
if (SetLinkServerHost(link_host.utf8_str())) {
|
||||
link_mode = LINK_DISCONNECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConnectionState linkState = InitLink(link_mode);
|
||||
|
||||
if (linkState != LINK_OK) {
|
||||
if (InitLink(link_mode) != LINK_OK) {
|
||||
CloseLink();
|
||||
}
|
||||
|
||||
if (GetLinkMode() != LINK_DISCONNECTED) {
|
||||
cmd_enable |= CMDEN_LINK_ANY;
|
||||
SetLinkTimeout(gopts.link_timeout);
|
||||
SetLinkTimeout(OPTION(kGBALinkTimeout));
|
||||
EnableSpeedHacks(OPTION(kGBALinkFast));
|
||||
}
|
||||
|
||||
EnableNetworkMenu();
|
||||
#endif
|
||||
|
||||
enable_menus();
|
||||
panel->SetFrameTitle();
|
||||
// All OK; activate idle loop
|
||||
|
|
|
@ -27,11 +27,6 @@ extern struct opts_t {
|
|||
|
||||
/// GBA
|
||||
wxString gba_bios;
|
||||
// quick fix for issues #48 and #445
|
||||
wxString link_host = "127.0.0.1";
|
||||
wxString server_ip = "*";
|
||||
uint32_t link_port = 5738;
|
||||
int link_timeout = 500;
|
||||
int gba_link_type;
|
||||
|
||||
/// General
|
||||
|
@ -48,7 +43,6 @@ extern struct opts_t {
|
|||
|
||||
/// Core
|
||||
int gdb_port = 55555;
|
||||
int link_num_players = 2;
|
||||
int max_scale = 0;
|
||||
|
||||
/// Sound
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "config/option-proxy.h"
|
||||
#include "config/option.h"
|
||||
#include "config/user-input.h"
|
||||
#include "dialogs/net-link.h"
|
||||
#include "drawing.h"
|
||||
#include "filters.h"
|
||||
#include "wayland.h"
|
||||
|
@ -523,9 +524,9 @@ void GameArea::LoadGame(const wxString& name)
|
|||
|
||||
#ifndef NO_LINK
|
||||
if (OPTION(kGBALinkAuto)) {
|
||||
BootLink(mf->GetConfiguredLinkMode(), UTF8(gopts.link_host),
|
||||
gopts.link_timeout, OPTION(kGBALinkFast),
|
||||
gopts.link_num_players);
|
||||
BootLink(dialogs::GetConfiguredLinkMode(), UTF8(OPTION(kGBALinkHost)),
|
||||
OPTION(kGBALinkTimeout), OPTION(kGBALinkFast),
|
||||
OPTION(kPrefLinkNumPlayers));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <wx/choice.h>
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
namespace widgets {
|
||||
|
||||
|
@ -142,4 +143,63 @@ bool OptionChoiceValidator::WriteToOption() {
|
|||
return option()->SetUnsigned(choice->GetSelection());
|
||||
}
|
||||
|
||||
OptionIntValidator::OptionIntValidator(config::OptionID option_id,
|
||||
int32_t value)
|
||||
: OptionValidator(option_id), value_(value) {
|
||||
assert(option()->is_int());
|
||||
assert(option()->GetIntMin() <= value_);
|
||||
assert(option()->GetIntMax() >= value_);
|
||||
}
|
||||
|
||||
wxObject* OptionIntValidator::Clone() const {
|
||||
return new OptionIntValidator(option()->id(), value_);
|
||||
}
|
||||
|
||||
bool OptionIntValidator::IsWindowValueValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OptionIntValidator::WriteToWindow() {
|
||||
wxRadioButton* radio_button = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
assert(radio_button);
|
||||
radio_button->SetValue(option()->GetInt() == value_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OptionIntValidator::WriteToOption() {
|
||||
const wxRadioButton* radio_button =
|
||||
wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
assert(radio_button);
|
||||
if (radio_button->GetValue()) {
|
||||
option()->SetInt(value_);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
OptionStringValidator::OptionStringValidator(config::OptionID option_id)
|
||||
: OptionValidator(option_id) {
|
||||
assert(option()->is_string());
|
||||
}
|
||||
|
||||
wxObject* OptionStringValidator::Clone() const {
|
||||
return new OptionStringValidator(option()->id());
|
||||
}
|
||||
|
||||
bool OptionStringValidator::IsWindowValueValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OptionStringValidator::WriteToWindow() {
|
||||
wxTextCtrl* text_control = wxDynamicCast(GetWindow(), wxTextCtrl);
|
||||
assert(text_control);
|
||||
text_control->SetValue(option()->GetString());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OptionStringValidator::WriteToOption() {
|
||||
const wxTextCtrl* text_control = wxDynamicCast(GetWindow(), wxTextCtrl);
|
||||
assert(text_control);
|
||||
return option()->SetString(text_control->GetValue());
|
||||
}
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
@ -140,6 +140,42 @@ private:
|
|||
bool WriteToOption() override;
|
||||
};
|
||||
|
||||
// Validator for a wxRadioButton widget with a selected kInt Option. This will
|
||||
// keep the kInt Option and the wxRadioButton selection in sync.
|
||||
class OptionIntValidator : public OptionValidator {
|
||||
public:
|
||||
explicit OptionIntValidator(config::OptionID option_id, int32_t value);
|
||||
~OptionIntValidator() override = default;
|
||||
|
||||
// Returns a copy of the object.
|
||||
wxObject* Clone() const override;
|
||||
|
||||
private:
|
||||
// OptionValidator implementation.
|
||||
bool IsWindowValueValid() override;
|
||||
bool WriteToWindow() override;
|
||||
bool WriteToOption() override;
|
||||
|
||||
const int32_t value_;
|
||||
};
|
||||
|
||||
// Validator for a wxTextCtrl widget with a selected kString Option. This will
|
||||
// keep the kString Option and the wxTextCtrl in sync.
|
||||
class OptionStringValidator : public OptionValidator {
|
||||
public:
|
||||
explicit OptionStringValidator(config::OptionID option_id);
|
||||
~OptionStringValidator() override = default;
|
||||
|
||||
// Returns a copy of the object.
|
||||
wxObject* Clone() const override;
|
||||
|
||||
private:
|
||||
// OptionValidator implementation.
|
||||
bool IsWindowValueValid() override;
|
||||
bool WriteToWindow() override;
|
||||
bool WriteToOption() override;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
||||
#endif // VBAM_WX_WIDGETS_OPTION_VALIDATOR_H_
|
||||
|
|
|
@ -52,36 +52,6 @@ protected:
|
|||
uint32_t* uint_val;
|
||||
};
|
||||
|
||||
// boolean copy-only validator with reversed value
|
||||
// may be attached to radio button or checkbox
|
||||
class wxBoolRevValidator : public wxValidator {
|
||||
public:
|
||||
wxBoolRevValidator(bool* _vptr)
|
||||
: wxValidator()
|
||||
, vptr(_vptr)
|
||||
{
|
||||
}
|
||||
wxBoolRevValidator(const wxBoolRevValidator& v)
|
||||
: wxValidator()
|
||||
, vptr(v.vptr)
|
||||
{
|
||||
}
|
||||
wxObject* Clone() const
|
||||
{
|
||||
return new wxBoolRevValidator(vptr);
|
||||
}
|
||||
bool TransferToWindow();
|
||||
bool TransferFromWindow();
|
||||
bool Validate(wxWindow* p)
|
||||
{
|
||||
(void)p; // unused params
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool* vptr;
|
||||
};
|
||||
|
||||
// wxFilePickerCtrl/wxDirPickerCtrl copy-only vvalidator
|
||||
class wxFileDirPickerValidator : public wxValidator {
|
||||
public:
|
||||
|
@ -114,139 +84,6 @@ protected:
|
|||
wxStaticText* vlabel;
|
||||
};
|
||||
|
||||
// Copy-only validators for checkboxes and radio buttons that enables a set
|
||||
// of dependent widgets
|
||||
// Requires an event handler during run-time
|
||||
|
||||
// there's probably a standard wxWindowList or some such, but it's
|
||||
// undocumented and I prefer arrays
|
||||
typedef std::vector<wxWindow*> wxWindow_v;
|
||||
|
||||
class wxBoolEnValidator : public wxGenericValidator {
|
||||
public:
|
||||
wxBoolEnValidator(bool* vptr)
|
||||
: wxGenericValidator(vptr)
|
||||
{
|
||||
}
|
||||
wxBoolEnValidator(bool* vptr, wxWindow_v& cnt, std::vector<int> rev = std::vector<int>())
|
||||
: wxGenericValidator(vptr)
|
||||
, controls(cnt)
|
||||
, reverse(rev)
|
||||
{
|
||||
}
|
||||
wxBoolEnValidator(const wxBoolEnValidator& v)
|
||||
: wxGenericValidator(v)
|
||||
, controls(v.controls)
|
||||
, reverse(v.reverse)
|
||||
{
|
||||
}
|
||||
wxObject* Clone() const
|
||||
{
|
||||
return new wxBoolEnValidator(*this);
|
||||
}
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
};
|
||||
|
||||
class wxBoolIntEnValidator : public wxBoolIntValidator {
|
||||
public:
|
||||
wxBoolIntEnValidator(int* vptr, int val, int mask = ~0)
|
||||
: wxBoolIntValidator(vptr, val, mask)
|
||||
{
|
||||
}
|
||||
wxBoolIntEnValidator(int* vptr, int val, int mask, wxWindow_v& cnt,
|
||||
std::vector<int> rev = std::vector<int>())
|
||||
: wxBoolIntValidator(vptr, val, mask)
|
||||
, controls(cnt)
|
||||
, reverse(rev)
|
||||
{
|
||||
}
|
||||
wxBoolIntEnValidator(const wxBoolIntEnValidator& v)
|
||||
: wxBoolIntValidator(v)
|
||||
, controls(v.controls)
|
||||
, reverse(v.reverse)
|
||||
{
|
||||
}
|
||||
wxObject* Clone() const
|
||||
{
|
||||
return new wxBoolIntEnValidator(*this);
|
||||
}
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
};
|
||||
|
||||
class wxBoolRevEnValidator : public wxBoolRevValidator {
|
||||
public:
|
||||
wxBoolRevEnValidator(bool* vptr)
|
||||
: wxBoolRevValidator(vptr)
|
||||
{
|
||||
}
|
||||
wxBoolRevEnValidator(bool* vptr, wxWindow_v& cnt, std::vector<int> rev = std::vector<int>())
|
||||
: wxBoolRevValidator(vptr)
|
||||
, controls(cnt)
|
||||
, reverse(rev)
|
||||
{
|
||||
}
|
||||
wxBoolRevEnValidator(const wxBoolRevEnValidator& v)
|
||||
: wxBoolRevValidator(v)
|
||||
, controls(v.controls)
|
||||
, reverse(v.reverse)
|
||||
{
|
||||
}
|
||||
wxObject* Clone() const
|
||||
{
|
||||
return new wxBoolRevEnValidator(*this);
|
||||
}
|
||||
// set these after init, rather than in constructor
|
||||
wxWindow_v controls;
|
||||
// set reverse entries to true if disabled when checkbox checked
|
||||
// controls past the end of the reverse array are not reversed
|
||||
std::vector<int> reverse;
|
||||
// inherit validate, xferfrom from parent
|
||||
bool TransferToWindow();
|
||||
};
|
||||
|
||||
// and here's an event handler that can be attached to the widget or a parent
|
||||
// of the widget
|
||||
// It is a descendent of wxEvtHandler so its methods can be used as
|
||||
// event handlers
|
||||
class wxBoolEnHandler : public wxEvtHandler {
|
||||
public:
|
||||
wxWindow_v controls;
|
||||
std::vector<int> reverse;
|
||||
void ToggleCheck(wxCommandEvent& ev);
|
||||
void Enable(wxCommandEvent& ev);
|
||||
void Disable(wxCommandEvent& ev);
|
||||
};
|
||||
|
||||
// use this to connect to the handler of id in win to obj
|
||||
#define wxCBBoolEnHandlerConnect(win, id, obj) \
|
||||
(win)->Connect(id, \
|
||||
wxEVT_COMMAND_CHECKBOX_CLICKED, \
|
||||
wxCommandEventHandler(wxBoolEnHandler::ToggleCheck), \
|
||||
NULL, \
|
||||
&obj)
|
||||
|
||||
#define wxRBBoolEnHandlerConnect(win, id, obj, f) \
|
||||
(win)->Connect(id, \
|
||||
wxEVT_COMMAND_RADIOBUTTON_SELECTED, \
|
||||
wxCommandEventHandler(wxBoolEnHandler::f), \
|
||||
NULL, \
|
||||
&obj)
|
||||
|
||||
#define wxRBEBoolEnHandlerConnect(win, id, obj) wxRBBoolEnHandlerConnect(win, id, obj, Enable)
|
||||
#define wxRBDBoolEnHandlerConnect(win, id, obj) wxRBBoolEnHandlerConnect(win, id, obj, Disable)
|
||||
|
||||
// for wxTextValidator include lists
|
||||
extern const wxArrayString val_hexdigits, val_sigdigits, val_unsdigits;
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
// utility widgets
|
||||
#include "wx/wxmisc.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "wx/wxmisc.h"
|
||||
#include <wx/wx.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/filepicker.h>
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
bool wxBoolIntValidator::TransferToWindow()
|
||||
{
|
||||
|
@ -57,51 +60,6 @@ bool wxBoolIntValidator::TransferFromWindow()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool wxBoolRevValidator::TransferToWindow()
|
||||
{
|
||||
if (!vptr)
|
||||
return false;
|
||||
|
||||
wxCheckBox* cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
|
||||
if (cb) {
|
||||
cb->SetValue(!*vptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
wxRadioButton* rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
|
||||
if (rb) {
|
||||
rb->SetValue(!*vptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wxBoolRevValidator::TransferFromWindow()
|
||||
{
|
||||
if (!vptr)
|
||||
return false;
|
||||
|
||||
wxCheckBox* cb = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||
|
||||
if (cb)
|
||||
*vptr = !cb->GetValue();
|
||||
else {
|
||||
wxRadioButton* rb = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||
|
||||
if (rb)
|
||||
*vptr = !rb->GetValue();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <wx/filepicker.h>
|
||||
|
||||
bool wxFileDirPickerValidator::TransferToWindow()
|
||||
{
|
||||
if (!vptr)
|
||||
|
@ -148,70 +106,6 @@ bool wxFileDirPickerValidator::TransferFromWindow()
|
|||
return false;
|
||||
}
|
||||
|
||||
static void enable(wxWindow_v controls, std::vector<int> reverse, bool en)
|
||||
{
|
||||
for (size_t i = 0; i < controls.size(); i++)
|
||||
controls[i]->Enable(reverse.size() <= i || !reverse[i] ? en : !en);
|
||||
}
|
||||
|
||||
#define boolen(r) \
|
||||
do { \
|
||||
int en; \
|
||||
wxCheckBox* cb = wxDynamicCast(GetWindow(), wxCheckBox); \
|
||||
if (cb) \
|
||||
en = cb->GetValue(); \
|
||||
else { \
|
||||
wxRadioButton* rb = wxDynamicCast(GetWindow(), wxRadioButton); \
|
||||
if (!rb) \
|
||||
return false; \
|
||||
en = rb->GetValue(); \
|
||||
} \
|
||||
enable(controls, reverse, r ? !en : en); \
|
||||
return true; \
|
||||
} while (0)
|
||||
|
||||
bool wxBoolEnValidator::TransferToWindow()
|
||||
{
|
||||
if (!wxGenericValidator::TransferToWindow())
|
||||
return false;
|
||||
|
||||
boolen(false);
|
||||
}
|
||||
|
||||
bool wxBoolIntEnValidator::TransferToWindow()
|
||||
{
|
||||
if (!wxBoolIntValidator::TransferToWindow())
|
||||
return false;
|
||||
|
||||
boolen(false);
|
||||
}
|
||||
|
||||
bool wxBoolRevEnValidator::TransferToWindow()
|
||||
{
|
||||
if (!wxBoolRevValidator::TransferToWindow())
|
||||
return false;
|
||||
|
||||
boolen(true);
|
||||
}
|
||||
|
||||
void wxBoolEnHandler::ToggleCheck(wxCommandEvent& ev)
|
||||
{
|
||||
enable(controls, reverse, ev.IsChecked());
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void wxBoolEnHandler::Enable(wxCommandEvent& ev)
|
||||
{
|
||||
enable(controls, reverse, true);
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
void wxBoolEnHandler::Disable(wxCommandEvent& ev)
|
||||
{
|
||||
enable(controls, reverse, false);
|
||||
ev.Skip();
|
||||
}
|
||||
|
||||
static const wxString val_hexdigits_s[] = {
|
||||
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
|
||||
wxT("7"), wxT("8"), wxT("9"), wxT("A"), wxT("B"), wxT("C"), wxT("D"),
|
||||
|
|
|
@ -1212,49 +1212,6 @@ void MainFrame::StopModal()
|
|||
panel->Resume();
|
||||
}
|
||||
|
||||
LinkMode MainFrame::GetConfiguredLinkMode()
|
||||
{
|
||||
switch (gopts.gba_link_type) {
|
||||
case 0:
|
||||
return LINK_DISCONNECTED;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (OPTION(kGBALinkProto))
|
||||
return LINK_CABLE_IPC;
|
||||
else
|
||||
return LINK_CABLE_SOCKET;
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (OPTION(kGBALinkProto))
|
||||
return LINK_RFU_IPC;
|
||||
else
|
||||
return LINK_RFU_SOCKET;
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
return LINK_GAMECUBE_DOLPHIN;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (OPTION(kGBALinkProto))
|
||||
return LINK_GAMEBOY_IPC;
|
||||
else
|
||||
return LINK_GAMEBOY_SOCKET;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return LINK_DISCONNECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
return LINK_DISCONNECTED;
|
||||
}
|
||||
|
||||
void MainFrame::IdentifyRom()
|
||||
{
|
||||
if (!panel->rom_name.empty())
|
||||
|
|
|
@ -280,9 +280,6 @@ public:
|
|||
return focused;
|
||||
}
|
||||
|
||||
// Returns the link mode to set according to the options
|
||||
LinkMode GetConfiguredLinkMode();
|
||||
|
||||
void IdentifyRom();
|
||||
|
||||
// Start GDB listener
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<resource xmlns="http://www.wxwidgets.org/wxxrc" version="2.5.3.0">
|
||||
<object class="wxDialog" name="LinkConfig">
|
||||
<title>Link configuration</title>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<object class="wxBoxSizer">
|
||||
<object class="sizeritem">
|
||||
<object class="wxStaticText" name="LinkTimeoutLab">
|
||||
<label>Link timeout (in milliseconds)</label>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxSpinCtrl" name="LinkTimeout">
|
||||
<min>0</min>
|
||||
<max>9999999</max>
|
||||
</object>
|
||||
<option>1</option>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
</object>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxStdDialogButtonSizer">
|
||||
<object class="button">
|
||||
<object class="wxButton" name="wxID_OK"/>
|
||||
</object>
|
||||
<object class="button">
|
||||
<object class="wxButton" name="wxID_CANCEL"/>
|
||||
</object>
|
||||
</object>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</resource>
|
|
@ -306,9 +306,6 @@
|
|||
<label>_Speed hack</label>
|
||||
<checkable>1</checkable>
|
||||
</object>
|
||||
<object class="wxMenuItem" name="LinkConfigure">
|
||||
<label>_Configure...</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="wxMenu">
|
||||
<label>_Video</label>
|
||||
|
|
|
@ -5,106 +5,47 @@
|
|||
<object class="wxBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<object class="wxGridSizer">
|
||||
<object class="wxFlexGridSizer">
|
||||
<rows>2</rows>
|
||||
<cols>2</cols>
|
||||
<object class="sizeritem">
|
||||
<object class="wxRadioButton" name="Server">
|
||||
<label>Server</label>
|
||||
<style>wxRB_GROUP</style>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE</flag>
|
||||
<flag>wxALL|wxALIGN_LEFT</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton" name="Server">
|
||||
<style>wxRB_GROUP</style>
|
||||
<label>Server</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL|wxALIGN_LEFT</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton" name="Client">
|
||||
<label>Client</label>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
</object>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxFlexGridSizer">
|
||||
<object class="sizeritem">
|
||||
<object class="wxStaticText" name="PlayersLab">
|
||||
<label>Players:</label>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxGridSizer">
|
||||
<object class="sizeritem">
|
||||
<object class="wxRadioButton" name="Link2P">
|
||||
<label>2</label>
|
||||
<style>wxRB_GROUP</style>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxRadioButton" name="Link3P">
|
||||
<label>3</label>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxRadioButton" name="Link4P">
|
||||
<label>4</label>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<cols>3</cols>
|
||||
</object>
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object_ref name="NetLinkServerPanel" ref="NetLinkServerPanel" />
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxStaticText" name="ServerIPLab">
|
||||
<label>Server:</label>
|
||||
<wrap>200</wrap>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxTextCtrl" name="ServerIP"/>
|
||||
<option>1</option>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxStaticText" name="ServerPortLab">
|
||||
<label>Port:</label>
|
||||
</object>
|
||||
<flag>wxALL|wxALIGN_CENTRE_VERTICAL</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<object class="wxTextCtrl" name="ServerPort"/>
|
||||
<option>1</option>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
</object>
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object_ref name="NetLinkClientPanel" ref="NetLinkClientPanel" />
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_RIGHT|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStdDialogButtonSizer">
|
||||
<object class="button">
|
||||
<object class="wxButton" name="wxID_OK">
|
||||
<label>Connect</label>
|
||||
</object>
|
||||
<object class="wxButton" name="wxID_OK" />
|
||||
</object>
|
||||
<object class="button">
|
||||
<object class="wxButton" name="wxID_CANCEL"/>
|
||||
<object class="wxButton" name="wxID_CANCEL" />
|
||||
</object>
|
||||
</object>
|
||||
<flag>wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<resource xmlns="http://www.wxwidgets.org/wxxrc" version="2.5.3.0">
|
||||
<object class="wxPanel" name="NetLinkClientPanel">
|
||||
<object class="wxFlexGridSizer">
|
||||
<rows>2</rows>
|
||||
<cols>2</cols>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText" name="LinkHostLab">
|
||||
<label>Server:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_LEFT|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxTextCtrl" name="LinkHost"/>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText" name="LinkPortLab">
|
||||
<label>Port:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_LEFT|wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxSpinCtrl" name="LinkPort">
|
||||
<min>0</min>
|
||||
<max>65535</max>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</resource>
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<resource xmlns="http://www.wxwidgets.org/wxxrc" version="2.5.3.0">
|
||||
<object class="wxPanel" name="NetLinkServerPanel">
|
||||
<object class="wxFlexGridSizer">
|
||||
<rows>4</rows>
|
||||
<cols>2</cols>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText" name="PlayersLab">
|
||||
<label>Players:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_LEFT|wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL|wxALIGN_CENTER</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton" name="Link2P">
|
||||
<style>wxRB_GROUP</style>
|
||||
<label>2</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL|wxALIGN_CENTER</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton" name="Link3P">
|
||||
<label>3</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL|wxALIGN_CENTER</flag>
|
||||
<border>5</border>
|
||||
<object class="wxRadioButton" name="Link4P">
|
||||
<label>4</label>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText" name="ServerIPLab">
|
||||
<label>Server:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_LEFT|wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxTextCtrl" name="ServerIP" />
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText" name="ServerPortLab">
|
||||
<label>Port:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_LEFT|wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxSpinCtrl" name="ServerPort">
|
||||
<min>0</min>
|
||||
<max>65535</max>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText" name="LinkTimeoutLab">
|
||||
<label>Timeout:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<flag>wxALIGN_LEFT|wxALL|wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxSpinCtrl" name="LinkTimeout">
|
||||
<style>wxSP_ARROW_KEYS</style>
|
||||
<min>0</min>
|
||||
<max>9999999</max>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</resource>
|
Loading…
Reference in New Issue