diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt
index da4e8856cb..5e9ea11c96 100644
--- a/Source/Core/DolphinWX/CMakeLists.txt
+++ b/Source/Core/DolphinWX/CMakeLists.txt
@@ -32,6 +32,10 @@ set(GUI_SRCS
Debugger/RegisterWindow.cpp
Debugger/WatchView.cpp
Debugger/WatchWindow.cpp
+ NetPlay/ChangeGameDialog.cpp
+ NetPlay/NetPlaySetupFrame.cpp
+ NetPlay/NetWindow.cpp
+ NetPlay/PadMapDialog.cpp
FifoPlayerDlg.cpp
Frame.cpp
FrameAui.cpp
@@ -46,7 +50,6 @@ set(GUI_SRCS
LogWindow.cpp
Main.cpp
MemcardManager.cpp
- NetWindow.cpp
PatchAddEdit.cpp
PostProcessingConfigDiag.cpp
SoftwareVideoConfigDialog.cpp
diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj b/Source/Core/DolphinWX/DolphinWX.vcxproj
index d1592b7516..f6ecb0ae14 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcxproj
+++ b/Source/Core/DolphinWX/DolphinWX.vcxproj
@@ -80,6 +80,9 @@
+
+
+
@@ -97,7 +100,7 @@
true
-
+
@@ -115,6 +118,9 @@
+
+
+
@@ -140,6 +146,7 @@
+
@@ -152,7 +159,6 @@
-
diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj.filters b/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
index 9d71b2f175..54604a1a33 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
+++ b/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
@@ -97,15 +97,15 @@
GUI\Debugger
+
+ GUI\NetPlay
+
GUI\InputConfig
GUI\InputConfig
-
- GUI\NetPlay
-
GUI\Video
@@ -190,6 +190,15 @@
GUI\Config
+
+ GUI\NetPlay
+
+
+ GUI\NetPlay
+
+
+ GUI\NetPlay
+
@@ -255,12 +264,12 @@
GUI\Debugger
+
+ GUI\NetPlay
+
GUI\InputConfig
-
- GUI\NetPlay
-
GUI\Video
@@ -345,6 +354,15 @@
GUI\Config
+
+ GUI\NetPlay
+
+
+ GUI\NetPlay
+
+
+ GUI\NetPlay
+
diff --git a/Source/Core/DolphinWX/Frame.h b/Source/Core/DolphinWX/Frame.h
index dff539f7c9..5cd026e05b 100644
--- a/Source/Core/DolphinWX/Frame.h
+++ b/Source/Core/DolphinWX/Frame.h
@@ -38,7 +38,7 @@ class CCodeWindow;
class CLogWindow;
class FifoPlayerDlg;
class LogConfigWindow;
-class NetPlaySetupDiag;
+class NetPlaySetupFrame;
class TASInputDlg;
class wxCheatsWindow;
@@ -98,7 +98,7 @@ public:
// These have to be public
CCodeWindow* g_pCodeWindow;
- NetPlaySetupDiag* g_NetPlaySetupDiag;
+ NetPlaySetupFrame* g_NetPlaySetupDiag;
wxCheatsWindow* g_CheatsWindow;
TASInputDlg* g_TASInputDlg[8];
diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp
index de41814259..5c67dc4c3d 100644
--- a/Source/Core/DolphinWX/FrameTools.cpp
+++ b/Source/Core/DolphinWX/FrameTools.cpp
@@ -75,7 +75,6 @@
#include "DolphinWX/ISOFile.h"
#include "DolphinWX/LogWindow.h"
#include "DolphinWX/MemcardManager.h"
-#include "DolphinWX/NetWindow.h"
#include "DolphinWX/TASInputDlg.h"
#include "DolphinWX/WXInputBase.h"
#include "DolphinWX/WxUtils.h"
@@ -84,6 +83,8 @@
#include "DolphinWX/Debugger/BreakpointWindow.h"
#include "DolphinWX/Debugger/CodeWindow.h"
#include "DolphinWX/Debugger/WatchWindow.h"
+#include "DolphinWX/NetPlay/NetPlaySetupFrame.h"
+#include "DolphinWX/NetPlay/NetWindow.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
@@ -1213,7 +1214,9 @@ void CFrame::DoStop()
DoRecordingSave();
if (Movie::IsMovieActive())
Movie::EndPlayInput(false);
- NetPlay::StopGame();
+
+ if (NetPlayDialog::GetNetPlayClient())
+ NetPlayDialog::GetNetPlayClient()->Stop();
BootManager::Stop();
UpdateGUI();
@@ -1450,10 +1453,10 @@ void CFrame::OnNetPlay(wxCommandEvent& WXUNUSED (event))
{
if (!g_NetPlaySetupDiag)
{
- if (NetPlayDiag::GetInstance() != nullptr)
- NetPlayDiag::GetInstance()->Raise();
+ if (NetPlayDialog::GetInstance() != nullptr)
+ NetPlayDialog::GetInstance()->Raise();
else
- g_NetPlaySetupDiag = new NetPlaySetupDiag(this, m_GameListCtrl);
+ g_NetPlaySetupDiag = new NetPlaySetupFrame(this, m_GameListCtrl);
}
else
{
diff --git a/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.cpp b/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.cpp
new file mode 100644
index 0000000000..6151cf8b98
--- /dev/null
+++ b/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.cpp
@@ -0,0 +1,37 @@
+// Copyright 2015 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include
+#include
+#include
+
+#include "DolphinWX/NetPlay/ChangeGameDialog.h"
+#include "DolphinWX/NetPlay/NetWindow.h"
+
+ChangeGameDialog::ChangeGameDialog(wxWindow* parent, const CGameListCtrl* const game_list, wxString& game_name)
+ : wxDialog(parent, wxID_ANY, _("Change Game"))
+ , m_game_name(game_name)
+{
+ m_game_lbox = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxLB_SORT);
+ m_game_lbox->Bind(wxEVT_LISTBOX_DCLICK, &ChangeGameDialog::OnPick, this);
+
+ NetPlayDialog::FillWithGameNames(m_game_lbox, *game_list);
+
+ wxButton* const ok_btn = new wxButton(this, wxID_OK, _("Change"));
+ ok_btn->Bind(wxEVT_BUTTON, &ChangeGameDialog::OnPick, this);
+
+ wxBoxSizer* const szr = new wxBoxSizer(wxVERTICAL);
+ szr->Add(m_game_lbox, 1, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 5);
+ szr->Add(ok_btn, 0, wxALL | wxALIGN_RIGHT, 5);
+
+ SetSizerAndFit(szr);
+ SetFocus();
+}
+
+void ChangeGameDialog::OnPick(wxCommandEvent& event)
+{
+ // return the selected game name
+ m_game_name = m_game_lbox->GetStringSelection();
+ EndModal(wxID_OK);
+}
diff --git a/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.h b/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.h
new file mode 100644
index 0000000000..fedfc45f17
--- /dev/null
+++ b/Source/Core/DolphinWX/NetPlay/ChangeGameDialog.h
@@ -0,0 +1,22 @@
+// Copyright 2015 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+
+class CGameListCtrl;
+class wxListBox;
+
+class ChangeGameDialog final : public wxDialog
+{
+public:
+ ChangeGameDialog(wxWindow* parent, const CGameListCtrl* const game_list, wxString& game_name);
+
+private:
+ void OnPick(wxCommandEvent& event);
+
+ wxListBox* m_game_lbox;
+ wxString& m_game_name;
+};
diff --git a/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.cpp b/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.cpp
new file mode 100644
index 0000000000..857a082ae4
--- /dev/null
+++ b/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.cpp
@@ -0,0 +1,390 @@
+// Copyright 2015 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Common/FileUtil.h"
+#include "Common/IniFile.h"
+#include "Core/NetPlayClient.h"
+#include "Core/NetPlayServer.h"
+#include "DolphinWX/Frame.h"
+#include "DolphinWX/Main.h"
+#include "DolphinWX/WxUtils.h"
+#include "DolphinWX/NetPlay/NetPlaySetupFrame.h"
+#include "DolphinWX/NetPlay/NetWindow.h"
+
+NetPlaySetupFrame::NetPlaySetupFrame(wxWindow* const parent, const CGameListCtrl* const game_list)
+ : wxFrame(parent, wxID_ANY, _("Dolphin NetPlay Setup"))
+ , m_game_list(game_list)
+{
+ IniFile inifile;
+ inifile.Load(File::GetUserPath(D_CONFIG_IDX) + "Dolphin.ini");
+ IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay");
+
+ wxPanel* const panel = new wxPanel(this);
+
+ // top row
+ wxBoxSizer* const trav_szr = new wxBoxSizer(wxHORIZONTAL);
+
+ m_direct_traversal = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(75, -1));
+ m_direct_traversal->Bind(wxEVT_CHOICE, &NetPlaySetupFrame::OnChoice, this);
+ m_direct_traversal->Append(_("Direct"));
+ m_direct_traversal->Append(_("Traversal"));
+
+ std::string travChoice;
+ netplay_section.Get("TraversalChoice", &travChoice, "direct");
+
+ if (travChoice == "traversal")
+ {
+ m_direct_traversal->Select(1);
+ }
+ else
+ {
+ m_direct_traversal->Select(0);
+ }
+
+ trav_szr->Add(m_direct_traversal, 0, wxRIGHT);
+
+ wxBoxSizer* const nick_szr = new wxBoxSizer(wxHORIZONTAL);
+ wxStaticText* const nick_lbl = new wxStaticText(panel, wxID_ANY, _("Nickname :"));
+ std::string nickname;
+ netplay_section.Get("Nickname", &nickname, "Player");
+ m_nickname_text = new wxTextCtrl(panel, wxID_ANY, StrToWxStr(nickname));
+ nick_szr->Add(nick_lbl, 0, wxCENTER);
+ nick_szr->Add(m_nickname_text, 0, wxALL, 5);
+
+ std::string centralServer;
+ netplay_section.Get("TraversalServer", ¢ralServer, "");
+ m_traversal_server_lbl = new wxStaticText(panel, wxID_ANY, _("Traversal:"));
+ m_traversal_server = new wxTextCtrl(panel, wxID_ANY, StrToWxStr(centralServer));
+ nick_szr->Add(m_traversal_server_lbl, 0, wxCENTER);
+ nick_szr->Add(m_traversal_server, 0, wxALL, 5);
+
+ std::string centralPort;
+ netplay_section.Get("TraversalPort", ¢ralPort, "");
+ m_traversal_port_lbl = new wxStaticText(panel, wxID_ANY, _("Port:"));
+ m_traversal_port = new wxTextCtrl(panel, wxID_ANY, StrToWxStr(centralPort));
+ nick_szr->Add(m_traversal_port_lbl, 0, wxCENTER);
+ nick_szr->Add(m_traversal_port, 0, wxALL, 5);
+
+ // tabs
+ wxNotebook* const notebook = new wxNotebook(panel, wxID_ANY);
+ wxPanel* const connect_tab = new wxPanel(notebook, wxID_ANY);
+ notebook->AddPage(connect_tab, _("Connect"));
+ wxPanel* const host_tab = new wxPanel(notebook, wxID_ANY);
+ notebook->AddPage(host_tab, _("Host"));
+
+ // connect tab
+ {
+ m_ip_lbl = new wxStaticText(connect_tab, wxID_ANY, _("Host Code :"));
+
+ std::string address;
+ netplay_section.Get("HostCode", &address, "00000000");
+ m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(address));
+
+ m_client_port_lbl = new wxStaticText(connect_tab, wxID_ANY, _("Port :"));
+
+ // string? w/e
+ std::string port;
+ netplay_section.Get("ConnectPort", &port, "2626");
+ m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(port));
+
+ wxButton* const connect_btn = new wxButton(connect_tab, wxID_ANY, _("Connect"));
+ connect_btn->Bind(wxEVT_BUTTON, &NetPlaySetupFrame::OnJoin, this);
+
+ wxStaticText* const alert_lbl = new wxStaticText(connect_tab, wxID_ANY,
+ _("ALERT:\n\n"
+ "Netplay will only work with the following settings:\n"
+ " - DSP Emulator Engine Must be the same on all computers!\n"
+ " - DSP on Dedicated Thread [OFF]\n"
+ " - Manually set the extensions for each Wiimote\n"
+ "\n"
+ "All players should use the same Dolphin version and settings.\n"
+ "All memory cards must be identical between players or disabled.\n"
+ "Wiimote support is probably terrible. Don't use it.\n"
+ "\n"
+ "If connecting directly host must have the chosen UDP port open/forwarded!\n"));
+
+ wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL);
+
+ top_szr->Add(m_ip_lbl, 0, wxCENTER | wxRIGHT, 5);
+ top_szr->Add(m_connect_ip_text, 3);
+ top_szr->Add(m_client_port_lbl, 0, wxCENTER | wxRIGHT | wxLEFT, 5);
+ top_szr->Add(m_connect_port_text, 1);
+
+ wxBoxSizer* const con_szr = new wxBoxSizer(wxVERTICAL);
+ con_szr->Add(top_szr, 0, wxALL | wxEXPAND, 5);
+ con_szr->AddStretchSpacer(1);
+ con_szr->Add(alert_lbl, 0, wxLEFT | wxRIGHT | wxEXPAND, 5);
+ con_szr->AddStretchSpacer(1);
+ con_szr->Add(connect_btn, 0, wxALL | wxALIGN_RIGHT, 5);
+
+ connect_tab->SetSizerAndFit(con_szr);
+ }
+
+ // host tab
+ {
+ m_host_port_lbl = new wxStaticText(host_tab, wxID_ANY, _("Port :"));
+
+ // string? w/e
+ std::string port;
+ netplay_section.Get("HostPort", &port, "2626");
+ m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, StrToWxStr(port));
+
+ wxButton* const host_btn = new wxButton(host_tab, wxID_ANY, _("Host"));
+ host_btn->Bind(wxEVT_BUTTON, &NetPlaySetupFrame::OnHost, this);
+
+ m_game_lbox = new wxListBox(host_tab, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxLB_SORT);
+ m_game_lbox->Bind(wxEVT_LISTBOX_DCLICK, &NetPlaySetupFrame::OnHost, this);
+
+ NetPlayDialog::FillWithGameNames(m_game_lbox, *game_list);
+
+ wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL);
+ top_szr->Add(m_host_port_lbl, 0, wxCENTER | wxRIGHT, 5);
+ top_szr->Add(m_host_port_text, 0);
+#ifdef USE_UPNP
+ m_upnp_chk = new wxCheckBox(host_tab, wxID_ANY, _("Forward port (UPnP)"));
+ top_szr->Add(m_upnp_chk, 0, wxALL | wxALIGN_RIGHT, 5);
+#endif
+
+ wxBoxSizer* const host_szr = new wxBoxSizer(wxVERTICAL);
+ host_szr->Add(top_szr, 0, wxALL | wxEXPAND, 5);
+ host_szr->Add(m_game_lbox, 1, wxLEFT | wxRIGHT | wxEXPAND, 5);
+ host_szr->Add(host_btn, 0, wxALL | wxALIGN_RIGHT, 5);
+
+ host_tab->SetSizerAndFit(host_szr);
+ }
+
+ // bottom row
+ wxButton* const quit_btn = new wxButton(panel, wxID_ANY, _("Quit"));
+ quit_btn->Bind(wxEVT_BUTTON, &NetPlaySetupFrame::OnQuit, this);
+
+ // main sizer
+ wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
+ main_szr->Add(trav_szr, 0, wxALL | wxALIGN_LEFT);
+ main_szr->Add(nick_szr, 0, wxALL | wxALIGN_LEFT, 5);
+ main_szr->Add(notebook, 1, wxLEFT | wxRIGHT | wxEXPAND, 5);
+ main_szr->Add(quit_btn, 0, wxALL | wxALIGN_RIGHT, 5);
+
+ panel->SetSizerAndFit(main_szr);
+
+ //wxBoxSizer* const diag_szr = new wxBoxSizer(wxVERTICAL);
+ //diag_szr->Add(panel, 1, wxEXPAND);
+ //SetSizerAndFit(diag_szr);
+
+ main_szr->SetSizeHints(this);
+
+ Center();
+ Show();
+
+ // Needs to be done last or it set up the spacing on the page correctly
+ wxCommandEvent ev;
+ OnChoice(ev);
+}
+
+NetPlaySetupFrame::~NetPlaySetupFrame()
+{
+ IniFile inifile;
+ const std::string dolphin_ini = File::GetUserPath(D_CONFIG_IDX) + "Dolphin.ini";
+ inifile.Load(dolphin_ini);
+ IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay");
+
+ std::string travChoice = "traversal";
+ if (m_direct_traversal->GetSelection() == 1)
+ {
+ netplay_section.Set("TraversalChoice", travChoice);
+ }
+ else
+ {
+ travChoice = "direct";
+ netplay_section.Set("TraversalChoice", travChoice);
+ }
+
+ netplay_section.Set("Nickname", WxStrToStr(m_nickname_text->GetValue()));
+ netplay_section.Set("TraversalServer", WxStrToStr(m_traversal_server->GetValue()));
+ netplay_section.Set("TraversalPort", WxStrToStr(m_traversal_port->GetValue()));
+
+ if (m_direct_traversal->GetCurrentSelection() == 0)
+ {
+ netplay_section.Set("Address", WxStrToStr(m_connect_ip_text->GetValue()));
+ }
+ else
+ {
+ netplay_section.Set("HostCode", WxStrToStr(m_connect_ip_text->GetValue()));
+ }
+ netplay_section.Set("ConnectPort", WxStrToStr(m_connect_port_text->GetValue()));
+ netplay_section.Set("HostPort", WxStrToStr(m_host_port_text->GetValue()));
+
+ inifile.Save(dolphin_ini);
+ main_frame->g_NetPlaySetupDiag = nullptr;
+}
+
+void NetPlaySetupFrame::MakeNetPlayDiag(int port, const std::string &game, bool is_hosting)
+{
+ NetPlayDialog*& npd = NetPlayDialog::GetInstance();
+ NetPlayClient*& netplay_client = NetPlayDialog::GetNetPlayClient();
+
+ std::string ip;
+ npd = new NetPlayDialog(m_parent, m_game_list, game, is_hosting);
+ if (is_hosting)
+ ip = "127.0.0.1";
+ else
+ ip = WxStrToStr(m_connect_ip_text->GetValue());
+
+ bool trav;
+ if (!is_hosting && m_direct_traversal->GetCurrentSelection() == 1)
+ trav = true;
+ else
+ trav = false;
+
+ unsigned long centralPort = 0;
+ m_traversal_port->GetValue().ToULong(¢ralPort);
+ netplay_client = new NetPlayClient(ip, (u16)port, npd, WxStrToStr(m_nickname_text->GetValue()), trav, WxStrToStr(m_traversal_server->GetValue()), (u16)centralPort);
+ if (netplay_client->is_connected)
+ {
+ npd->Show();
+ Destroy();
+ }
+ else
+ {
+ npd->Destroy();
+ }
+}
+
+void NetPlaySetupFrame::OnHost(wxCommandEvent&)
+{
+ NetPlayDialog*& npd = NetPlayDialog::GetInstance();
+ NetPlayServer*& netplay_server = NetPlayDialog::GetNetPlayServer();
+
+ if (npd)
+ {
+ WxUtils::ShowErrorDialog(_("A NetPlay window is already open!"));
+ return;
+ }
+
+ if (m_game_lbox->GetSelection() == wxNOT_FOUND)
+ {
+ WxUtils::ShowErrorDialog(_("You must choose a game!"));
+ return;
+ }
+
+ std::string game(WxStrToStr(m_game_lbox->GetStringSelection()));
+
+ bool trav;
+ if (m_direct_traversal->GetCurrentSelection() == 1)
+ trav = true;
+ else
+ trav = false;
+
+ unsigned long port = 0;
+ m_host_port_text->GetValue().ToULong(&port);
+
+ unsigned long centralPort = 0;
+ m_traversal_port->GetValue().ToULong(¢ralPort);
+ netplay_server = new NetPlayServer((u16)port, trav, WxStrToStr(m_traversal_server->GetValue()), (u16)centralPort);
+ if (netplay_server->is_connected)
+ {
+ netplay_server->ChangeGame(game);
+ netplay_server->AdjustPadBufferSize(INITIAL_PAD_BUFFER_SIZE);
+#ifdef USE_UPNP
+ if (m_upnp_chk->GetValue())
+ netplay_server->TryPortmapping(port);
+#endif
+ MakeNetPlayDiag(netplay_server->GetPort(), game, true);
+ netplay_server->SetNetPlayUI(NetPlayDialog::GetInstance());
+ }
+ else
+ {
+ WxUtils::ShowErrorDialog(_("Failed to listen. Is another instance of the NetPlay server running?"));
+ }
+}
+
+void NetPlaySetupFrame::OnJoin(wxCommandEvent&)
+{
+ NetPlayDialog*& npd = NetPlayDialog::GetInstance();
+ if (npd)
+ {
+ WxUtils::ShowErrorDialog(_("A NetPlay window is already open!"));
+ return;
+ }
+
+ unsigned long port = 0;
+ m_connect_port_text->GetValue().ToULong(&port);
+ MakeNetPlayDiag(port, "", false);
+}
+
+void NetPlaySetupFrame::OnChoice(wxCommandEvent& event)
+{
+ int sel = m_direct_traversal->GetSelection();
+ IniFile inifile;
+ inifile.Load(File::GetUserPath(D_CONFIG_IDX) + "Dolphin.ini");
+ IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay");
+
+ if (sel == 1)
+ {
+ m_traversal_server_lbl->Show();
+ m_traversal_server->Show();
+
+ m_traversal_port_lbl->Show();
+ m_traversal_port->Show();
+
+ //Traversal
+ //client tab
+ {
+ m_ip_lbl->SetLabelText("Host Code: ");
+
+ std::string address;
+ netplay_section.Get("HostCode", &address, "00000000");
+ m_connect_ip_text->SetLabelText(address);
+
+ m_client_port_lbl->Hide();
+ m_connect_port_text->Hide();
+ }
+
+ //server tab
+ {
+ m_host_port_lbl->Hide();
+ m_host_port_text->Hide();
+ m_upnp_chk->Hide();
+ }
+ }
+ else
+ {
+ m_traversal_server_lbl->Hide();
+ m_traversal_server->Hide();
+
+ m_traversal_port_lbl->Hide();
+ m_traversal_port->Hide();
+ // Direct
+ // Client tab
+ {
+ m_ip_lbl->SetLabelText("IP Address :");
+
+ std::string address;
+ netplay_section.Get("Address", &address, "127.0.0.1");
+ m_connect_ip_text->SetLabelText(address);
+
+ m_client_port_lbl->Show();
+ m_connect_port_text->Show();
+ }
+
+ // Server tab
+ m_host_port_lbl->Show();
+ m_host_port_text->Show();
+ m_upnp_chk->Show();
+ }
+}
+
+void NetPlaySetupFrame::OnQuit(wxCommandEvent&)
+{
+ Destroy();
+}
diff --git a/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.h b/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.h
new file mode 100644
index 0000000000..15cddb1841
--- /dev/null
+++ b/Source/Core/DolphinWX/NetPlay/NetPlaySetupFrame.h
@@ -0,0 +1,50 @@
+// Copyright 2015 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+#include
+
+class CGameListCtrl;
+class wxCheckBox;
+class wxChoice;
+class wxListBox;
+class wxStaticText;
+class wxTextCtrl;
+
+class NetPlaySetupFrame final : public wxFrame
+{
+public:
+ NetPlaySetupFrame(wxWindow* const parent, const CGameListCtrl* const game_list);
+ ~NetPlaySetupFrame();
+
+private:
+ void OnJoin(wxCommandEvent& event);
+ void OnHost(wxCommandEvent& event);
+ void OnQuit(wxCommandEvent& event);
+ void OnChoice(wxCommandEvent& event);
+
+ void MakeNetPlayDiag(int port, const std::string& game, bool is_hosting);
+
+ wxStaticText* m_ip_lbl;
+ wxStaticText* m_client_port_lbl;
+ wxTextCtrl* m_nickname_text;
+ wxStaticText* m_host_port_lbl;
+ wxTextCtrl* m_host_port_text;
+ wxTextCtrl* m_connect_port_text;
+ wxTextCtrl* m_connect_ip_text;
+ wxChoice* m_direct_traversal;
+ wxStaticText* m_traversal_server_lbl;
+ wxTextCtrl* m_traversal_server;
+ wxStaticText* m_traversal_port_lbl;
+ wxTextCtrl* m_traversal_port;
+
+ wxListBox* m_game_lbox;
+#ifdef USE_UPNP
+ wxCheckBox* m_upnp_chk;
+#endif
+
+ const CGameListCtrl* const m_game_list;
+};
diff --git a/Source/Core/DolphinWX/NetPlay/NetWindow.cpp b/Source/Core/DolphinWX/NetPlay/NetWindow.cpp
new file mode 100644
index 0000000000..febb30e570
--- /dev/null
+++ b/Source/Core/DolphinWX/NetPlay/NetWindow.cpp
@@ -0,0 +1,591 @@
+// Copyright 2013 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Common/CommonTypes.h"
+#include "Common/FifoQueue.h"
+#include "Common/FileUtil.h"
+#include "Common/IniFile.h"
+
+#include "Core/ConfigManager.h"
+#include "Core/CoreParameter.h"
+#include "Core/NetPlayClient.h"
+#include "Core/NetPlayProto.h"
+#include "Core/NetPlayServer.h"
+#include "Core/HW/EXI_Device.h"
+
+#include "DolphinWX/Frame.h"
+#include "DolphinWX/GameListCtrl.h"
+#include "DolphinWX/ISOFile.h"
+#include "DolphinWX/Main.h"
+#include "DolphinWX/WxUtils.h"
+#include "DolphinWX/NetPlay/ChangeGameDialog.h"
+#include "DolphinWX/NetPlay/NetWindow.h"
+#include "DolphinWX/NetPlay/PadMapDialog.h"
+
+NetPlayServer* NetPlayDialog::netplay_server = nullptr;
+NetPlayClient* NetPlayDialog::netplay_client = nullptr;
+NetPlayDialog *NetPlayDialog::npd = nullptr;
+
+static wxString FailureReasonStringForHostLabel(int reason)
+{
+ switch (reason)
+ {
+ case TraversalClient::BadHost:
+ return _("(Error: Bad host)");
+ case TraversalClient::VersionTooOld:
+ return _("(Error: Dolphin too old)");
+ case TraversalClient::ServerForgotAboutUs:
+ return _("(Error: Disconnected)");
+ case TraversalClient::SocketSendError:
+ return _("(Error: Socket)");
+ case TraversalClient::ResendTimeout:
+ return _("(Error: Timeout)");
+ default:
+ return _("(Error: Unknown)");
+ }
+}
+
+static std::string BuildGameName(const GameListItem& game)
+{
+ // Lang needs to be consistent
+ auto const lang = 0;
+
+ std::string name(game.GetName(lang));
+
+ if (game.GetRevision() != 0)
+ return name + " (" + game.GetUniqueID() + ", Revision " + std::to_string((long long)game.GetRevision()) + ")";
+ else
+ return name + " (" + game.GetUniqueID() + ")";
+}
+
+void NetPlayDialog::FillWithGameNames(wxListBox* game_lbox, const CGameListCtrl& game_list)
+{
+ for (u32 i = 0; auto game = game_list.GetISO(i); ++i)
+ game_lbox->Append(StrToWxStr(BuildGameName(*game)));
+}
+
+NetPlayDialog::NetPlayDialog(wxWindow* const parent, const CGameListCtrl* const game_list,
+ const std::string& game, const bool is_hosting)
+ : wxFrame(parent, wxID_ANY, _("Dolphin NetPlay"))
+ , m_selected_game(game)
+ , m_start_btn(nullptr)
+ , m_host_label(nullptr)
+ , m_host_type_choice(nullptr)
+ , m_host_copy_btn(nullptr)
+ , m_host_copy_btn_is_retry(false)
+ , m_is_hosting(is_hosting)
+ , m_game_list(game_list)
+{
+ Bind(wxEVT_THREAD, &NetPlayDialog::OnThread, this);
+
+ wxPanel* const panel = new wxPanel(this);
+
+ // top crap
+ m_game_btn = new wxButton(panel, wxID_ANY,
+ StrToWxStr(m_selected_game).Prepend(_(" Game : ")),
+ wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
+
+ if (m_is_hosting)
+ m_game_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnChangeGame, this);
+ else
+ m_game_btn->Disable();
+
+ // middle crap
+
+ // chat
+ m_chat_text = new wxTextCtrl(panel, wxID_ANY, wxEmptyString
+ , wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE);
+
+ m_chat_msg_text = new wxTextCtrl(panel, wxID_ANY, wxEmptyString
+ , wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
+ m_chat_msg_text->Bind(wxEVT_TEXT_ENTER, &NetPlayDialog::OnChat, this);
+ m_chat_msg_text->SetMaxLength(2000);
+
+ wxButton* const chat_msg_btn = new wxButton(panel, wxID_ANY, _("Send"));
+ chat_msg_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnChat, this);
+
+ wxBoxSizer* const chat_msg_szr = new wxBoxSizer(wxHORIZONTAL);
+ chat_msg_szr->Add(m_chat_msg_text, 1);
+ chat_msg_szr->Add(chat_msg_btn, 0);
+
+ wxStaticBoxSizer* const chat_szr = new wxStaticBoxSizer(wxVERTICAL, panel, _("Chat"));
+ chat_szr->Add(m_chat_text, 1, wxEXPAND);
+ chat_szr->Add(chat_msg_szr, 0, wxEXPAND | wxTOP, 5);
+
+ m_player_lbox = new wxListBox(panel, wxID_ANY, wxDefaultPosition, wxSize(256, -1));
+
+ wxStaticBoxSizer* const player_szr = new wxStaticBoxSizer(wxVERTICAL, panel, _("Players"));
+
+ // player list
+ if (m_is_hosting && g_TraversalClient)
+ {
+ wxBoxSizer* const host_szr = new wxBoxSizer(wxHORIZONTAL);
+ m_host_type_choice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(60, -1));
+ m_host_type_choice->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &NetPlayDialog::OnChoice, this);
+ m_host_type_choice->Append(_("ID:"));
+ host_szr->Add(m_host_type_choice);
+
+ m_host_label = new wxStaticText(panel, wxID_ANY, "555.555.555.555:55555", wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE | wxALIGN_LEFT);
+ // Update() should fix this immediately.
+ m_host_label->SetLabel(_(""));
+ host_szr->Add(m_host_label, 1, wxLEFT | wxCENTER, 5);
+
+ m_host_copy_btn = new wxButton(panel, wxID_ANY, _("Copy"));
+ m_host_copy_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlayDialog::OnCopyIP, this);
+ m_host_copy_btn->Disable();
+ host_szr->Add(m_host_copy_btn, 0, wxLEFT | wxCENTER, 5);
+ player_szr->Add(host_szr, 0, wxEXPAND | wxBOTTOM, 5);
+ m_host_type_choice->Select(0);
+
+ UpdateHostLabel();
+ }
+
+ player_szr->Add(m_player_lbox, 1, wxEXPAND);
+
+ if (m_is_hosting)
+ {
+ m_player_lbox->Bind(wxEVT_LISTBOX, &NetPlayDialog::OnPlayerSelect, this);
+ m_kick_btn = new wxButton(panel, wxID_ANY, _("Kick Player"));
+ m_kick_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnKick, this);
+ player_szr->Add(m_kick_btn, 0, wxEXPAND | wxTOP, 5);
+ m_kick_btn->Disable();
+
+ m_player_config_btn = new wxButton(panel, wxID_ANY, _("Configure Pads"));
+ m_player_config_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnConfigPads, this);
+ player_szr->Add(m_player_config_btn, 0, wxEXPAND | wxTOP, 5);
+ }
+
+ wxBoxSizer* const mid_szr = new wxBoxSizer(wxHORIZONTAL);
+ mid_szr->Add(chat_szr, 1, wxEXPAND | wxRIGHT, 5);
+ mid_szr->Add(player_szr, 0, wxEXPAND);
+
+ // bottom crap
+ wxButton* const quit_btn = new wxButton(panel, wxID_ANY, _("Quit"));
+ quit_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnQuit, this);
+
+ wxBoxSizer* const bottom_szr = new wxBoxSizer(wxHORIZONTAL);
+ if (is_hosting)
+ {
+ m_start_btn = new wxButton(panel, wxID_ANY, _("Start"));
+ m_start_btn->Bind(wxEVT_BUTTON, &NetPlayDialog::OnStart, this);
+ bottom_szr->Add(m_start_btn);
+
+ bottom_szr->Add(new wxStaticText(panel, wxID_ANY, _("Buffer:")), 0, wxLEFT | wxCENTER, 5);
+ wxSpinCtrl* const padbuf_spin = new wxSpinCtrl(panel, wxID_ANY, std::to_string(INITIAL_PAD_BUFFER_SIZE)
+ , wxDefaultPosition, wxSize(64, -1), wxSP_ARROW_KEYS, 0, 200, INITIAL_PAD_BUFFER_SIZE);
+ padbuf_spin->Bind(wxEVT_SPINCTRL, &NetPlayDialog::OnAdjustBuffer, this);
+ bottom_szr->Add(padbuf_spin, 0, wxCENTER);
+
+ m_memcard_write = new wxCheckBox(panel, wxID_ANY, _("Write memcards (GC)"));
+ bottom_szr->Add(m_memcard_write, 0, wxCENTER);
+ }
+
+ m_record_chkbox = new wxCheckBox(panel, wxID_ANY, _("Record input"));
+ bottom_szr->Add(m_record_chkbox, 0, wxCENTER);
+
+ bottom_szr->AddStretchSpacer(1);
+ bottom_szr->Add(quit_btn);
+
+ // main sizer
+ wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
+ main_szr->Add(m_game_btn, 0, wxEXPAND | wxALL, 5);
+ main_szr->Add(mid_szr, 1, wxEXPAND | wxLEFT | wxRIGHT, 5);
+ main_szr->Add(bottom_szr, 0, wxEXPAND | wxALL, 5);
+
+ panel->SetSizerAndFit(main_szr);
+
+ main_szr->SetSizeHints(this);
+ SetSize(512, 512 - 128);
+
+ Center();
+}
+
+NetPlayDialog::~NetPlayDialog()
+{
+ if (netplay_client)
+ {
+ delete netplay_client;
+ netplay_client = nullptr;
+ }
+ if (netplay_server)
+ {
+ delete netplay_server;
+ netplay_server = nullptr;
+ }
+ npd = nullptr;
+}
+
+void NetPlayDialog::OnChat(wxCommandEvent&)
+{
+ wxString text = m_chat_msg_text->GetValue();
+
+ if (!text.empty())
+ {
+ netplay_client->SendChatMessage(WxStrToStr(text));
+ m_chat_text->AppendText(text.Prepend(" >> ").Append('\n'));
+ m_chat_msg_text->Clear();
+ }
+}
+
+void NetPlayDialog::GetNetSettings(NetSettings &settings)
+{
+ SConfig &instance = SConfig::GetInstance();
+ settings.m_CPUthread = instance.m_LocalCoreStartupParameter.bCPUThread;
+ settings.m_CPUcore = instance.m_LocalCoreStartupParameter.iCPUCore;
+ settings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE;
+ settings.m_DSPEnableJIT = instance.m_DSPEnableJIT;
+ settings.m_WriteToMemcard = m_memcard_write->GetValue();
+ settings.m_OCEnable = instance.m_OCEnable;
+ settings.m_OCFactor = instance.m_OCFactor;
+ settings.m_EXIDevice[0] = instance.m_EXIDevice[0];
+ settings.m_EXIDevice[1] = instance.m_EXIDevice[1];
+}
+
+std::string NetPlayDialog::FindGame()
+{
+ // find path for selected game, sloppy..
+ for (u32 i = 0; auto game = m_game_list->GetISO(i); ++i)
+ if (m_selected_game == BuildGameName(*game))
+ return game->GetFileName();
+
+ WxUtils::ShowErrorDialog(_("Game not found!"));
+ return "";
+}
+
+void NetPlayDialog::OnStart(wxCommandEvent&)
+{
+ NetSettings settings;
+ GetNetSettings(settings);
+ netplay_server->SetNetSettings(settings);
+ netplay_server->StartGame();
+}
+
+void NetPlayDialog::BootGame(const std::string& filename)
+{
+ main_frame->BootGame(filename);
+}
+
+void NetPlayDialog::StopGame()
+{
+ main_frame->DoStop();
+}
+
+// NetPlayUI methods called from ---NETPLAY--- thread
+void NetPlayDialog::Update()
+{
+ wxThreadEvent evt(wxEVT_THREAD, 1);
+ GetEventHandler()->AddPendingEvent(evt);
+}
+
+void NetPlayDialog::AppendChat(const std::string& msg)
+{
+ chat_msgs.Push(msg);
+ // silly
+ Update();
+}
+
+void NetPlayDialog::OnMsgChangeGame(const std::string& filename)
+{
+ wxThreadEvent* evt = new wxThreadEvent(wxEVT_THREAD, NP_GUI_EVT_CHANGE_GAME);
+ evt->SetString(StrToWxStr(filename));
+ GetEventHandler()->QueueEvent(evt);
+}
+
+void NetPlayDialog::OnMsgStartGame()
+{
+ wxThreadEvent evt(wxEVT_THREAD, NP_GUI_EVT_START_GAME);
+ GetEventHandler()->AddPendingEvent(evt);
+ if (m_is_hosting)
+ {
+ m_start_btn->Disable();
+ m_memcard_write->Disable();
+ m_game_btn->Disable();
+ m_player_config_btn->Disable();
+ }
+
+ m_record_chkbox->Disable();
+}
+
+void NetPlayDialog::OnMsgStopGame()
+{
+ wxThreadEvent evt(wxEVT_THREAD, NP_GUI_EVT_STOP_GAME);
+ GetEventHandler()->AddPendingEvent(evt);
+ if (m_is_hosting)
+ {
+ m_start_btn->Enable();
+ m_memcard_write->Enable();
+ m_game_btn->Enable();
+ m_player_config_btn->Enable();
+ }
+ m_record_chkbox->Enable();
+}
+
+void NetPlayDialog::OnAdjustBuffer(wxCommandEvent& event)
+{
+ const int val = ((wxSpinCtrl*)event.GetEventObject())->GetValue();
+ netplay_server->AdjustPadBufferSize(val);
+
+ std::ostringstream ss;
+ ss << "< Pad Buffer: " << val << " >";
+ netplay_client->SendChatMessage(ss.str());
+ m_chat_text->AppendText(StrToWxStr(ss.str()).Append('\n'));
+}
+
+void NetPlayDialog::OnQuit(wxCommandEvent&)
+{
+ Destroy();
+}
+
+// update gui
+void NetPlayDialog::OnThread(wxThreadEvent& event)
+{
+ if (m_is_hosting && m_host_label && g_TraversalClient)
+ {
+ UpdateHostLabel();
+ }
+
+ // player list
+ m_playerids.clear();
+ std::string tmps;
+ netplay_client->GetPlayerList(tmps, m_playerids);
+
+ wxString selection;
+ if (m_player_lbox->GetSelection() != wxNOT_FOUND)
+ selection = m_player_lbox->GetString(m_player_lbox->GetSelection());
+
+ m_player_lbox->Clear();
+ std::istringstream ss(tmps);
+ while (std::getline(ss, tmps))
+ m_player_lbox->Append(StrToWxStr(tmps));
+
+ // remove ping from selection string, in case it has changed
+ selection.erase(selection.find_last_of("|") + 1);
+
+ if (!selection.empty())
+ {
+ for (unsigned int i = 0; i < m_player_lbox->GetCount(); ++i)
+ {
+ if (selection == m_player_lbox->GetString(i).Mid(0, selection.length()))
+ {
+ m_player_lbox->SetSelection(i);
+ break;
+ }
+ }
+ }
+
+ // flash window in taskbar when someone joins if window isn't active
+ static u8 numPlayers = 1;
+ bool focus = (wxWindow::FindFocus() == this || (wxWindow::FindFocus() != nullptr && wxWindow::FindFocus()->GetParent() == this) ||
+ (wxWindow::FindFocus() != nullptr && wxWindow::FindFocus()->GetParent() != nullptr
+ && wxWindow::FindFocus()->GetParent()->GetParent() == this));
+ if (netplay_server != nullptr && numPlayers < m_playerids.size() && !focus)
+ {
+ RequestUserAttention();
+ }
+ numPlayers = m_playerids.size();
+
+ switch (event.GetId())
+ {
+ case NP_GUI_EVT_CHANGE_GAME:
+ // update selected game :/
+ {
+ m_selected_game.assign(WxStrToStr(event.GetString()));
+
+ wxString button_label = event.GetString();
+ m_game_btn->SetLabel(button_label.Prepend(_(" Game : ")));
+ }
+ break;
+ case NP_GUI_EVT_START_GAME:
+ // client start game :/
+ {
+ netplay_client->StartGame(FindGame());
+ }
+ break;
+ case NP_GUI_EVT_STOP_GAME:
+ // client stop game
+ {
+ netplay_client->StopGame();
+ }
+ break;
+ }
+
+ // chat messages
+ while (chat_msgs.Size())
+ {
+ std::string s;
+ chat_msgs.Pop(s);
+ //PanicAlert("message: %s", s.c_str());
+ m_chat_text->AppendText(StrToWxStr(s).Append('\n'));
+ }
+}
+
+void NetPlayDialog::OnChangeGame(wxCommandEvent&)
+{
+ wxString game_name;
+
+ ChangeGameDialog cgd(this, m_game_list, game_name);
+ cgd.ShowModal();
+
+ if (game_name.length())
+ {
+ m_selected_game = WxStrToStr(game_name);
+ netplay_server->ChangeGame(m_selected_game);
+ m_game_btn->SetLabel(game_name.Prepend(_(" Game : ")));
+ }
+}
+
+void NetPlayDialog::OnConfigPads(wxCommandEvent&)
+{
+ PadMapping mapping[4];
+ PadMapping wiimotemapping[4];
+ std::vector player_list;
+
+ netplay_server->GetPadMapping(mapping);
+ netplay_server->GetWiimoteMapping(wiimotemapping);
+ netplay_client->GetPlayers(player_list);
+
+ PadMapDialog pmd(this, mapping, wiimotemapping, player_list);
+ pmd.ShowModal();
+
+ netplay_server->SetPadMapping(mapping);
+ netplay_server->SetWiimoteMapping(wiimotemapping);
+}
+
+void NetPlayDialog::OnKick(wxCommandEvent&)
+{
+ wxString selection = m_player_lbox->GetStringSelection();
+ unsigned long player = 0;
+ selection.Mid(selection.find_last_of("[") + 1, selection.find_last_of("]")).ToULong(&player);
+
+ netplay_server->KickPlayer((u8)player);
+
+ m_player_lbox->SetSelection(wxNOT_FOUND);
+ wxCommandEvent event;
+ OnPlayerSelect(event);
+}
+
+void NetPlayDialog::OnPlayerSelect(wxCommandEvent&)
+{
+ if (m_player_lbox->GetSelection() > 0)
+ m_kick_btn->Enable();
+ else
+ m_kick_btn->Disable();
+}
+
+bool NetPlayDialog::IsRecording()
+{
+ return m_record_chkbox->GetValue();
+}
+
+
+void NetPlayDialog::OnCopyIP(wxCommandEvent&)
+{
+ if (m_host_copy_btn_is_retry)
+ {
+ g_TraversalClient->ReconnectToServer();
+ Update();
+ }
+ else
+ {
+ if (wxTheClipboard->Open())
+ {
+ wxTheClipboard->SetData(new wxTextDataObject(m_host_label->GetLabel()));
+ wxTheClipboard->Close();
+ }
+ }
+}
+
+void NetPlayDialog::OnChoice(wxCommandEvent& event)
+{
+ UpdateHostLabel();
+}
+
+
+void NetPlayDialog::UpdateHostLabel()
+{
+ wxString label = _(" (internal IP)");
+ auto DeLabel = [=](wxString str) {
+ if (str == _("Localhost"))
+ return std::string("!local!");
+ return WxStrToStr(str.Left(str.Len() - label.Len()));
+ };
+ auto EnLabel = [=](std::string str) -> wxString {
+ if (str == "!local!")
+ return _("Localhost");
+ return StrToWxStr(str) + label;
+ };
+ int sel = m_host_type_choice->GetSelection();
+ if (sel == 0)
+ {
+ // the traversal ID
+ switch (g_TraversalClient->m_State)
+ {
+ case TraversalClient::Connecting:
+ m_host_label->SetForegroundColour(*wxLIGHT_GREY);
+ m_host_label->SetLabel("...");
+ m_host_copy_btn->SetLabel(_("Copy"));
+ m_host_copy_btn->Disable();
+ break;
+ case TraversalClient::Connected:
+ m_host_label->SetForegroundColour(*wxBLACK);
+ m_host_label->SetLabel(wxString(g_TraversalClient->m_HostId.data(), g_TraversalClient->m_HostId.size()));
+ m_host_copy_btn->SetLabel(_("Copy"));
+ m_host_copy_btn->Enable();
+ m_host_copy_btn_is_retry = false;
+ break;
+ case TraversalClient::Failure:
+ m_host_label->SetForegroundColour(*wxBLACK);
+ m_host_label->SetLabel(FailureReasonStringForHostLabel(g_TraversalClient->m_FailureReason));
+ m_host_copy_btn->SetLabel(_("Retry"));
+ m_host_copy_btn->Enable();
+ m_host_copy_btn_is_retry = true;
+ break;
+ }
+ }
+ else if (sel != wxNOT_FOUND) // wxNOT_FOUND shouldn't generally happen
+ {
+ m_host_label->SetForegroundColour(*wxBLACK);
+ m_host_label->SetLabel(netplay_server->GetInterfaceHost(DeLabel(m_host_type_choice->GetString(sel))));
+ m_host_copy_btn->SetLabel(_("Copy"));
+ m_host_copy_btn->Enable();
+ m_host_copy_btn_is_retry = false;
+ }
+
+ auto set = netplay_server->GetInterfaceSet();
+ for (const std::string& iface : set)
+ {
+ wxString wxIface = EnLabel(iface);
+ if (m_host_type_choice->FindString(wxIface) == wxNOT_FOUND)
+ m_host_type_choice->Append(wxIface);
+ }
+ for (unsigned i = 1, count = m_host_type_choice->GetCount(); i != count; i++)
+ {
+ if (set.find(DeLabel(m_host_type_choice->GetString(i))) == set.end())
+ {
+ m_host_type_choice->Delete(i);
+ i--;
+ count--;
+ }
+ }
+}
diff --git a/Source/Core/DolphinWX/NetWindow.h b/Source/Core/DolphinWX/NetPlay/NetWindow.h
similarity index 51%
rename from Source/Core/DolphinWX/NetWindow.h
rename to Source/Core/DolphinWX/NetPlay/NetWindow.h
index a883bf9692..d1ab7ad90a 100644
--- a/Source/Core/DolphinWX/NetWindow.h
+++ b/Source/Core/DolphinWX/NetPlay/NetWindow.h
@@ -6,13 +6,12 @@
#include
#include
-#include
-#include
#include
#include "Common/FifoQueue.h"
#include "Core/NetPlayClient.h"
#include "Core/NetPlayProto.h"
+#include "Core/NetPlayServer.h"
class CGameListCtrl;
class wxButton;
@@ -20,8 +19,8 @@ class wxCheckBox;
class wxChoice;
class wxListBox;
class wxString;
+class wxStaticText;
class wxTextCtrl;
-class wxWindow;
enum
{
@@ -30,47 +29,17 @@ enum
NP_GUI_EVT_STOP_GAME,
};
-class NetPlaySetupDiag : public wxFrame
+enum
{
-public:
- NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* const game_list);
- ~NetPlaySetupDiag();
-private:
- void OnJoin(wxCommandEvent& event);
- void OnHost(wxCommandEvent& event);
- void OnQuit(wxCommandEvent& event);
-
- void MakeNetPlayDiag(int port, const std::string &game, bool is_hosting);
-
- void OnChoice(wxCommandEvent& event);
-
- wxStaticText* m_ip_lbl;
- wxStaticText* m_client_port_lbl;
- wxTextCtrl* m_nickname_text;
- wxStaticText* m_host_port_lbl;
- wxTextCtrl* m_host_port_text;
- wxTextCtrl* m_connect_port_text;
- wxTextCtrl* m_connect_ip_text;
- wxChoice* m_direct_traversal;
- wxStaticText* m_traversal_server_lbl;
- wxTextCtrl* m_traversal_server;
- wxStaticText* m_traversal_port_lbl;
- wxTextCtrl* m_traversal_port;
-
- wxListBox* m_game_lbox;
-#ifdef USE_UPNP
- wxCheckBox* m_upnp_chk;
-#endif
-
- const CGameListCtrl* const m_game_list;
+ INITIAL_PAD_BUFFER_SIZE = 5
};
-class NetPlayDiag : public wxFrame, public NetPlayUI
+class NetPlayDialog : public wxFrame, public NetPlayUI
{
public:
- NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game_list
+ NetPlayDialog(wxWindow* parent, const CGameListCtrl* const game_list
, const std::string& game, const bool is_hosting = false);
- ~NetPlayDiag();
+ ~NetPlayDialog();
Common::FifoQueue chat_msgs;
@@ -87,7 +56,10 @@ public:
void OnMsgStartGame() override;
void OnMsgStopGame() override;
- static NetPlayDiag *&GetInstance() { return npd; };
+ static NetPlayDialog*& GetInstance() { return npd; }
+ static NetPlayClient*& GetNetPlayClient() { return netplay_client; }
+ static NetPlayServer*& GetNetPlayServer() { return netplay_server; }
+ static void FillWithGameNames(wxListBox* game_lbox, const CGameListCtrl& game_list);
bool IsRecording() override;
@@ -100,7 +72,7 @@ private:
void OnConfigPads(wxCommandEvent& event);
void OnKick(wxCommandEvent& event);
void OnPlayerSelect(wxCommandEvent& event);
- void GetNetSettings(NetSettings &settings);
+ void GetNetSettings(NetSettings& settings);
std::string FindGame();
void OnCopyIP(wxCommandEvent&);
@@ -128,36 +100,7 @@ private:
const CGameListCtrl* const m_game_list;
- static NetPlayDiag* npd;
+ static NetPlayDialog* npd;
+ static NetPlayServer* netplay_server;
+ static NetPlayClient* netplay_client;
};
-
-class ChangeGameDiag : public wxDialog
-{
-public:
- ChangeGameDiag(wxWindow* const parent, const CGameListCtrl* const game_list, wxString& game_name);
-
-private:
- void OnPick(wxCommandEvent& event);
-
- wxListBox* m_game_lbox;
- wxString& m_game_name;
-};
-
-class PadMapDiag : public wxDialog
-{
-public:
- PadMapDiag(wxWindow* const parent, PadMapping map[], PadMapping wiimotemap[], std::vector& player_list);
-
-private:
- void OnAdjust(wxCommandEvent& event);
-
- wxChoice* m_map_cbox[8];
- PadMapping* const m_mapping;
- PadMapping* const m_wiimapping;
- std::vector& m_player_list;
-};
-
-namespace NetPlay
-{
- void StopGame();
-}
diff --git a/Source/Core/DolphinWX/NetPlay/PadMapDialog.cpp b/Source/Core/DolphinWX/NetPlay/PadMapDialog.cpp
new file mode 100644
index 0000000000..a9e066984f
--- /dev/null
+++ b/Source/Core/DolphinWX/NetPlay/PadMapDialog.cpp
@@ -0,0 +1,106 @@
+// Copyright 2015 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include
+#include
+#include
+
+#include "Core/NetPlayClient.h"
+#include "Core/NetPlayProto.h"
+#include "DolphinWX/NetPlay/PadMapDialog.h"
+
+PadMapDialog::PadMapDialog(wxWindow* parent, PadMapping map[], PadMapping wiimotemap[], std::vector& player_list)
+ : wxDialog(parent, wxID_ANY, _("Configure Pads"))
+ , m_mapping(map)
+ , m_wiimapping(wiimotemap)
+ , m_player_list(player_list)
+{
+ wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL);
+ h_szr->AddSpacer(10);
+
+ wxArrayString player_names;
+ player_names.Add(_("None"));
+ for (auto& player : m_player_list)
+ player_names.Add(player->name);
+
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL);
+ v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("Pad ")) + (wxChar)('0' + i))),
+ 1, wxALIGN_CENTER_HORIZONTAL);
+
+ m_map_cbox[i] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names);
+ m_map_cbox[i]->Bind(wxEVT_CHOICE, &PadMapDialog::OnAdjust, this);
+ if (m_mapping[i] == -1)
+ {
+ m_map_cbox[i]->Select(0);
+ }
+ else
+ {
+ for (unsigned int j = 0; j < m_player_list.size(); j++)
+ {
+ if (m_mapping[i] == m_player_list[j]->pid)
+ m_map_cbox[i]->Select(j + 1);
+ }
+ }
+
+ v_szr->Add(m_map_cbox[i], 1);
+
+ h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20);
+ h_szr->AddSpacer(10);
+ }
+
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL);
+ v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("Wiimote ")) + (wxChar)('0' + i))),
+ 1, wxALIGN_CENTER_HORIZONTAL);
+
+ m_map_cbox[i + 4] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names);
+ m_map_cbox[i + 4]->Bind(wxEVT_CHOICE, &PadMapDialog::OnAdjust, this);
+ if (m_wiimapping[i] == -1)
+ {
+ m_map_cbox[i + 4]->Select(0);
+ }
+ else
+ {
+ for (unsigned int j = 0; j < m_player_list.size(); j++)
+ {
+ if (m_wiimapping[i] == m_player_list[j]->pid)
+ m_map_cbox[i + 4]->Select(j + 1);
+ }
+ }
+
+ v_szr->Add(m_map_cbox[i + 4], 1);
+
+ h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20);
+ h_szr->AddSpacer(10);
+ }
+
+ wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
+ main_szr->Add(h_szr);
+ main_szr->AddSpacer(5);
+ main_szr->Add(CreateButtonSizer(wxOK), 0, wxEXPAND | wxLEFT | wxRIGHT, 20);
+ main_szr->AddSpacer(5);
+ SetSizerAndFit(main_szr);
+ SetFocus();
+}
+
+void PadMapDialog::OnAdjust(wxCommandEvent& WXUNUSED(event))
+{
+ for (unsigned int i = 0; i < 4; i++)
+ {
+ int player_idx = m_map_cbox[i]->GetSelection();
+ if (player_idx > 0)
+ m_mapping[i] = m_player_list[player_idx - 1]->pid;
+ else
+ m_mapping[i] = -1;
+
+ player_idx = m_map_cbox[i + 4]->GetSelection();
+ if (player_idx > 0)
+ m_wiimapping[i] = m_player_list[player_idx - 1]->pid;
+ else
+ m_wiimapping[i] = -1;
+ }
+}
diff --git a/Source/Core/DolphinWX/NetPlay/PadMapDialog.h b/Source/Core/DolphinWX/NetPlay/PadMapDialog.h
new file mode 100644
index 0000000000..c7a18cc084
--- /dev/null
+++ b/Source/Core/DolphinWX/NetPlay/PadMapDialog.h
@@ -0,0 +1,27 @@
+// Copyright 2015 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+#include
+
+#include "Core/NetPlayProto.h"
+
+class Player;
+class wxChoice;
+
+class PadMapDialog final : public wxDialog
+{
+public:
+ PadMapDialog(wxWindow* parent, PadMapping map[], PadMapping wiimotemap[], std::vector& player_list);
+
+private:
+ void OnAdjust(wxCommandEvent& event);
+
+ wxChoice* m_map_cbox[8];
+ PadMapping* const m_mapping;
+ PadMapping* const m_wiimapping;
+ std::vector& m_player_list;
+};
diff --git a/Source/Core/DolphinWX/NetWindow.cpp b/Source/Core/DolphinWX/NetWindow.cpp
deleted file mode 100644
index fc9289148e..0000000000
--- a/Source/Core/DolphinWX/NetWindow.cpp
+++ /dev/null
@@ -1,1079 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-
-#include "Common/CommonTypes.h"
-#include "Common/FifoQueue.h"
-#include "Common/FileUtil.h"
-#include "Common/IniFile.h"
-
-#include "Core/ConfigManager.h"
-#include "Core/CoreParameter.h"
-#include "Core/NetPlayClient.h"
-#include "Core/NetPlayProto.h"
-#include "Core/NetPlayServer.h"
-#include "Core/HW/EXI_Device.h"
-
-#include "DolphinWX/Frame.h"
-#include "DolphinWX/GameListCtrl.h"
-#include "DolphinWX/ISOFile.h"
-#include "DolphinWX/Main.h"
-#include "DolphinWX/NetWindow.h"
-#include "DolphinWX/WxUtils.h"
-
-#define INITIAL_PAD_BUFFER_SIZE 5
-
-static NetPlayServer* netplay_server = nullptr;
-static NetPlayClient* netplay_client = nullptr;
-NetPlayDiag *NetPlayDiag::npd = nullptr;
-
-
-static wxString FailureReasonStringForHostLabel(int reason)
-{
- switch (reason)
- {
- case TraversalClient::BadHost:
- return _("(Error: Bad host)");
- case TraversalClient::VersionTooOld:
- return _("(Error: Dolphin too old)");
- case TraversalClient::ServerForgotAboutUs:
- return _("(Error: Disconnected)");
- case TraversalClient::SocketSendError:
- return _("(Error: Socket)");
- case TraversalClient::ResendTimeout:
- return _("(Error: Timeout)");
- default:
- return _("(Error: Unknown)");
- }
-}
-
-static std::string BuildGameName(const GameListItem& game)
-{
- // Lang needs to be consistent
- auto const lang = 0;
-
- std::string name(game.GetName(lang));
-
- if (game.GetRevision() != 0)
- return name + " (" + game.GetUniqueID() + ", Revision " + std::to_string((long long)game.GetRevision()) + ")";
- else
- return name + " (" + game.GetUniqueID() + ")";
-}
-
-static void FillWithGameNames(wxListBox* game_lbox, const CGameListCtrl& game_list)
-{
- for (u32 i = 0; auto game = game_list.GetISO(i); ++i)
- game_lbox->Append(StrToWxStr(BuildGameName(*game)));
-}
-
-NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* const game_list)
- : wxFrame(parent, wxID_ANY, _("Dolphin NetPlay Setup"))
- , m_game_list(game_list)
-{
- IniFile inifile;
- inifile.Load(File::GetUserPath(D_CONFIG_IDX) + "Dolphin.ini");
- IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay");
-
- wxPanel* const panel = new wxPanel(this);
-
- // top row
- wxBoxSizer* const trav_szr = new wxBoxSizer(wxHORIZONTAL);
-
- m_direct_traversal = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(75, -1));
- m_direct_traversal->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &NetPlaySetupDiag::OnChoice, this);
- m_direct_traversal->Append(_("Direct"));
- m_direct_traversal->Append(_("Traversal"));
-
- std::string travChoice;
- netplay_section.Get("TraversalChoice", &travChoice, "direct");
-
- if (travChoice == "traversal")
- {
- m_direct_traversal->Select(1);
- }
- else
- {
- m_direct_traversal->Select(0);
- }
-
- trav_szr->Add(m_direct_traversal, 0, wxRIGHT);
-
- wxBoxSizer* const nick_szr = new wxBoxSizer(wxHORIZONTAL);
- wxStaticText* const nick_lbl = new wxStaticText(panel, wxID_ANY, _("Nickname :"));
- std::string nickname;
- netplay_section.Get("Nickname", &nickname, "Player");
- m_nickname_text = new wxTextCtrl(panel, wxID_ANY, StrToWxStr(nickname));
- nick_szr->Add(nick_lbl, 0, wxCENTER);
- nick_szr->Add(m_nickname_text, 0, wxALL, 5);
-
- std::string centralServer;
- netplay_section.Get("TraversalServer", ¢ralServer, "");
- m_traversal_server_lbl = new wxStaticText(panel, wxID_ANY, _("Traversal:"));
- m_traversal_server = new wxTextCtrl(panel, wxID_ANY, StrToWxStr(centralServer));
- nick_szr->Add(m_traversal_server_lbl, 0, wxCENTER);
- nick_szr->Add(m_traversal_server, 0, wxALL, 5);
-
- std::string centralPort;
- netplay_section.Get("TraversalPort", ¢ralPort, "");
- m_traversal_port_lbl = new wxStaticText(panel, wxID_ANY, _("Port:"));
- m_traversal_port = new wxTextCtrl(panel, wxID_ANY, StrToWxStr(centralPort));
- nick_szr->Add(m_traversal_port_lbl, 0, wxCENTER);
- nick_szr->Add(m_traversal_port, 0, wxALL, 5);
-
- // tabs
- wxNotebook* const notebook = new wxNotebook(panel, wxID_ANY);
- wxPanel* const connect_tab = new wxPanel(notebook, wxID_ANY);
- notebook->AddPage(connect_tab, _("Connect"));
- wxPanel* const host_tab = new wxPanel(notebook, wxID_ANY);
- notebook->AddPage(host_tab, _("Host"));
-
- // connect tab
- {
- m_ip_lbl = new wxStaticText(connect_tab, wxID_ANY, _("Host Code :"));
-
- std::string address;
- netplay_section.Get("HostCode", &address, "00000000");
- m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(address));
-
- m_client_port_lbl = new wxStaticText(connect_tab, wxID_ANY, _("Port :"));
-
- // string? w/e
- std::string port;
- netplay_section.Get("ConnectPort", &port, "2626");
- m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(port));
-
- wxButton* const connect_btn = new wxButton(connect_tab, wxID_ANY, _("Connect"));
- connect_btn->Bind(wxEVT_BUTTON, &NetPlaySetupDiag::OnJoin, this);
-
- wxStaticText* const alert_lbl = new wxStaticText(connect_tab, wxID_ANY,
- _("ALERT:\n\n"
- "Netplay will only work with the following settings:\n"
- " - DSP Emulator Engine Must be the same on all computers!\n"
- " - DSP on Dedicated Thread [OFF]\n"
- " - Manually set the extensions for each Wiimote\n"
- "\n"
- "All players should use the same Dolphin version and settings.\n"
- "All memory cards must be identical between players or disabled.\n"
- "Wiimote support is probably terrible. Don't use it.\n"
- "\n"
- "If connecting directly host must have the chosen UDP port open/forwarded!\n"));
-
- wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL);
-
- top_szr->Add(m_ip_lbl, 0, wxCENTER | wxRIGHT, 5);
- top_szr->Add(m_connect_ip_text, 3);
- top_szr->Add(m_client_port_lbl, 0, wxCENTER | wxRIGHT | wxLEFT, 5);
- top_szr->Add(m_connect_port_text, 1);
-
- wxBoxSizer* const con_szr = new wxBoxSizer(wxVERTICAL);
- con_szr->Add(top_szr, 0, wxALL | wxEXPAND, 5);
- con_szr->AddStretchSpacer(1);
- con_szr->Add(alert_lbl, 0, wxLEFT | wxRIGHT | wxEXPAND, 5);
- con_szr->AddStretchSpacer(1);
- con_szr->Add(connect_btn, 0, wxALL | wxALIGN_RIGHT, 5);
-
- connect_tab->SetSizerAndFit(con_szr);
- }
-
- // host tab
- {
- m_host_port_lbl = new wxStaticText(host_tab, wxID_ANY, _("Port :"));
-
- // string? w/e
- std::string port;
- netplay_section.Get("HostPort", &port, "2626");
- m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, StrToWxStr(port));
-
- wxButton* const host_btn = new wxButton(host_tab, wxID_ANY, _("Host"));
- host_btn->Bind(wxEVT_BUTTON, &NetPlaySetupDiag::OnHost, this);
-
- m_game_lbox = new wxListBox(host_tab, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxLB_SORT);
- m_game_lbox->Bind(wxEVT_LISTBOX_DCLICK, &NetPlaySetupDiag::OnHost, this);
-
- FillWithGameNames(m_game_lbox, *game_list);
-
- wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL);
- top_szr->Add(m_host_port_lbl, 0, wxCENTER | wxRIGHT, 5);
- top_szr->Add(m_host_port_text, 0);
-#ifdef USE_UPNP
- m_upnp_chk = new wxCheckBox(host_tab, wxID_ANY, _("Forward port (UPnP)"));
- top_szr->Add(m_upnp_chk, 0, wxALL | wxALIGN_RIGHT, 5);
-#endif
-
- wxBoxSizer* const host_szr = new wxBoxSizer(wxVERTICAL);
- host_szr->Add(top_szr, 0, wxALL | wxEXPAND, 5);
- host_szr->Add(m_game_lbox, 1, wxLEFT | wxRIGHT | wxEXPAND, 5);
- host_szr->Add(host_btn, 0, wxALL | wxALIGN_RIGHT, 5);
-
- host_tab->SetSizerAndFit(host_szr);
- }
-
- // bottom row
- wxButton* const quit_btn = new wxButton(panel, wxID_ANY, _("Quit"));
- quit_btn->Bind(wxEVT_BUTTON, &NetPlaySetupDiag::OnQuit, this);
-
- // main sizer
- wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
- main_szr->Add(trav_szr, 0, wxALL | wxALIGN_LEFT);
- main_szr->Add(nick_szr, 0, wxALL | wxALIGN_LEFT, 5);
- main_szr->Add(notebook, 1, wxLEFT | wxRIGHT | wxEXPAND, 5);
- main_szr->Add(quit_btn, 0, wxALL | wxALIGN_RIGHT, 5);
-
- panel->SetSizerAndFit(main_szr);
-
- //wxBoxSizer* const diag_szr = new wxBoxSizer(wxVERTICAL);
- //diag_szr->Add(panel, 1, wxEXPAND);
- //SetSizerAndFit(diag_szr);
-
- main_szr->SetSizeHints(this);
-
- Center();
- Show();
-
- // Needs to be done last or it set up the spacing on the page correctly
- wxCommandEvent ev;
- OnChoice(ev);
-
-}
-
-NetPlaySetupDiag::~NetPlaySetupDiag()
-{
- IniFile inifile;
- const std::string dolphin_ini = File::GetUserPath(D_CONFIG_IDX) + "Dolphin.ini";
- inifile.Load(dolphin_ini);
- IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay");
-
- std::string travChoice = "traversal";
- if (m_direct_traversal->GetSelection() == 1)
- {
- netplay_section.Set("TraversalChoice", travChoice);
- }
- else
- {
- travChoice = "direct";
- netplay_section.Set("TraversalChoice", travChoice);
- }
-
- netplay_section.Set("Nickname", WxStrToStr(m_nickname_text->GetValue()));
- netplay_section.Set("TraversalServer", WxStrToStr(m_traversal_server->GetValue()));
- netplay_section.Set("TraversalPort", WxStrToStr(m_traversal_port->GetValue()));
-
- if (m_direct_traversal->GetCurrentSelection() == 0)
- {
- netplay_section.Set("Address", WxStrToStr(m_connect_ip_text->GetValue()));
- }
- else
- {
- netplay_section.Set("HostCode", WxStrToStr(m_connect_ip_text->GetValue()));
- }
- netplay_section.Set("ConnectPort", WxStrToStr(m_connect_port_text->GetValue()));
- netplay_section.Set("HostPort", WxStrToStr(m_host_port_text->GetValue()));
-
- inifile.Save(dolphin_ini);
- main_frame->g_NetPlaySetupDiag = nullptr;
-}
-
-void NetPlaySetupDiag::MakeNetPlayDiag(int port, const std::string &game, bool is_hosting)
-{
- NetPlayDiag *&npd = NetPlayDiag::GetInstance();
- std::string ip;
- npd = new NetPlayDiag(m_parent, m_game_list, game, is_hosting);
- if (is_hosting)
- ip = "127.0.0.1";
- else
- ip = WxStrToStr(m_connect_ip_text->GetValue());
-
- bool trav;
- if (!is_hosting && m_direct_traversal->GetCurrentSelection() == 1)
- trav = true;
- else
- trav = false;
-
- unsigned long centralPort = 0;
- m_traversal_port->GetValue().ToULong(¢ralPort);
- netplay_client = new NetPlayClient(ip, (u16)port, npd, WxStrToStr(m_nickname_text->GetValue()), trav, WxStrToStr(m_traversal_server->GetValue()), (u16)centralPort);
- if (netplay_client->is_connected)
- {
- npd->Show();
- Destroy();
- }
- else
- {
- npd->Destroy();
- }
-}
-
-void NetPlaySetupDiag::OnHost(wxCommandEvent&)
-{
- NetPlayDiag *&npd = NetPlayDiag::GetInstance();
- if (npd)
- {
- WxUtils::ShowErrorDialog(_("A NetPlay window is already open!"));
- return;
- }
-
- if (-1 == m_game_lbox->GetSelection())
- {
- WxUtils::ShowErrorDialog(_("You must choose a game!"));
- return;
- }
-
- std::string game(WxStrToStr(m_game_lbox->GetStringSelection()));
-
- bool trav;
- if (m_direct_traversal->GetCurrentSelection() == 1)
- trav = true;
- else
- trav = false;
-
- unsigned long port = 0;
- m_host_port_text->GetValue().ToULong(&port);
-
- unsigned long centralPort = 0;
- m_traversal_port->GetValue().ToULong(¢ralPort);
- netplay_server = new NetPlayServer(u16(port), trav, WxStrToStr(m_traversal_server->GetValue()), u16(centralPort));
- if (netplay_server->is_connected)
- {
- netplay_server->ChangeGame(game);
- netplay_server->AdjustPadBufferSize(INITIAL_PAD_BUFFER_SIZE);
-#ifdef USE_UPNP
- if (m_upnp_chk->GetValue())
- netplay_server->TryPortmapping(port);
-#endif
- MakeNetPlayDiag(netplay_server->GetPort(), game, true);
- netplay_server->SetNetPlayUI(NetPlayDiag::GetInstance());
- }
- else
- {
- WxUtils::ShowErrorDialog(_("Failed to listen. Is another instance of the NetPlay server running?"));
- }
-}
-
-void NetPlaySetupDiag::OnJoin(wxCommandEvent&)
-{
- NetPlayDiag *&npd = NetPlayDiag::GetInstance();
- if (npd)
- {
- WxUtils::ShowErrorDialog(_("A NetPlay window is already open!"));
- return;
- }
-
- unsigned long port = 0;
- m_connect_port_text->GetValue().ToULong(&port);
- MakeNetPlayDiag(port, "", false);
-}
-
-void NetPlaySetupDiag::OnChoice(wxCommandEvent& event)
-{
- int sel = m_direct_traversal->GetSelection();
- IniFile inifile;
- inifile.Load(File::GetUserPath(D_CONFIG_IDX) + "Dolphin.ini");
- IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay");
-
- if (sel == 1)
- {
- m_traversal_server_lbl->Show(true);
- m_traversal_server->Show(true);
-
- m_traversal_port_lbl->Show(true);
- m_traversal_port->Show(true);
-
- //Traversal
- //client tab
- {
- m_ip_lbl->SetLabelText("Host Code: ");
-
- std::string address;
- netplay_section.Get("HostCode", &address, "00000000");
- m_connect_ip_text->SetLabelText(address);
-
- m_client_port_lbl->Show(false);
- m_connect_port_text->Show(false);
- }
-
- //server tab
- {
- m_host_port_lbl->Show(false);
- m_host_port_text->Show(false);
- m_upnp_chk->Show(false);
- }
- }
- else
- {
- m_traversal_server_lbl->Show(false);
- m_traversal_server->Show(false);
-
- m_traversal_port_lbl->Show(false);
- m_traversal_port->Show(false);
- //Direct
- //client tab
- {
- m_ip_lbl->SetLabelText("IP Address :");
-
- std::string address;
- netplay_section.Get("Address", &address, "127.0.0.1");
- m_connect_ip_text->SetLabelText(address);
-
- m_client_port_lbl->Show(true);
- m_connect_port_text->Show(true);
- }
-
- //server tab
- {
- m_host_port_lbl->Show(true);
- m_host_port_text->Show(true);
- m_upnp_chk->Show(true);
- }
- }
-}
-
-void NetPlaySetupDiag::OnQuit(wxCommandEvent&)
-{
- Destroy();
-}
-
-NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game_list,
- const std::string& game, const bool is_hosting)
- : wxFrame(parent, wxID_ANY, _("Dolphin NetPlay"))
- , m_selected_game(game)
- , m_start_btn(nullptr)
- , m_host_label(nullptr)
- , m_host_type_choice(nullptr)
- , m_host_copy_btn(nullptr)
- , m_host_copy_btn_is_retry(false)
- , m_is_hosting(is_hosting)
- , m_game_list(game_list)
-{
- Bind(wxEVT_THREAD, &NetPlayDiag::OnThread, this);
-
- wxPanel* const panel = new wxPanel(this);
-
- // top crap
- m_game_btn = new wxButton(panel, wxID_ANY,
- StrToWxStr(m_selected_game).Prepend(_(" Game : ")),
- wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
-
- if (m_is_hosting)
- m_game_btn->Bind(wxEVT_BUTTON, &NetPlayDiag::OnChangeGame, this);
- else
- m_game_btn->Disable();
-
- // middle crap
-
- // chat
- m_chat_text = new wxTextCtrl(panel, wxID_ANY, wxEmptyString
- , wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE);
-
- m_chat_msg_text = new wxTextCtrl(panel, wxID_ANY, wxEmptyString
- , wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
- m_chat_msg_text->Bind(wxEVT_TEXT_ENTER, &NetPlayDiag::OnChat, this);
- m_chat_msg_text->SetMaxLength(2000);
-
- wxButton* const chat_msg_btn = new wxButton(panel, wxID_ANY, _("Send"));
- chat_msg_btn->Bind(wxEVT_BUTTON, &NetPlayDiag::OnChat, this);
-
- wxBoxSizer* const chat_msg_szr = new wxBoxSizer(wxHORIZONTAL);
- chat_msg_szr->Add(m_chat_msg_text, 1);
- chat_msg_szr->Add(chat_msg_btn, 0);
-
- wxStaticBoxSizer* const chat_szr = new wxStaticBoxSizer(wxVERTICAL, panel, _("Chat"));
- chat_szr->Add(m_chat_text, 1, wxEXPAND);
- chat_szr->Add(chat_msg_szr, 0, wxEXPAND | wxTOP, 5);
-
- m_player_lbox = new wxListBox(panel, wxID_ANY, wxDefaultPosition, wxSize(256, -1));
-
- wxStaticBoxSizer* const player_szr = new wxStaticBoxSizer(wxVERTICAL, panel, _("Players"));
-
- // player list
- if (m_is_hosting && g_TraversalClient)
- {
- wxBoxSizer* const host_szr = new wxBoxSizer(wxHORIZONTAL);
- m_host_type_choice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(60, -1));
- m_host_type_choice->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &NetPlayDiag::OnChoice, this);
- m_host_type_choice->Append(_("ID:"));
- host_szr->Add(m_host_type_choice);
-
- m_host_label = new wxStaticText(panel, wxID_ANY, "555.555.555.555:55555", wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE | wxALIGN_LEFT);
- // Update() should fix this immediately.
- m_host_label->SetLabel(_(""));
- host_szr->Add(m_host_label, 1, wxLEFT | wxCENTER, 5);
-
- m_host_copy_btn = new wxButton(panel, wxID_ANY, _("Copy"));
- m_host_copy_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlayDiag::OnCopyIP, this);
- m_host_copy_btn->Disable();
- host_szr->Add(m_host_copy_btn, 0, wxLEFT | wxCENTER, 5);
- player_szr->Add(host_szr, 0, wxEXPAND | wxBOTTOM, 5);
- m_host_type_choice->Select(0);
-
- UpdateHostLabel();
- }
-
- player_szr->Add(m_player_lbox, 1, wxEXPAND);
-
- if (m_is_hosting)
- {
- m_player_lbox->Bind(wxEVT_LISTBOX, &NetPlayDiag::OnPlayerSelect, this);
- m_kick_btn = new wxButton(panel, wxID_ANY, _("Kick Player"));
- m_kick_btn->Bind(wxEVT_BUTTON, &NetPlayDiag::OnKick, this);
- player_szr->Add(m_kick_btn, 0, wxEXPAND | wxTOP, 5);
- m_kick_btn->Disable();
-
- m_player_config_btn = new wxButton(panel, wxID_ANY, _("Configure Pads"));
- m_player_config_btn->Bind(wxEVT_BUTTON, &NetPlayDiag::OnConfigPads, this);
- player_szr->Add(m_player_config_btn, 0, wxEXPAND | wxTOP, 5);
- }
-
- wxBoxSizer* const mid_szr = new wxBoxSizer(wxHORIZONTAL);
- mid_szr->Add(chat_szr, 1, wxEXPAND | wxRIGHT, 5);
- mid_szr->Add(player_szr, 0, wxEXPAND);
-
- // bottom crap
- wxButton* const quit_btn = new wxButton(panel, wxID_ANY, _("Quit"));
- quit_btn->Bind(wxEVT_BUTTON, &NetPlayDiag::OnQuit, this);
-
- wxBoxSizer* const bottom_szr = new wxBoxSizer(wxHORIZONTAL);
- if (is_hosting)
- {
- m_start_btn = new wxButton(panel, wxID_ANY, _("Start"));
- m_start_btn->Bind(wxEVT_BUTTON, &NetPlayDiag::OnStart, this);
- bottom_szr->Add(m_start_btn);
-
- bottom_szr->Add(new wxStaticText(panel, wxID_ANY, _("Buffer:")), 0, wxLEFT | wxCENTER, 5);
- wxSpinCtrl* const padbuf_spin = new wxSpinCtrl(panel, wxID_ANY, std::to_string(INITIAL_PAD_BUFFER_SIZE)
- , wxDefaultPosition, wxSize(64, -1), wxSP_ARROW_KEYS, 0, 200, INITIAL_PAD_BUFFER_SIZE);
- padbuf_spin->Bind(wxEVT_SPINCTRL, &NetPlayDiag::OnAdjustBuffer, this);
- bottom_szr->Add(padbuf_spin, 0, wxCENTER);
-
- m_memcard_write = new wxCheckBox(panel, wxID_ANY, _("Write memcards (GC)"));
- bottom_szr->Add(m_memcard_write, 0, wxCENTER);
- }
-
- m_record_chkbox = new wxCheckBox(panel, wxID_ANY, _("Record input"));
- bottom_szr->Add(m_record_chkbox, 0, wxCENTER);
-
- bottom_szr->AddStretchSpacer(1);
- bottom_szr->Add(quit_btn);
-
- // main sizer
- wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
- main_szr->Add(m_game_btn, 0, wxEXPAND | wxALL, 5);
- main_szr->Add(mid_szr, 1, wxEXPAND | wxLEFT | wxRIGHT, 5);
- main_szr->Add(bottom_szr, 0, wxEXPAND | wxALL, 5);
-
- panel->SetSizerAndFit(main_szr);
-
- main_szr->SetSizeHints(this);
- SetSize(512, 512 - 128);
-
- Center();
-}
-
-NetPlayDiag::~NetPlayDiag()
-{
- if (netplay_client)
- {
- delete netplay_client;
- netplay_client = nullptr;
- }
- if (netplay_server)
- {
- delete netplay_server;
- netplay_server = nullptr;
- }
- npd = nullptr;
-}
-
-void NetPlayDiag::OnChat(wxCommandEvent&)
-{
- wxString text = m_chat_msg_text->GetValue();
-
- if (!text.empty())
- {
- netplay_client->SendChatMessage(WxStrToStr(text));
- m_chat_text->AppendText(text.Prepend(" >> ").Append('\n'));
- m_chat_msg_text->Clear();
- }
-}
-
-void NetPlayDiag::GetNetSettings(NetSettings &settings)
-{
- SConfig &instance = SConfig::GetInstance();
- settings.m_CPUthread = instance.m_LocalCoreStartupParameter.bCPUThread;
- settings.m_CPUcore = instance.m_LocalCoreStartupParameter.iCPUCore;
- settings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE;
- settings.m_DSPEnableJIT = instance.m_DSPEnableJIT;
- settings.m_WriteToMemcard = m_memcard_write->GetValue();
- settings.m_OCEnable = instance.m_OCEnable;
- settings.m_OCFactor = instance.m_OCFactor;
- settings.m_EXIDevice[0] = instance.m_EXIDevice[0];
- settings.m_EXIDevice[1] = instance.m_EXIDevice[1];
-}
-
-std::string NetPlayDiag::FindGame()
-{
- // find path for selected game, sloppy..
- for (u32 i = 0; auto game = m_game_list->GetISO(i); ++i)
- if (m_selected_game == BuildGameName(*game))
- return game->GetFileName();
-
- WxUtils::ShowErrorDialog(_("Game not found!"));
- return "";
-}
-
-void NetPlayDiag::OnStart(wxCommandEvent&)
-{
- NetSettings settings;
- GetNetSettings(settings);
- netplay_server->SetNetSettings(settings);
- netplay_server->StartGame();
-}
-
-void NetPlayDiag::BootGame(const std::string& filename)
-{
- main_frame->BootGame(filename);
-}
-
-void NetPlayDiag::StopGame()
-{
- main_frame->DoStop();
-}
-
-// NetPlayUI methods called from ---NETPLAY--- thread
-void NetPlayDiag::Update()
-{
- wxThreadEvent evt(wxEVT_THREAD, 1);
- GetEventHandler()->AddPendingEvent(evt);
-}
-
-void NetPlayDiag::AppendChat(const std::string& msg)
-{
- chat_msgs.Push(msg);
- // silly
- Update();
-}
-
-void NetPlayDiag::OnMsgChangeGame(const std::string& filename)
-{
- wxThreadEvent* evt = new wxThreadEvent(wxEVT_THREAD, NP_GUI_EVT_CHANGE_GAME);
- evt->SetString(StrToWxStr(filename));
- GetEventHandler()->QueueEvent(evt);
-}
-
-void NetPlayDiag::OnMsgStartGame()
-{
- wxThreadEvent evt(wxEVT_THREAD, NP_GUI_EVT_START_GAME);
- GetEventHandler()->AddPendingEvent(evt);
- if (m_is_hosting)
- {
- m_start_btn->Disable();
- m_memcard_write->Disable();
- m_game_btn->Disable();
- m_player_config_btn->Disable();
- }
-
- m_record_chkbox->Disable();
-}
-
-void NetPlayDiag::OnMsgStopGame()
-{
- wxThreadEvent evt(wxEVT_THREAD, NP_GUI_EVT_STOP_GAME);
- GetEventHandler()->AddPendingEvent(evt);
- if (m_is_hosting)
- {
- m_start_btn->Enable();
- m_memcard_write->Enable();
- m_game_btn->Enable();
- m_player_config_btn->Enable();
- }
- m_record_chkbox->Enable();
-}
-
-void NetPlayDiag::OnAdjustBuffer(wxCommandEvent& event)
-{
- const int val = ((wxSpinCtrl*)event.GetEventObject())->GetValue();
- netplay_server->AdjustPadBufferSize(val);
-
- std::ostringstream ss;
- ss << "< Pad Buffer: " << val << " >";
- netplay_client->SendChatMessage(ss.str());
- m_chat_text->AppendText(StrToWxStr(ss.str()).Append('\n'));
-}
-
-void NetPlayDiag::OnQuit(wxCommandEvent&)
-{
- Destroy();
-}
-
-// update gui
-void NetPlayDiag::OnThread(wxThreadEvent& event)
-{
- if (m_is_hosting && m_host_label && g_TraversalClient)
- {
- UpdateHostLabel();
- }
-
- // player list
- m_playerids.clear();
- std::string tmps;
- netplay_client->GetPlayerList(tmps, m_playerids);
-
- wxString selection;
- if (m_player_lbox->GetSelection() != wxNOT_FOUND)
- selection = m_player_lbox->GetString(m_player_lbox->GetSelection());
-
- m_player_lbox->Clear();
- std::istringstream ss(tmps);
- while (std::getline(ss, tmps))
- m_player_lbox->Append(StrToWxStr(tmps));
-
- // remove ping from selection string, in case it has changed
- selection.erase(selection.find_last_of("|") + 1);
-
- if (!selection.empty())
- {
- for (unsigned int i = 0; i < m_player_lbox->GetCount(); ++i)
- {
- if (selection == m_player_lbox->GetString(i).Mid(0, selection.length()))
- {
- m_player_lbox->SetSelection(i);
- break;
- }
- }
- }
-
- // flash window in taskbar when someone joins if window isn't active
- static u8 numPlayers = 1;
- bool focus = (wxWindow::FindFocus() == this || (wxWindow::FindFocus() != nullptr && wxWindow::FindFocus()->GetParent() == this) ||
- (wxWindow::FindFocus() != nullptr && wxWindow::FindFocus()->GetParent() != nullptr
- && wxWindow::FindFocus()->GetParent()->GetParent() == this));
- if (netplay_server != nullptr && numPlayers < m_playerids.size() && !focus)
- {
- RequestUserAttention();
- }
- numPlayers = m_playerids.size();
-
- switch (event.GetId())
- {
- case NP_GUI_EVT_CHANGE_GAME:
- // update selected game :/
- {
- m_selected_game.assign(WxStrToStr(event.GetString()));
-
- wxString button_label = event.GetString();
- m_game_btn->SetLabel(button_label.Prepend(_(" Game : ")));
- }
- break;
- case NP_GUI_EVT_START_GAME:
- // client start game :/
- {
- netplay_client->StartGame(FindGame());
- }
- break;
- case NP_GUI_EVT_STOP_GAME:
- // client stop game
- {
- netplay_client->StopGame();
- }
- break;
- }
-
- // chat messages
- while (chat_msgs.Size())
- {
- std::string s;
- chat_msgs.Pop(s);
- //PanicAlert("message: %s", s.c_str());
- m_chat_text->AppendText(StrToWxStr(s).Append('\n'));
- }
-}
-
-void NetPlayDiag::OnChangeGame(wxCommandEvent&)
-{
- wxString game_name;
- ChangeGameDiag* const cgd = new ChangeGameDiag(this, m_game_list, game_name);
- cgd->ShowModal();
-
- if (game_name.length())
- {
- m_selected_game = WxStrToStr(game_name);
- netplay_server->ChangeGame(m_selected_game);
- m_game_btn->SetLabel(game_name.Prepend(_(" Game : ")));
- }
-}
-
-void NetPlayDiag::OnConfigPads(wxCommandEvent&)
-{
- PadMapping mapping[4];
- PadMapping wiimotemapping[4];
- std::vector player_list;
- netplay_server->GetPadMapping(mapping);
- netplay_server->GetWiimoteMapping(wiimotemapping);
- netplay_client->GetPlayers(player_list);
- PadMapDiag pmd(this, mapping, wiimotemapping, player_list);
- pmd.ShowModal();
- netplay_server->SetPadMapping(mapping);
- netplay_server->SetWiimoteMapping(wiimotemapping);
-}
-
-void NetPlayDiag::OnKick(wxCommandEvent&)
-{
- wxString selection = m_player_lbox->GetStringSelection();
- unsigned long player = 0;
- selection.Mid(selection.find_last_of("[") + 1, selection.find_last_of("]")).ToULong(&player);
-
- netplay_server->KickPlayer((u8)player);
-
- m_player_lbox->SetSelection(wxNOT_FOUND);
- wxCommandEvent event;
- OnPlayerSelect(event);
-}
-
-void NetPlayDiag::OnPlayerSelect(wxCommandEvent&)
-{
- if (m_player_lbox->GetSelection() > 0)
- m_kick_btn->Enable();
- else
- m_kick_btn->Disable();
-}
-
-bool NetPlayDiag::IsRecording()
-{
- return m_record_chkbox->GetValue();
-}
-
-
-void NetPlayDiag::OnCopyIP(wxCommandEvent&)
-{
- if (m_host_copy_btn_is_retry)
- {
- g_TraversalClient->ReconnectToServer();
- Update();
- }
- else
- {
- if (wxTheClipboard->Open())
- {
- wxTheClipboard->SetData(new wxTextDataObject(m_host_label->GetLabel()));
- wxTheClipboard->Close();
- }
- }
-}
-
-void NetPlayDiag::OnChoice(wxCommandEvent& event)
-{
- UpdateHostLabel();
-}
-
-
-void NetPlayDiag::UpdateHostLabel()
-{
- wxString label = _(" (internal IP)");
- auto DeLabel = [=](wxString str) {
- if (str == _("Localhost"))
- return std::string("!local!");
- return WxStrToStr(str.Left(str.Len() - label.Len()));
- };
- auto EnLabel = [=](std::string str) -> wxString {
- if (str == "!local!")
- return _("Localhost");
- return StrToWxStr(str) + label;
- };
- int sel = m_host_type_choice->GetSelection();
- if (sel == 0)
- {
- // the traversal ID
- switch (g_TraversalClient->m_State)
- {
- case TraversalClient::Connecting:
- m_host_label->SetForegroundColour(*wxLIGHT_GREY);
- m_host_label->SetLabel("...");
- m_host_copy_btn->SetLabel(_("Copy"));
- m_host_copy_btn->Disable();
- break;
- case TraversalClient::Connected:
- m_host_label->SetForegroundColour(*wxBLACK);
- m_host_label->SetLabel(wxString(g_TraversalClient->m_HostId.data(), g_TraversalClient->m_HostId.size()));
- m_host_copy_btn->SetLabel(_("Copy"));
- m_host_copy_btn->Enable();
- m_host_copy_btn_is_retry = false;
- break;
- case TraversalClient::Failure:
- m_host_label->SetForegroundColour(*wxBLACK);
- m_host_label->SetLabel(FailureReasonStringForHostLabel(g_TraversalClient->m_FailureReason));
- m_host_copy_btn->SetLabel(_("Retry"));
- m_host_copy_btn->Enable();
- m_host_copy_btn_is_retry = true;
- break;
- }
- }
- else if (sel != wxNOT_FOUND) // wxNOT_FOUND shouldn't generally happen
- {
- m_host_label->SetForegroundColour(*wxBLACK);
- m_host_label->SetLabel(netplay_server->GetInterfaceHost(DeLabel(m_host_type_choice->GetString(sel))));
- m_host_copy_btn->SetLabel(_("Copy"));
- m_host_copy_btn->Enable();
- m_host_copy_btn_is_retry = false;
- }
-
- auto set = netplay_server->GetInterfaceSet();
- for (const std::string& iface : set)
- {
- wxString wxIface = EnLabel(iface);
- if (m_host_type_choice->FindString(wxIface) == wxNOT_FOUND)
- m_host_type_choice->Append(wxIface);
- }
- for (unsigned i = 1, count = m_host_type_choice->GetCount(); i != count; i++)
- {
- if (set.find(DeLabel(m_host_type_choice->GetString(i))) == set.end())
- {
- m_host_type_choice->Delete(i);
- i--;
- count--;
- }
- }
-}
-
-ChangeGameDiag::ChangeGameDiag(wxWindow* const parent, const CGameListCtrl* const game_list, wxString& game_name)
- : wxDialog(parent, wxID_ANY, _("Change Game"))
- , m_game_name(game_name)
-{
- m_game_lbox = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxLB_SORT);
- m_game_lbox->Bind(wxEVT_LISTBOX_DCLICK, &ChangeGameDiag::OnPick, this);
-
- FillWithGameNames(m_game_lbox, *game_list);
-
- wxButton* const ok_btn = new wxButton(this, wxID_OK, _("Change"));
- ok_btn->Bind(wxEVT_BUTTON, &ChangeGameDiag::OnPick, this);
-
- wxBoxSizer* const szr = new wxBoxSizer(wxVERTICAL);
- szr->Add(m_game_lbox, 1, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, 5);
- szr->Add(ok_btn, 0, wxALL | wxALIGN_RIGHT, 5);
-
- SetSizerAndFit(szr);
- SetFocus();
-}
-
-void ChangeGameDiag::OnPick(wxCommandEvent& event)
-{
- // return the selected game name
- m_game_name = m_game_lbox->GetStringSelection();
- EndModal(wxID_OK);
-}
-
-PadMapDiag::PadMapDiag(wxWindow* const parent, PadMapping map[], PadMapping wiimotemap[], std::vector& player_list)
- : wxDialog(parent, wxID_ANY, _("Configure Pads"))
- , m_mapping(map)
- , m_wiimapping(wiimotemap)
- , m_player_list(player_list)
-{
- wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL);
- h_szr->AddSpacer(10);
-
- wxArrayString player_names;
- player_names.Add(_("None"));
- for (auto& player : m_player_list)
- player_names.Add(player->name);
-
- for (unsigned int i = 0; i < 4; ++i)
- {
- wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL);
- v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("Pad ")) + (wxChar)('0' + i))),
- 1, wxALIGN_CENTER_HORIZONTAL);
-
- m_map_cbox[i] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names);
- m_map_cbox[i]->Bind(wxEVT_CHOICE, &PadMapDiag::OnAdjust, this);
- if (m_mapping[i] == -1)
- m_map_cbox[i]->Select(0);
- else
- for (unsigned int j = 0; j < m_player_list.size(); j++)
- if (m_mapping[i] == m_player_list[j]->pid)
- m_map_cbox[i]->Select(j + 1);
-
- v_szr->Add(m_map_cbox[i], 1);
-
- h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20);
- h_szr->AddSpacer(10);
- }
-
- for (unsigned int i = 0; i < 4; ++i)
- {
- wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL);
- v_szr->Add(new wxStaticText(this, wxID_ANY, (wxString(_("Wiimote ")) + (wxChar)('0' + i))),
- 1, wxALIGN_CENTER_HORIZONTAL);
-
- m_map_cbox[i + 4] = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, player_names);
- m_map_cbox[i + 4]->Bind(wxEVT_CHOICE, &PadMapDiag::OnAdjust, this);
- if (m_wiimapping[i] == -1)
- m_map_cbox[i + 4]->Select(0);
- else
- for (unsigned int j = 0; j < m_player_list.size(); j++)
- if (m_wiimapping[i] == m_player_list[j]->pid)
- m_map_cbox[i + 4]->Select(j + 1);
-
- v_szr->Add(m_map_cbox[i + 4], 1);
-
- h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20);
- h_szr->AddSpacer(10);
- }
-
- wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
- main_szr->Add(h_szr);
- main_szr->AddSpacer(5);
- main_szr->Add(CreateButtonSizer(wxOK), 0, wxEXPAND | wxLEFT | wxRIGHT, 20);
- main_szr->AddSpacer(5);
- SetSizerAndFit(main_szr);
- SetFocus();
-}
-
-void PadMapDiag::OnAdjust(wxCommandEvent& event)
-{
- (void)event;
- for (unsigned int i = 0; i < 4; i++)
- {
- int player_idx = m_map_cbox[i]->GetSelection();
- if (player_idx > 0)
- m_mapping[i] = m_player_list[player_idx - 1]->pid;
- else
- m_mapping[i] = -1;
-
- player_idx = m_map_cbox[i + 4]->GetSelection();
- if (player_idx > 0)
- m_wiimapping[i] = m_player_list[player_idx - 1]->pid;
- else
- m_wiimapping[i] = -1;
- }
-}
-
-void NetPlay::StopGame()
-{
- if (netplay_client != nullptr)
- netplay_client->Stop();
-}