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/IOViewer.xrc
|
||||||
xrc/JoyPanel.xrc
|
xrc/JoyPanel.xrc
|
||||||
xrc/JoypadConfig.xrc
|
xrc/JoypadConfig.xrc
|
||||||
xrc/LinkConfig.xrc
|
|
||||||
xrc/Logging.xrc
|
xrc/Logging.xrc
|
||||||
xrc/MainFrame.xrc
|
xrc/MainFrame.xrc
|
||||||
xrc/MainIcon.xrc
|
xrc/MainIcon.xrc
|
||||||
|
@ -631,6 +630,8 @@ set(
|
||||||
xrc/MapViewer.xrc
|
xrc/MapViewer.xrc
|
||||||
xrc/MemSelRegion.xrc
|
xrc/MemSelRegion.xrc
|
||||||
xrc/MemViewer.xrc
|
xrc/MemViewer.xrc
|
||||||
|
xrc/NetLinkClientPanel.xrc
|
||||||
|
xrc/NetLinkServerPanel.xrc
|
||||||
xrc/NetLink.xrc
|
xrc/NetLink.xrc
|
||||||
xrc/OAMViewer.xrc
|
xrc/OAMViewer.xrc
|
||||||
xrc/PaletteViewer.xrc
|
xrc/PaletteViewer.xrc
|
||||||
|
@ -768,6 +769,7 @@ set(
|
||||||
dialogs/directories-config.cpp
|
dialogs/directories-config.cpp
|
||||||
dialogs/display-config.cpp
|
dialogs/display-config.cpp
|
||||||
dialogs/game-boy-config.cpp
|
dialogs/game-boy-config.cpp
|
||||||
|
dialogs/net-link.cpp
|
||||||
widgets/group-check-box.cpp
|
widgets/group-check-box.cpp
|
||||||
widgets/keep-on-top-styler.cpp
|
widgets/keep-on-top-styler.cpp
|
||||||
widgets/keyedit.cpp
|
widgets/keyedit.cpp
|
||||||
|
@ -817,6 +819,7 @@ set(
|
||||||
dialogs/directories-config.h
|
dialogs/directories-config.h
|
||||||
dialogs/display-config.h
|
dialogs/display-config.h
|
||||||
dialogs/game-boy-config.h
|
dialogs/game-boy-config.h
|
||||||
|
dialogs/net-link.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
|
||||||
|
|
|
@ -3032,8 +3032,7 @@ EVT_HANDLER_MASK(LanLink, "Start Network link", CMDEN_LINK_ANY)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDialog* dlg = GetXRCDialog("NetLink");
|
ShowModal(GetXRCDialog("NetLink"));
|
||||||
ShowModal(dlg);
|
|
||||||
panel->SetFrameTitle();
|
panel->SetFrameTitle();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -3075,21 +3074,8 @@ EVT_HANDLER(SpeedOn, "Enable faster network protocol by default")
|
||||||
|
|
||||||
EVT_HANDLER(LinkProto, "Local host IPC")
|
EVT_HANDLER(LinkProto, "Local host IPC")
|
||||||
{
|
{
|
||||||
GetMenuOptionConfig("LinkProto", config::OptionID::kGBALinkHost);
|
GetMenuOptionConfig("LinkProto", config::OptionID::kGBALinkProto);
|
||||||
}
|
|
||||||
|
|
||||||
EVT_HANDLER(LinkConfigure, "Link options...")
|
|
||||||
{
|
|
||||||
#ifndef NO_LINK
|
|
||||||
wxDialog* dlg = GetXRCDialog("LinkConfig");
|
|
||||||
|
|
||||||
if (ShowModal(dlg) != wxID_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SetLinkTimeout(gopts.link_timeout);
|
|
||||||
update_opts();
|
|
||||||
EnableNetworkMenu();
|
EnableNetworkMenu();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dummy for disabling system key bindings
|
// Dummy for disabling system key bindings
|
||||||
|
|
|
@ -177,7 +177,12 @@ std::array<Option, kNbOptions>& Option::All() {
|
||||||
bool gba_lcd_filter = false;
|
bool gba_lcd_filter = false;
|
||||||
bool link_auto = false;
|
bool link_auto = false;
|
||||||
bool link_hacks = true;
|
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;
|
bool link_proto = false;
|
||||||
|
int32_t link_timeout = 500;
|
||||||
wxString gba_rom_dir;
|
wxString gba_rom_dir;
|
||||||
|
|
||||||
/// Core
|
/// Core
|
||||||
|
@ -190,6 +195,9 @@ std::array<Option, kNbOptions>& Option::All() {
|
||||||
uint32_t flash_size = 0;
|
uint32_t flash_size = 0;
|
||||||
int32_t frame_skip = 0;
|
int32_t frame_skip = 0;
|
||||||
bool gdb_break_on_load = false;
|
bool gdb_break_on_load = false;
|
||||||
|
#ifndef NO_LINK
|
||||||
|
int32_t link_num_players = 2;
|
||||||
|
#endif
|
||||||
bool pause_when_inactive = false;
|
bool pause_when_inactive = false;
|
||||||
uint32_t show_speed = 0;
|
uint32_t show_speed = 0;
|
||||||
bool show_speed_transparent = false;
|
bool show_speed_transparent = false;
|
||||||
|
@ -265,11 +273,12 @@ std::array<Option, kNbOptions>& Option::All() {
|
||||||
#ifndef NO_LINK
|
#ifndef NO_LINK
|
||||||
Option(OptionID::kGBALinkAuto, &g_owned_opts.link_auto),
|
Option(OptionID::kGBALinkAuto, &g_owned_opts.link_auto),
|
||||||
Option(OptionID::kGBALinkFast, &g_owned_opts.link_hacks),
|
Option(OptionID::kGBALinkFast, &g_owned_opts.link_hacks),
|
||||||
Option(OptionID::kGBALinkHost, &gopts.link_host),
|
Option(OptionID::kGBALinkHost, &g_owned_opts.link_host),
|
||||||
Option(OptionID::kGBAServerIP, &gopts.server_ip),
|
Option(OptionID::kGBAServerIP, &g_owned_opts.server_ip),
|
||||||
Option(OptionID::kGBALinkPort, &gopts.link_port, 0, 65535),
|
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::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),
|
Option(OptionID::kGBALinkType, &gopts.gba_link_type, 0, 5),
|
||||||
#endif
|
#endif
|
||||||
Option(OptionID::kGBAROMDir, &g_owned_opts.gba_rom_dir),
|
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::kPrefGDBBreakOnLoad, &g_owned_opts.gdb_break_on_load),
|
||||||
Option(OptionID::kPrefGDBPort, &gopts.gdb_port, 0, 65535),
|
Option(OptionID::kPrefGDBPort, &gopts.gdb_port, 0, 65535),
|
||||||
#ifndef NO_LINK
|
#ifndef NO_LINK
|
||||||
Option(OptionID::kPrefLinkNumPlayers, &gopts.link_num_players, 2, 4),
|
Option(OptionID::kPrefLinkNumPlayers, &g_owned_opts.link_num_players, 2, 4),
|
||||||
#endif
|
#endif
|
||||||
Option(OptionID::kPrefMaxScale, &gopts.max_scale, 0, 100),
|
Option(OptionID::kPrefMaxScale, &gopts.max_scale, 0, 100),
|
||||||
Option(OptionID::kPrefPauseWhenInactive, &g_owned_opts.pause_when_inactive),
|
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/LinkHost", "", _("Default network link client host")},
|
||||||
OptionData{"GBA/ServerIP", "", _("Default network link server IP to bind")},
|
OptionData{"GBA/ServerIP", "", _("Default network link server IP to bind")},
|
||||||
OptionData{"GBA/LinkPort", "",
|
OptionData{"GBA/LinkPort", "", _("Default network link port (client)")},
|
||||||
_("Default network link port (server and client)")},
|
OptionData{"GBA/ServerPort", "", _("Default network link port (server)")},
|
||||||
OptionData{"GBA/LinkProto", "LinkProto", _("Default network protocol")},
|
OptionData{"GBA/LinkProto", "LinkProto", _("Default network protocol")},
|
||||||
OptionData{"GBA/LinkTimeout", "LinkTimeout", _("Link timeout (ms)")},
|
OptionData{"GBA/LinkTimeout", "LinkTimeout", _("Link timeout (ms)")},
|
||||||
OptionData{"GBA/LinkType", "LinkType", _("Link cable type")},
|
OptionData{"GBA/LinkType", "LinkType", _("Link cable type")},
|
||||||
|
@ -571,7 +580,8 @@ const std::array<OptionData, kNbOptions + 1> kAllOptionsData = {
|
||||||
"AllowJoystickBackgroundInput",
|
"AllowJoystickBackgroundInput",
|
||||||
_("Capture joy events while on background")},
|
_("Capture joy events while on background")},
|
||||||
OptionData{"ui/hideMenuBar", "", _("Hide menu bar when mouse is inactive")},
|
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
|
/// Sound
|
||||||
OptionData{"Sound/AudioAPI", "",
|
OptionData{"Sound/AudioAPI", "",
|
||||||
|
|
|
@ -40,6 +40,7 @@ enum class OptionID {
|
||||||
kGBALinkHost,
|
kGBALinkHost,
|
||||||
kGBAServerIP,
|
kGBAServerIP,
|
||||||
kGBALinkPort,
|
kGBALinkPort,
|
||||||
|
kGBAServerPort,
|
||||||
kGBALinkProto,
|
kGBALinkProto,
|
||||||
kGBALinkTimeout,
|
kGBALinkTimeout,
|
||||||
kGBALinkType,
|
kGBALinkType,
|
||||||
|
|
|
@ -43,7 +43,8 @@ static constexpr std::array<Option::Type, kNbOptions> kOptionsTypes = {
|
||||||
/*kGBALinkFast*/ Option::Type::kBool,
|
/*kGBALinkFast*/ Option::Type::kBool,
|
||||||
/*kGBALinkHost*/ Option::Type::kString,
|
/*kGBALinkHost*/ Option::Type::kString,
|
||||||
/*kGBAServerIP*/ Option::Type::kString,
|
/*kGBAServerIP*/ Option::Type::kString,
|
||||||
/*kGBALinkPort*/ Option::Type::kUnsigned,
|
/*kGBALinkPort*/ Option::Type::kInt,
|
||||||
|
/*kGBAServerPort*/ Option::Type::kInt,
|
||||||
/*kGBALinkProto*/ Option::Type::kBool,
|
/*kGBALinkProto*/ Option::Type::kBool,
|
||||||
/*kGBALinkTimeout*/ Option::Type::kInt,
|
/*kGBALinkTimeout*/ Option::Type::kInt,
|
||||||
/*kGBALinkType*/ 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 "opts.h"
|
||||||
#include "widgets/option-validator.h"
|
#include "widgets/option-validator.h"
|
||||||
|
|
||||||
|
#ifndef NO_LINK
|
||||||
|
#include "dialogs/net-link.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__WXGTK__)
|
#if defined(__WXGTK__)
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -70,126 +74,6 @@ const
|
||||||
|
|
||||||
// Event handlers must be methods of wxEvtHandler-derived objects
|
// 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
|
// manage the cheat list dialog
|
||||||
static class CheatList_t : public wxEvtHandler {
|
static class CheatList_t : public wxEvtHandler {
|
||||||
public:
|
public:
|
||||||
|
@ -2528,7 +2412,7 @@ bool MainFrame::BindControls()
|
||||||
#endif
|
#endif
|
||||||
#ifdef NO_LINK
|
#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)
|
if (mi)
|
||||||
mi->GetMenu()->Remove(mi);
|
mi->GetMenu()->Remove(mi);
|
||||||
|
|
||||||
|
@ -2819,7 +2703,7 @@ bool MainFrame::BindControls()
|
||||||
d->Fit();
|
d->Fit();
|
||||||
//// Emulation menu
|
//// Emulation menu
|
||||||
#ifndef NO_LINK
|
#ifndef NO_LINK
|
||||||
d = LoadXRCDialog("NetLink");
|
dialogs::NetLink::NewInstance(this);
|
||||||
#endif
|
#endif
|
||||||
wxRadioButton* rb;
|
wxRadioButton* rb;
|
||||||
#define getrbo(name, option_id, value) \
|
#define getrbo(name, option_id, value) \
|
||||||
|
@ -2833,109 +2717,12 @@ bool MainFrame::BindControls()
|
||||||
rb = SafeXRCCTRL<wxRadioButton>(d, n); \
|
rb = SafeXRCCTRL<wxRadioButton>(d, n); \
|
||||||
rb->SetValidator(wxBoolIntValidator(&o, v)); \
|
rb->SetValidator(wxBoolIntValidator(&o, v)); \
|
||||||
} while (0)
|
} 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;
|
wxTextCtrl* tc;
|
||||||
#define gettc(n, o) \
|
#define gettc(n, o) \
|
||||||
do { \
|
do { \
|
||||||
tc = SafeXRCCTRL<wxTextCtrl>(d, n); \
|
tc = SafeXRCCTRL<wxTextCtrl>(d, n); \
|
||||||
tc->SetValidator(wxTextValidator(wxFILTER_NONE, &o)); \
|
tc->SetValidator(wxTextValidator(wxFILTER_NONE, &o)); \
|
||||||
} while (0)
|
} 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");
|
d = LoadXRCDialog("CheatList");
|
||||||
{
|
{
|
||||||
cheat_list_handler.dlg = d;
|
cheat_list_handler.dlg = d;
|
||||||
|
@ -3363,16 +3150,6 @@ bool MainFrame::BindControls()
|
||||||
joyDialog->Fit();
|
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");
|
d = LoadXRCDialog("AccelConfig");
|
||||||
{
|
{
|
||||||
wxTreeCtrl* tc;
|
wxTreeCtrl* tc;
|
||||||
|
@ -3504,36 +3281,31 @@ bool MainFrame::BindControls()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_LINK
|
#ifndef NO_LINK
|
||||||
LinkMode link_mode = GetConfiguredLinkMode();
|
LinkMode link_mode = dialogs::GetConfiguredLinkMode();
|
||||||
|
|
||||||
if (link_mode == LINK_GAMECUBE_DOLPHIN) {
|
if (link_mode == LINK_GAMECUBE_DOLPHIN) {
|
||||||
bool isv = !gopts.link_host.empty();
|
const wxString& link_host = OPTION(kGBALinkHost).Get();
|
||||||
|
if (link_host.empty()) {
|
||||||
if (isv) {
|
|
||||||
isv = SetLinkServerHost(gopts.link_host.utf8_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isv) {
|
|
||||||
wxLogError(_("JoyBus host invalid; disabling"));
|
wxLogError(_("JoyBus host invalid; disabling"));
|
||||||
} else {
|
} else {
|
||||||
|
if (SetLinkServerHost(link_host.utf8_str())) {
|
||||||
link_mode = LINK_DISCONNECTED;
|
link_mode = LINK_DISCONNECTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionState linkState = InitLink(link_mode);
|
if (InitLink(link_mode) != LINK_OK) {
|
||||||
|
|
||||||
if (linkState != LINK_OK) {
|
|
||||||
CloseLink();
|
CloseLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLinkMode() != LINK_DISCONNECTED) {
|
if (GetLinkMode() != LINK_DISCONNECTED) {
|
||||||
cmd_enable |= CMDEN_LINK_ANY;
|
cmd_enable |= CMDEN_LINK_ANY;
|
||||||
SetLinkTimeout(gopts.link_timeout);
|
SetLinkTimeout(OPTION(kGBALinkTimeout));
|
||||||
EnableSpeedHacks(OPTION(kGBALinkFast));
|
EnableSpeedHacks(OPTION(kGBALinkFast));
|
||||||
}
|
}
|
||||||
|
|
||||||
EnableNetworkMenu();
|
EnableNetworkMenu();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enable_menus();
|
enable_menus();
|
||||||
panel->SetFrameTitle();
|
panel->SetFrameTitle();
|
||||||
// All OK; activate idle loop
|
// All OK; activate idle loop
|
||||||
|
|
|
@ -27,11 +27,6 @@ extern struct opts_t {
|
||||||
|
|
||||||
/// GBA
|
/// GBA
|
||||||
wxString gba_bios;
|
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;
|
int gba_link_type;
|
||||||
|
|
||||||
/// General
|
/// General
|
||||||
|
@ -48,7 +43,6 @@ extern struct opts_t {
|
||||||
|
|
||||||
/// Core
|
/// Core
|
||||||
int gdb_port = 55555;
|
int gdb_port = 55555;
|
||||||
int link_num_players = 2;
|
|
||||||
int max_scale = 0;
|
int max_scale = 0;
|
||||||
|
|
||||||
/// Sound
|
/// Sound
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "config/option-proxy.h"
|
#include "config/option-proxy.h"
|
||||||
#include "config/option.h"
|
#include "config/option.h"
|
||||||
#include "config/user-input.h"
|
#include "config/user-input.h"
|
||||||
|
#include "dialogs/net-link.h"
|
||||||
#include "drawing.h"
|
#include "drawing.h"
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
@ -523,9 +524,9 @@ void GameArea::LoadGame(const wxString& name)
|
||||||
|
|
||||||
#ifndef NO_LINK
|
#ifndef NO_LINK
|
||||||
if (OPTION(kGBALinkAuto)) {
|
if (OPTION(kGBALinkAuto)) {
|
||||||
BootLink(mf->GetConfiguredLinkMode(), UTF8(gopts.link_host),
|
BootLink(dialogs::GetConfiguredLinkMode(), UTF8(OPTION(kGBALinkHost)),
|
||||||
gopts.link_timeout, OPTION(kGBALinkFast),
|
OPTION(kGBALinkTimeout), OPTION(kGBALinkFast),
|
||||||
gopts.link_num_players);
|
OPTION(kPrefLinkNumPlayers));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <wx/choice.h>
|
#include <wx/choice.h>
|
||||||
#include <wx/radiobut.h>
|
#include <wx/radiobut.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
|
@ -142,4 +143,63 @@ bool OptionChoiceValidator::WriteToOption() {
|
||||||
return option()->SetUnsigned(choice->GetSelection());
|
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
|
} // namespace widgets
|
||||||
|
|
|
@ -140,6 +140,42 @@ private:
|
||||||
bool WriteToOption() override;
|
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
|
} // namespace widgets
|
||||||
|
|
||||||
#endif // VBAM_WX_WIDGETS_OPTION_VALIDATOR_H_
|
#endif // VBAM_WX_WIDGETS_OPTION_VALIDATOR_H_
|
||||||
|
|
|
@ -52,36 +52,6 @@ protected:
|
||||||
uint32_t* uint_val;
|
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
|
// wxFilePickerCtrl/wxDirPickerCtrl copy-only vvalidator
|
||||||
class wxFileDirPickerValidator : public wxValidator {
|
class wxFileDirPickerValidator : public wxValidator {
|
||||||
public:
|
public:
|
||||||
|
@ -114,139 +84,6 @@ protected:
|
||||||
wxStaticText* vlabel;
|
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
|
// for wxTextValidator include lists
|
||||||
extern const wxArrayString val_hexdigits, val_sigdigits, val_unsdigits;
|
extern const wxArrayString val_hexdigits, val_sigdigits, val_unsdigits;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
// utility widgets
|
// utility widgets
|
||||||
|
#include "wx/wxmisc.h"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "wx/wxmisc.h"
|
#include <wx/checkbox.h>
|
||||||
#include <wx/wx.h>
|
#include <wx/filepicker.h>
|
||||||
|
#include <wx/radiobut.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
|
||||||
bool wxBoolIntValidator::TransferToWindow()
|
bool wxBoolIntValidator::TransferToWindow()
|
||||||
{
|
{
|
||||||
|
@ -57,51 +60,6 @@ bool wxBoolIntValidator::TransferFromWindow()
|
||||||
return true;
|
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()
|
bool wxFileDirPickerValidator::TransferToWindow()
|
||||||
{
|
{
|
||||||
if (!vptr)
|
if (!vptr)
|
||||||
|
@ -148,70 +106,6 @@ bool wxFileDirPickerValidator::TransferFromWindow()
|
||||||
return false;
|
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[] = {
|
static const wxString val_hexdigits_s[] = {
|
||||||
wxT("0"), wxT("1"), wxT("2"), wxT("3"), wxT("4"), wxT("5"), wxT("6"),
|
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"),
|
wxT("7"), wxT("8"), wxT("9"), wxT("A"), wxT("B"), wxT("C"), wxT("D"),
|
||||||
|
|
|
@ -1212,49 +1212,6 @@ void MainFrame::StopModal()
|
||||||
panel->Resume();
|
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()
|
void MainFrame::IdentifyRom()
|
||||||
{
|
{
|
||||||
if (!panel->rom_name.empty())
|
if (!panel->rom_name.empty())
|
||||||
|
|
|
@ -280,9 +280,6 @@ public:
|
||||||
return focused;
|
return focused;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the link mode to set according to the options
|
|
||||||
LinkMode GetConfiguredLinkMode();
|
|
||||||
|
|
||||||
void IdentifyRom();
|
void IdentifyRom();
|
||||||
|
|
||||||
// Start GDB listener
|
// 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>
|
<label>_Speed hack</label>
|
||||||
<checkable>1</checkable>
|
<checkable>1</checkable>
|
||||||
</object>
|
</object>
|
||||||
<object class="wxMenuItem" name="LinkConfigure">
|
|
||||||
<label>_Configure...</label>
|
|
||||||
</object>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="wxMenu">
|
<object class="wxMenu">
|
||||||
<label>_Video</label>
|
<label>_Video</label>
|
||||||
|
|
|
@ -5,106 +5,47 @@
|
||||||
<object class="wxBoxSizer">
|
<object class="wxBoxSizer">
|
||||||
<orient>wxVERTICAL</orient>
|
<orient>wxVERTICAL</orient>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxGridSizer">
|
<object class="wxFlexGridSizer">
|
||||||
|
<rows>2</rows>
|
||||||
|
<cols>2</cols>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxRadioButton" name="Server">
|
<flag>wxALL|wxALIGN_LEFT</flag>
|
||||||
<label>Server</label>
|
|
||||||
<style>wxRB_GROUP</style>
|
|
||||||
</object>
|
|
||||||
<flag>wxALL|wxALIGN_CENTRE</flag>
|
|
||||||
<border>5</border>
|
<border>5</border>
|
||||||
|
<object class="wxRadioButton" name="Server">
|
||||||
|
<style>wxRB_GROUP</style>
|
||||||
|
<label>Server</label>
|
||||||
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
|
<flag>wxALL|wxALIGN_LEFT</flag>
|
||||||
|
<border>5</border>
|
||||||
<object class="wxRadioButton" name="Client">
|
<object class="wxRadioButton" name="Client">
|
||||||
<label>Client</label>
|
<label>Client</label>
|
||||||
</object>
|
</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>
|
||||||
<object class="sizeritem">
|
<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>
|
<flag>wxEXPAND</flag>
|
||||||
|
<border>5</border>
|
||||||
|
<object_ref name="NetLinkServerPanel" ref="NetLinkServerPanel" />
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxStaticText" name="ServerIPLab">
|
<flag>wxEXPAND</flag>
|
||||||
<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>
|
<border>5</border>
|
||||||
|
<object_ref name="NetLinkClientPanel" ref="NetLinkClientPanel" />
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<flag>wxEXPAND</flag>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
|
<flag>wxALIGN_RIGHT|wxALL</flag>
|
||||||
|
<border>5</border>
|
||||||
<object class="wxStdDialogButtonSizer">
|
<object class="wxStdDialogButtonSizer">
|
||||||
<object class="button">
|
<object class="button">
|
||||||
<object class="wxButton" name="wxID_OK">
|
<object class="wxButton" name="wxID_OK" />
|
||||||
<label>Connect</label>
|
|
||||||
</object>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="button">
|
<object class="button">
|
||||||
<object class="wxButton" name="wxID_CANCEL"/>
|
<object class="wxButton" name="wxID_CANCEL" />
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<flag>wxALL|wxEXPAND</flag>
|
|
||||||
<border>5</border>
|
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</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