NetPlay: completely redone - should be somewhat usable when using Single Core and...
[dolphin.git] / Source / Core / DolphinWX / Src / NetWindow.cpp
blob166f5ceb078c6d08cc22aa80ae02621795c7e04d
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 #include "NetPlay.h"
19 #include "NetWindow.h"
21 #include <sstream>
23 #define _connect_macro_( b, f, c, s ) (b)->Connect( wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s )
25 #define NETPLAY_TITLEBAR "Dolphin NetPlay"
27 BEGIN_EVENT_TABLE(NetPlayDiag, wxFrame)
28 EVT_COMMAND(wxID_ANY, wxEVT_THREAD, NetPlayDiag::OnThread)
29 END_EVENT_TABLE()
31 NetPlay* netplay_ptr = NULL;
33 NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* parent, const CGameListCtrl* const game_list)
34 : wxFrame(parent, wxID_ANY, wxT(NETPLAY_TITLEBAR), wxDefaultPosition, wxDefaultSize)
35 , m_game_list(game_list)
37 //PanicAlert("ALERT: NetPlay is not 100%% functional !!!!");
39 wxPanel* const panel = new wxPanel(this);
41 // top row
42 wxStaticText* const nick_lbl = new wxStaticText(panel, wxID_ANY, wxT("Nickname :"), wxDefaultPosition, wxDefaultSize);
43 m_nickname_text = new wxTextCtrl(panel, wxID_ANY, wxT("Player"));
45 wxBoxSizer* const nick_szr = new wxBoxSizer(wxHORIZONTAL);
46 nick_szr->Add(nick_lbl, 0, wxCENTER);
47 nick_szr->Add(m_nickname_text, 0, wxALL, 5);
50 // tabs
51 wxNotebook* const notebook = new wxNotebook(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
52 wxPanel* const connect_tab = new wxPanel(notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
53 notebook->AddPage(connect_tab, wxT("Connect"));
54 wxPanel* const host_tab = new wxPanel(notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
55 notebook->AddPage(host_tab, wxT("Host"));
58 // connect tab
60 wxStaticText* const ip_lbl = new wxStaticText(connect_tab, wxID_ANY, wxT("Address :"), wxDefaultPosition, wxDefaultSize);
61 m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, wxT("localhost"));
62 wxStaticText* const port_lbl = new wxStaticText(connect_tab, wxID_ANY, wxT("Port :"), wxDefaultPosition, wxDefaultSize);
63 m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, wxT("2626"));
65 wxButton* const connect_btn = new wxButton(connect_tab, wxID_ANY, wxT("Connect"));
66 //connect_button->Disable();
67 _connect_macro_(connect_btn, NetPlaySetupDiag::OnJoin, wxEVT_COMMAND_BUTTON_CLICKED, this);
69 wxStaticText* const alert_lbl = new wxStaticText(connect_tab, wxID_ANY
70 , wxT("ALERT:\n\nNetPlay will currently only work properly when using the following settings:\n")
71 wxT(" - Dual Core [OFF]\n - DSP LLE Plugin\n - DSPLLE on thread [OFF]\n - Manually set the exact number of controller that will be used to [Standard Controller]")
72 wxT("\n\nAll players should try to use the same Dolphin version and settings.")
73 wxT("\nDisable all memory cards or send them to all players before starting.")
74 wxT("\nWiimote support has not been implemented.\nWii games will likely desync for other reasons as well.")
75 wxT("\n\nYou must forward TCP port to host!!")
76 , wxDefaultPosition, wxDefaultSize);
78 wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL);
79 top_szr->Add(ip_lbl, 0, wxCENTER | wxRIGHT, 5);
80 top_szr->Add(m_connect_ip_text, 3);
81 top_szr->Add(port_lbl, 0, wxCENTER | wxRIGHT | wxLEFT, 5);
82 top_szr->Add(m_connect_port_text, 1);
84 wxBoxSizer* const con_szr = new wxBoxSizer(wxVERTICAL);
85 con_szr->Add(top_szr, 0, wxALL | wxEXPAND, 5);
86 con_szr->AddStretchSpacer(1);
87 con_szr->Add(alert_lbl, 0, wxLEFT | wxRIGHT | wxEXPAND, 5);
88 con_szr->AddStretchSpacer(1);
89 con_szr->Add(connect_btn, 0, wxALL | wxALIGN_RIGHT, 5);
91 connect_tab->SetSizerAndFit(con_szr);
94 // host tab
96 wxStaticText* const port_lbl = new wxStaticText(host_tab, wxID_ANY, wxT("Port :"), wxDefaultPosition, wxDefaultSize);
97 m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, wxT("2626"));
99 wxButton* const host_btn = new wxButton(host_tab, wxID_ANY, wxT("Host"));
100 //host_button->Disable();
101 _connect_macro_(host_btn, NetPlaySetupDiag::OnHost, wxEVT_COMMAND_BUTTON_CLICKED, this);
103 m_game_lbox = new wxListBox(host_tab, wxID_ANY);
104 std::istringstream ss(game_list->GetGameNames());
105 std::string game;
106 while (std::getline(ss,game))
107 m_game_lbox->Append(wxString(game.c_str(), *wxConvCurrent));
109 wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL);
110 top_szr->Add(port_lbl, 0, wxCENTER | wxRIGHT, 5);
111 top_szr->Add(m_host_port_text, 0);
113 wxBoxSizer* const host_szr = new wxBoxSizer(wxVERTICAL);
114 host_szr->Add(top_szr, 0, wxALL | wxEXPAND, 5);
115 host_szr->Add(m_game_lbox, 1, wxLEFT | wxRIGHT | wxEXPAND, 5);
116 host_szr->Add(host_btn, 0, wxALL | wxALIGN_RIGHT, 5);
118 host_tab->SetSizerAndFit(host_szr);
121 // bottom row
122 wxButton* const quit_btn = new wxButton(panel, wxID_ANY, wxT("Quit"));
123 _connect_macro_(quit_btn, NetPlaySetupDiag::OnQuit, wxEVT_COMMAND_BUTTON_CLICKED, this);
125 // main sizer
126 wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
127 main_szr->Add(nick_szr, 0, wxALL | wxALIGN_RIGHT, 5);
128 main_szr->Add(notebook, 1, wxLEFT | wxRIGHT | wxEXPAND, 5);
129 main_szr->Add(quit_btn, 0, wxALL | wxALIGN_RIGHT, 5);
131 panel->SetSizerAndFit(main_szr);
133 //wxBoxSizer* const diag_szr = new wxBoxSizer(wxVERTICAL);
134 //diag_szr->Add(panel);
135 //SetSizerAndFit(diag_szr);
137 main_szr->SetSizeHints(this);
139 Center();
140 Show();
143 void NetPlaySetupDiag::OnHost(wxCommandEvent& event)
145 // warning removal
146 event.GetId();
148 if (::netplay_ptr)
150 PanicAlert("A NetPlay window is already open!!");
151 return;
154 if (-1 == m_game_lbox->GetSelection())
156 PanicAlert("You must choose a game!!");
157 return;
160 std::string game(m_game_lbox->GetStringSelection().mb_str());
162 NetPlayDiag* const npd = new NetPlayDiag(m_parent, m_game_list, game, true);
163 unsigned long port = 0;
164 m_host_port_text->GetValue().ToULong(&port);
165 ::netplay_ptr = new NetPlayServer(u16(port)
166 , std::string(m_nickname_text->GetValue().mb_str()), npd, game);
167 if (::netplay_ptr->is_connected)
169 //NetPlayServerDiag* const npsd =
170 npd->Show();
171 Destroy();
173 else
175 PanicAlert("Failed to Listen!!");
176 npd->Destroy();
177 // dialog will delete netplay
178 //delete ::netplay_ptr;
182 void NetPlaySetupDiag::OnJoin(wxCommandEvent& event)
184 // warning removal
185 event.GetId();
187 if (::netplay_ptr)
189 PanicAlert("A NetPlay window is already open!!");
190 return;
193 NetPlayDiag* const npd = new NetPlayDiag(m_parent, m_game_list, "");
194 unsigned long port = 0;
195 m_connect_port_text->GetValue().ToULong(&port);
196 ::netplay_ptr = new NetPlayClient(std::string(m_connect_ip_text->GetValue().mb_str())
197 , (u16)port, std::string(m_nickname_text->GetValue().mb_str()), npd);
198 if (::netplay_ptr->is_connected)
200 //NetPlayServerDiag* const npsd =
201 npd->Show();
202 Destroy();
204 else
206 //PanicAlert("Failed to Connect!!");
207 npd->Destroy();
208 // dialog will delete netplay
209 //delete ::netplay_ptr;
213 void NetPlaySetupDiag::OnQuit(wxCommandEvent& event)
215 // warning removal
216 event.GetId();
218 Destroy();
221 NetPlayDiag::NetPlayDiag(wxWindow* parent, const CGameListCtrl* const game_list
222 , const std::string& game, const bool is_hosting)
223 : wxFrame(parent, wxID_ANY, wxT(NETPLAY_TITLEBAR), wxDefaultPosition, wxDefaultSize)
224 , m_game_list(game_list)
225 , m_selected_game(game)
227 wxPanel* const panel = new wxPanel(this);
229 // top crap
230 m_game_btn = new wxButton(panel, wxID_ANY
231 , wxString(m_selected_game.c_str(), *wxConvCurrent).Prepend(wxT(" Game : ")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
232 m_game_btn->Disable();
234 // middle crap
236 // chat
237 m_chat_text = new wxTextCtrl(panel, wxID_ANY, wxEmptyString
238 , wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE);
240 m_chat_msg_text = new wxTextCtrl(panel, wxID_ANY, wxEmptyString
241 , wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
242 _connect_macro_(m_chat_msg_text, NetPlayDiag::OnChat, wxEVT_COMMAND_TEXT_ENTER, this);
244 wxButton* const chat_msg_btn = new wxButton(panel, wxID_ANY, wxT("Send"));
245 _connect_macro_(chat_msg_btn, NetPlayDiag::OnChat, wxEVT_COMMAND_BUTTON_CLICKED, this);
247 wxBoxSizer* const chat_msg_szr = new wxBoxSizer(wxHORIZONTAL);
248 chat_msg_szr->Add(m_chat_msg_text, 1);
249 chat_msg_szr->Add(chat_msg_btn, 0);
251 wxStaticBoxSizer* const chat_szr = new wxStaticBoxSizer(wxVERTICAL, panel, wxT("Chat"));
252 chat_szr->Add(m_chat_text, 1, wxEXPAND);
253 chat_szr->Add(chat_msg_szr, 0, wxEXPAND | wxTOP, 5);
255 m_player_lbox = new wxListBox(panel, wxID_ANY, wxDefaultPosition, wxSize(192,-1));
257 wxStaticBoxSizer* const player_szr = new wxStaticBoxSizer(wxVERTICAL, panel, wxT("Players"));
258 player_szr->Add(m_player_lbox, 1, wxEXPAND);
259 // player list
260 if (is_hosting)
262 wxButton* const player_config_btn = new wxButton(panel, wxID_ANY, wxT("Configure Pads [not implemented]"));
263 player_config_btn->Disable();
264 player_szr->Add(player_config_btn, 0, wxEXPAND | wxTOP, 5);
267 wxBoxSizer* const mid_szr = new wxBoxSizer(wxHORIZONTAL);
268 mid_szr->Add(chat_szr, 1, wxEXPAND | wxRIGHT, 5);
269 mid_szr->Add(player_szr, 0, wxEXPAND);
271 // bottom crap
272 wxButton* const quit_btn = new wxButton(panel, wxID_ANY, wxT("Quit"));
273 _connect_macro_(quit_btn, NetPlayDiag::OnQuit, wxEVT_COMMAND_BUTTON_CLICKED, this);
275 wxBoxSizer* const bottom_szr = new wxBoxSizer(wxHORIZONTAL);
276 if (is_hosting)
278 wxButton* const start_btn = new wxButton(panel, wxID_ANY, wxT("Start"));
279 _connect_macro_(start_btn, NetPlayDiag::OnStart, wxEVT_COMMAND_BUTTON_CLICKED, this);
280 bottom_szr->Add(start_btn);
283 bottom_szr->AddStretchSpacer(1);
284 bottom_szr->Add(quit_btn);
286 // main sizer
287 wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL);
288 main_szr->Add(m_game_btn, 0, wxEXPAND | wxALL, 5);
289 main_szr->Add(mid_szr, 1, wxEXPAND | wxLEFT | wxRIGHT, 5);
290 main_szr->Add(bottom_szr, 0, wxEXPAND | wxALL, 5);
292 panel->SetSizerAndFit(main_szr);
294 main_szr->SetSizeHints(this);
295 SetSize(512, 512-128);
297 Center();
300 NetPlayDiag::~NetPlayDiag()
302 if (::netplay_ptr)
304 delete netplay_ptr;
305 ::netplay_ptr = NULL;
309 void NetPlayDiag::OnChat(wxCommandEvent& event)
311 // warning removal
312 event.GetId();
314 wxString s = m_chat_msg_text->GetValue();
316 if (s.Length())
318 ::netplay_ptr->SendChatMessage(std::string(s.mb_str()));
319 m_chat_text->AppendText(s.Prepend(wxT(" >> ")).Append(wxT('\n')));
320 m_chat_msg_text->Clear();
324 void NetPlayDiag::OnStart(wxCommandEvent& event)
326 // warning removal
327 event.GetId();
329 // find path for selected game
330 std::string ntmp, ptmp, path;
331 std::istringstream nss(m_game_list->GetGameNames()), pss(m_game_list->GetGamePaths());
333 while(std::getline(nss,ntmp))
335 std::getline(pss,ptmp);
336 if (m_selected_game == ntmp)
338 path = ptmp;
339 break;
343 if (path.length())
344 ::netplay_ptr->StartGame(path);
345 else
346 PanicAlert("Game not found!!");
349 void NetPlayDiag::OnQuit(wxCommandEvent& event)
351 // warning removal
352 event.GetId();
354 Destroy();
357 // update gui
358 void NetPlayDiag::OnThread(wxCommandEvent& event)
360 // warning removal
361 event.GetId();
363 // player list
364 std::string tmps;
365 ::netplay_ptr->GetPlayerList(tmps);
367 m_player_lbox->Clear();
368 std::istringstream ss(tmps);
369 while (std::getline(ss, tmps))
370 m_player_lbox->Append(wxString(tmps.c_str(), *wxConvCurrent));
372 // update selected game :/
373 if (45 == event.GetId())
375 m_selected_game.assign(event.GetString().mb_str());
376 m_game_btn->SetLabel(event.GetString().Prepend(wxT(" Game : ")));
379 // chat messages
380 while (chat_msgs.Size())
382 std::string s;
383 chat_msgs.Pop(s);
384 //PanicAlert("message: %s", s.c_str());
385 m_chat_text->AppendText(wxString(s.c_str(), *wxConvCurrent).Append(wxT('\n')));