From 9e8655fa1f662cd294f67bcf2397fd2bdd23edd1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 5 Aug 2013 02:47:40 -0400 Subject: [PATCH 1/6] NetPlay: Remove some dead code --- Source/Core/Core/Src/NetPlay.h | 1 - Source/Core/Core/Src/NetPlayServer.cpp | 23 ----------------------- 2 files changed, 24 deletions(-) diff --git a/Source/Core/Core/Src/NetPlay.h b/Source/Core/Core/Src/NetPlay.h index 222fb680cf..7adf0c26a1 100644 --- a/Source/Core/Core/Src/NetPlay.h +++ b/Source/Core/Core/Src/NetPlay.h @@ -200,7 +200,6 @@ public: bool GetPadMapping(const int pid, int map[]); bool SetPadMapping(const int pid, const int map[]); - u64 CalculateMinimumBufferTime(); void AdjustPadBufferSize(unsigned int size); #ifdef USE_UPNP diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index db3a41a398..bd5d74f0da 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -380,29 +380,6 @@ void NetPlayServer::UpdatePadMapping() } -// called from ---GUI--- thread and ---NETPLAY--- thread -u64 NetPlayServer::CalculateMinimumBufferTime() -{ - std::lock_guard lkp(m_crit.players); - - std::map::const_iterator - i = m_players.begin(), - e = m_players.end(); - std::priority_queue pings; - for ( ;i!=e; ++i) - pings.push(i->second.ping/2); - - unsigned int required_ms = pings.top(); - // if there is more than 1 client, buffersize must be >= (2 highest ping times combined) - if (pings.size() > 1) - { - pings.pop(); - required_ms += pings.top(); - } - - return required_ms; -} - // called from ---GUI--- thread and ---NETPLAY--- thread void NetPlayServer::AdjustPadBufferSize(unsigned int size) { From 3b32d3c90d052873c0b8de6dbdb3c1d03ae90814 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 22 Jul 2013 04:21:56 -0400 Subject: [PATCH 2/6] NetPlay: Split the server out, and make the local system manage a client as well This should be transparent, but it may cause regressions. The idea here is that now all players, including the host of the server, talk to the server through TCP/IP networking. This significantly reduces our codepaths through netplay, and will prevent strange local-only bugs from happening. The cleanup isn't 100% finished yet. The NetPlay dialog still drives the server through private APIs. I eventually want to sanction off the server entirely, so all communication is done through TCP/IP. This will allow us to have high-traffic public servers that can relay multiple games and lobbies at a time, and split off channel and game management to people other than the host. This is all still just a pipe dream, though. --- Source/Core/Core/Src/NetPlay.cpp | 16 --- Source/Core/Core/Src/NetPlay.h | 132 +----------------------- Source/Core/Core/Src/NetPlayProto.h | 67 ++++++++++++ Source/Core/Core/Src/NetPlayServer.cpp | 100 ++++++------------ Source/Core/Core/Src/NetPlayServer.h | 116 +++++++++++++++++++++ Source/Core/DolphinWX/Src/NetWindow.cpp | 128 +++++++++++++---------- Source/Core/DolphinWX/Src/NetWindow.h | 5 +- 7 files changed, 294 insertions(+), 270 deletions(-) create mode 100644 Source/Core/Core/Src/NetPlayProto.h create mode 100644 Source/Core/Core/Src/NetPlayServer.h diff --git a/Source/Core/Core/Src/NetPlay.cpp b/Source/Core/Core/Src/NetPlay.cpp index 45d1689abe..d192a19506 100644 --- a/Source/Core/Core/Src/NetPlay.cpp +++ b/Source/Core/Core/Src/NetPlay.cpp @@ -261,12 +261,6 @@ bool NetPlay::StopGame() return true; } -void NetPlay::SetMemcardWriteEnabled(bool enabled) -{ - std::lock_guard lkg(m_crit.game); - g_NetPlaySettings.m_WriteToMemcard = enabled; -} - // called from ---CPU--- thread u8 NetPlay::GetPadNum(u8 numPAD) { @@ -279,16 +273,6 @@ u8 NetPlay::GetPadNum(u8 numPAD) return i; } -void NetPlay::GetNetSettings() -{ - SConfig &instance = SConfig::GetInstance(); - g_NetPlaySettings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE; - g_NetPlaySettings.m_DSPEnableJIT = instance.m_EnableJIT; - - for (unsigned int i = 0; i < 4; ++i) - g_NetPlaySettings.m_Controllers[i] = SConfig::GetInstance().m_SIDevice[i]; -} - // stuff hacked into dolphin // called from ---CPU--- thread diff --git a/Source/Core/Core/Src/NetPlay.h b/Source/Core/Core/Src/NetPlay.h index 7adf0c26a1..68fb615850 100644 --- a/Source/Core/Core/Src/NetPlay.h +++ b/Source/Core/Core/Src/NetPlay.h @@ -12,6 +12,7 @@ #include +#include "NetPlayProto.h" #include "GCPadStatus.h" #include @@ -31,63 +32,6 @@ public: u32 nLo; }; -struct NetSettings -{ - bool m_DSPHLE; - bool m_DSPEnableJIT; - bool m_WriteToMemcard; - u8 m_Controllers[4]; -}; -extern NetSettings g_NetPlaySettings; - -struct Rpt : public std::vector -{ - u16 channel; -}; - -typedef std::vector NetWiimote; - -#define NETPLAY_VERSION "Dolphin NetPlay 2013-07-22" - -// messages -enum -{ - NP_MSG_PLAYER_JOIN = 0x10, - NP_MSG_PLAYER_LEAVE = 0x11, - - NP_MSG_CHAT_MESSAGE = 0x30, - - NP_MSG_PAD_DATA = 0x60, - NP_MSG_PAD_MAPPING = 0x61, - NP_MSG_PAD_BUFFER = 0x62, - - NP_MSG_WIIMOTE_DATA = 0x70, - NP_MSG_WIIMOTE_MAPPING = 0x71, // just using pad mapping for now - - NP_MSG_START_GAME = 0xA0, - NP_MSG_CHANGE_GAME = 0xA1, - NP_MSG_STOP_GAME = 0xA2, - NP_MSG_DISABLE_GAME = 0xA3, - - NP_MSG_READY = 0xD0, - NP_MSG_NOT_READY = 0xD1, - - NP_MSG_PING = 0xE0, - NP_MSG_PONG = 0xE1, -}; - -typedef u8 MessageId; -typedef u8 PlayerId; -typedef s8 PadMapping; -typedef u32 FrameNum; - -enum -{ - CON_ERR_SERVER_FULL = 1, - CON_ERR_GAME_RUNNING, - CON_ERR_VERSION_MISMATCH -}; - class NetPlayUI { public: @@ -104,6 +48,8 @@ public: virtual void OnMsgStopGame() = 0; }; +extern NetSettings g_NetPlaySettings; + class NetPlay { public: @@ -124,16 +70,12 @@ public: virtual bool StartGame(const std::string &path); virtual bool StopGame(); - virtual void SetMemcardWriteEnabled(bool enabled); - //void PushPadStates(unsigned int count); - u8 GetPadNum(u8 numPAD); static NetPlay* GetNetPlayPtr(); protected: //void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues); void ClearBuffers(); - void GetNetSettings(); virtual void SendPadState(const PadMapping local_nb, const NetPad& np) = 0; struct @@ -179,74 +121,6 @@ protected: void NetPlay_Enable(NetPlay* const np); void NetPlay_Disable(); -class NetPlayServer : public NetPlay -{ -public: - void ThreadFunc(); - - NetPlayServer(const u16 port, const std::string& name, NetPlayUI* dialog); - ~NetPlayServer(); - - void GetPlayerList(std::string& list, std::vector& pid_list); - - // Send and receive pads values - //bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues); - bool ChangeGame(const std::string& game); - void SendChatMessage(const std::string& msg); - - bool StartGame(const std::string &path); - bool StopGame(); - - bool GetPadMapping(const int pid, int map[]); - bool SetPadMapping(const int pid, const int map[]); - - void AdjustPadBufferSize(unsigned int size); - -#ifdef USE_UPNP - void TryPortmapping(u16 port); -#endif - -private: - class Client : public Player - { - public: - Client() : ping(0), current_game(0) {} - - sf::SocketTCP socket; - u64 ping; - u32 current_game; - }; - - void SendPadState(const PadMapping local_nb, const NetPad& np); - void SendToClients(sf::Packet& packet, const PlayerId skip_pid = 0); - unsigned int OnConnect(sf::SocketTCP& socket); - unsigned int OnDisconnect(sf::SocketTCP& socket); - unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket); - void UpdatePadMapping(); - - std::map m_players; - - Common::Timer m_ping_timer; - u32 m_ping_key; - bool m_update_pings; - -#ifdef USE_UPNP - static void mapPortThread(const u16 port); - static void unmapPortThread(); - - static bool initUPnP(); - static bool UPnPMapPort(const std::string& addr, const u16 port); - static bool UPnPUnmapPort(const u16 port); - - static struct UPNPUrls m_upnp_urls; - static struct IGDdatas m_upnp_data; - static u16 m_upnp_mapped; - static bool m_upnp_inited; - static bool m_upnp_error; - static std::thread m_upnp_thread; -#endif -}; - class NetPlayClient : public NetPlay { public: diff --git a/Source/Core/Core/Src/NetPlayProto.h b/Source/Core/Core/Src/NetPlayProto.h new file mode 100644 index 0000000000..fc2031a0f0 --- /dev/null +++ b/Source/Core/Core/Src/NetPlayProto.h @@ -0,0 +1,67 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#ifndef _NETPLAY_PROTO_H +#define _NETPLAY_PROTO_H + +#include "Common.h" +#include "CommonTypes.h" + +struct NetSettings +{ + bool m_DSPHLE; + bool m_DSPEnableJIT; + bool m_WriteToMemcard; + u8 m_Controllers[4]; +}; + +struct Rpt : public std::vector +{ + u16 channel; +}; + +typedef std::vector NetWiimote; + +#define NETPLAY_VERSION "Dolphin NetPlay 2013-07-19" + +// messages +enum +{ + NP_MSG_PLAYER_JOIN = 0x10, + NP_MSG_PLAYER_LEAVE = 0x11, + + NP_MSG_CHAT_MESSAGE = 0x30, + + NP_MSG_PAD_DATA = 0x60, + NP_MSG_PAD_MAPPING = 0x61, + NP_MSG_PAD_BUFFER = 0x62, + + NP_MSG_WIIMOTE_DATA = 0x70, + NP_MSG_WIIMOTE_MAPPING = 0x71, // just using pad mapping for now + + NP_MSG_START_GAME = 0xA0, + NP_MSG_CHANGE_GAME = 0xA1, + NP_MSG_STOP_GAME = 0xA2, + NP_MSG_DISABLE_GAME = 0xA3, + + NP_MSG_READY = 0xD0, + NP_MSG_NOT_READY = 0xD1, + + NP_MSG_PING = 0xE0, + NP_MSG_PONG = 0xE1, +}; + +typedef u8 MessageId; +typedef u8 PlayerId; +typedef s8 PadMapping; +typedef u32 FrameNum; + +enum +{ + CON_ERR_SERVER_FULL = 1, + CON_ERR_GAME_RUNNING, + CON_ERR_VERSION_MISMATCH +}; + +#endif diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index bd5d74f0da..affffac1eb 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -2,9 +2,24 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include "NetPlay.h" +#include "NetPlayServer.h" + +NetPlayServer::Client::Client() +{ + memset(pad_map, -1, sizeof(pad_map)); +} // called from ---GUI--- thread +std::string NetPlayServer::Client::ToString() const +{ + std::ostringstream ss; + ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |"; + for (unsigned int i=0; i<4; ++i) + ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-'); + ss << '|'; + return ss.str(); +} + NetPlayServer::~NetPlayServer() { if (is_connected) @@ -22,35 +37,15 @@ NetPlayServer::~NetPlayServer() } // called from ---GUI--- thread -NetPlayServer::NetPlayServer(const u16 port, const std::string& name, NetPlayUI* dialog) : NetPlay(dialog) +NetPlayServer::NetPlayServer(const u16 port) : is_connected(false), m_is_running(false) { - m_update_pings = true; - if (m_socket.Listen(port)) { - Client player; - player.pid = 0; - player.revision = netplay_dolphin_ver; - player.socket = m_socket; - player.name = name; - - // map local pad 1 to game pad 1 - player.pad_map[0] = 0; - - // add self to player list - m_players[m_socket] = player; - m_local_player = &m_players[m_socket]; - //PanicAlertT("Listening"); - - m_dialog->Update(); - is_connected = true; - + m_do_loop = true; m_selector.Add(m_socket); m_thread = std::thread(std::mem_fun(&NetPlayServer::ThreadFunc), this); } - else - is_connected = false; } // called from ---NETPLAY--- thread @@ -258,8 +253,6 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) // add client to selector/ used for receiving m_selector.Add(socket); - m_dialog->Update(); - return 0; } @@ -271,7 +264,6 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket) PanicAlertT("Client disconnect while game is running!! NetPlay is disabled. You must manually stop the game."); std::lock_guard lkg(m_crit.game); m_is_running = false; - NetPlay_Disable(); sf::Packet spac; spac << (MessageId)NP_MSG_DISABLE_GAME; @@ -293,8 +285,6 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket) std::lock_guard lks(m_crit.send); SendToClients(spac); - m_dialog->Update(); - return 0; } @@ -357,8 +347,6 @@ bool NetPlayServer::SetPadMapping(const int pid, const int map[]) std::lock_guard lks(m_crit.send); UpdatePadMapping(); // sync pad mappings with everyone - m_dialog->Update(); - return true; } @@ -424,12 +412,6 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) std::lock_guard lks(m_crit.send); SendToClients(spac, player.pid); } - - // add to gui - std::ostringstream ss; - ss << player.name << '[' << (char)(player.pid+'0') << "]: " << msg; - - m_dialog->AppendChat(ss.str()); } break; @@ -440,8 +422,8 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) break; PadMapping map = 0; - NetPad np; - packet >> map >> np.nHi >> np.nLo; + int hi, lo; + packet >> map >> hi >> lo; // check if client's pad indeed maps in game if (map >= 0 && map < 4) @@ -454,14 +436,12 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) if (map < 0) return 1; - // add to pad buffer - m_pad_buffer[(unsigned)map].Push(np); // relay to clients sf::Packet spac; spac << (MessageId)NP_MSG_PAD_DATA; spac << map; // in game mapping - spac << np.nHi << np.nLo; + spac << hi << lo; std::lock_guard lks(m_crit.send); SendToClients(spac, player.pid); @@ -475,11 +455,7 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) packet >> ping_key; if (m_ping_key == ping_key) - { - //PanicAlertT("Good pong"); player.ping = ping; - } - m_dialog->Update(); } break; @@ -550,29 +526,16 @@ bool NetPlayServer::ChangeGame(const std::string &game) return true; } -// called from ---CPU--- thread -void NetPlayServer::SendPadState(const PadMapping local_nb, const NetPad& np) +// called from ---GUI--- thread +void NetPlayServer::SetNetSettings(const NetSettings &settings) { - // send to server - sf::Packet spac; - spac << (MessageId)NP_MSG_PAD_DATA; - spac << m_local_player->pad_map[local_nb]; // in-game pad num - spac << np.nHi << np.nLo; - - std::lock_guard lks(m_crit.send); - SendToClients(spac); + m_settings = settings; } // called from ---GUI--- thread bool NetPlayServer::StartGame(const std::string &path) { std::lock_guard lkg(m_crit.game); - - GetNetSettings(); - if (false == NetPlay::StartGame(path)) - return false; - - // TODO: i dont like this here m_current_game = Common::Timer::GetTimeMs(); // no change, just update with clients @@ -581,17 +544,19 @@ bool NetPlayServer::StartGame(const std::string &path) // tell clients to start game sf::Packet spac; spac << (MessageId)NP_MSG_START_GAME; - spac << NetPlay::m_current_game; - spac << g_NetPlaySettings.m_DSPEnableJIT; - spac << g_NetPlaySettings.m_DSPHLE; - spac << g_NetPlaySettings.m_WriteToMemcard; + spac << m_current_game; + spac << m_settings.m_DSPEnableJIT; + spac << m_settings.m_DSPHLE; + spac << m_settings.m_WriteToMemcard; for (unsigned int i = 0; i < 4; ++i) - spac << g_NetPlaySettings.m_Controllers[i]; + spac << m_settings.m_Controllers[i]; std::lock_guard lkp(m_crit.players); std::lock_guard lks(m_crit.send); SendToClients(spac); + m_is_running = true; + return true; } @@ -599,9 +564,6 @@ bool NetPlayServer::StartGame(const std::string &path) // called from ---GUI--- thread bool NetPlayServer::StopGame() { - if (false == NetPlay::StopGame()) - return false; - // tell clients to stop game sf::Packet spac; spac << (MessageId)NP_MSG_STOP_GAME; diff --git a/Source/Core/Core/Src/NetPlayServer.h b/Source/Core/Core/Src/NetPlayServer.h new file mode 100644 index 0000000000..7bf114205c --- /dev/null +++ b/Source/Core/Core/Src/NetPlayServer.h @@ -0,0 +1,116 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#ifndef _NETPLAY_SERVER_H +#define _NETPLAY_SERVER_H + +#include "Common.h" +#include "CommonTypes.h" +#include "Thread.h" +#include "Timer.h" + +#include + +#include "NetPlayProto.h" + +#include +#include +#include +#include + +class NetPlayServer +{ +public: + void ThreadFunc(); + + NetPlayServer(const u16 port); + ~NetPlayServer(); + + void GetPlayerList(std::string& list, std::vector& pid_list); + + bool ChangeGame(const std::string& game); + void SendChatMessage(const std::string& msg); + + void SetNetSettings(const NetSettings &settings); + + bool StartGame(const std::string &path); + bool StopGame(); + + bool GetPadMapping(const int pid, int map[]); + bool SetPadMapping(const int pid, const int map[]); + + void AdjustPadBufferSize(unsigned int size); + + bool is_connected; + +#ifdef USE_UPNP + void TryPortmapping(u16 port); +#endif + +private: + class Client + { + public: + Client(); + std::string ToString() const; + + PlayerId pid; + std::string name; + PadMapping pad_map[4]; + std::string revision; + + sf::SocketTCP socket; + u64 ping; + u32 current_game; + }; + + void SendToClients(sf::Packet& packet, const PlayerId skip_pid = 0); + unsigned int OnConnect(sf::SocketTCP& socket); + unsigned int OnDisconnect(sf::SocketTCP& socket); + unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket); + void UpdatePadMapping(); + + NetSettings m_settings; + + bool m_is_running; + bool m_do_loop; + Common::Timer m_ping_timer; + u32 m_ping_key; + bool m_update_pings; + u32 m_current_game; + unsigned int m_target_buffer_size; + + std::map m_players; + + struct + { + std::recursive_mutex game; + // lock order + std::recursive_mutex players, send; + } m_crit; + + std::string m_selected_game; + + sf::SocketTCP m_socket; + std::thread m_thread; + sf::Selector m_selector; + +#ifdef USE_UPNP + static void mapPortThread(const u16 port); + static void unmapPortThread(); + + static bool initUPnP(); + static bool UPnPMapPort(const std::string& addr, const u16 port); + static bool UPnPUnmapPort(const u16 port); + + static struct UPNPUrls m_upnp_urls; + static struct IGDdatas m_upnp_data; + static u16 m_upnp_mapped; + static bool m_upnp_inited; + static bool m_upnp_error; + static std::thread m_upnp_thread; +#endif +}; + +#endif diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 22cd588236..32a6b44453 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -7,9 +7,11 @@ #include "WxUtils.h" #include "NetPlay.h" +#include "NetPlayServer.h" #include "NetWindow.h" #include "Frame.h" #include "Core.h" +#include "ConfigManager.h" #include #include @@ -20,7 +22,8 @@ BEGIN_EVENT_TABLE(NetPlayDiag, wxFrame) EVT_COMMAND(wxID_ANY, wxEVT_THREAD, NetPlayDiag::OnThread) END_EVENT_TABLE() -static NetPlay* netplay_ptr = NULL; +static NetPlayServer* netplay_server = NULL; +static NetPlayClient* netplay_client = NULL; extern CFrame* main_frame; NetPlayDiag *NetPlayDiag::npd = NULL; @@ -200,6 +203,28 @@ NetPlaySetupDiag::~NetPlaySetupDiag() main_frame->g_NetPlaySetupDiag = NULL; } +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()); + + netplay_client = new NetPlayClient(ip, (u16)port, npd, WxStrToStr(m_nickname_text->GetValue())); + if (netplay_client->is_connected) + { + npd->Show(); + Destroy(); + } + else + { + npd->Destroy(); + } +} + void NetPlaySetupDiag::OnHost(wxCommandEvent&) { NetPlayDiag *&npd = NetPlayDiag::GetInstance(); @@ -217,25 +242,19 @@ void NetPlaySetupDiag::OnHost(wxCommandEvent&) std::string game(WxStrToStr(m_game_lbox->GetStringSelection())); - npd = new NetPlayDiag(m_parent, m_game_list, game, true); unsigned long port = 0; m_host_port_text->GetValue().ToULong(&port); - netplay_ptr = new NetPlayServer(u16(port), WxStrToStr(m_nickname_text->GetValue()), npd); - netplay_ptr->ChangeGame(game); - if (netplay_ptr->is_connected) + netplay_server = new NetPlayServer(u16(port)); + netplay_server->ChangeGame(game); + if (netplay_server->is_connected) { #ifdef USE_UPNP if(m_upnp_chk->GetValue()) - ((NetPlayServer*)netplay_ptr)->TryPortmapping(port); + netplay_server->TryPortmapping(port); #endif - npd->Show(); - Destroy(); - } - else - { - PanicAlertT("Failed to Listen!!"); - npd->Destroy(); } + + MakeNetPlayDiag(port, game, true); } void NetPlaySetupDiag::OnJoin(wxCommandEvent&) @@ -247,20 +266,9 @@ void NetPlaySetupDiag::OnJoin(wxCommandEvent&) return; } - npd = new NetPlayDiag(m_parent, m_game_list, ""); unsigned long port = 0; m_connect_port_text->GetValue().ToULong(&port); - netplay_ptr = new NetPlayClient(WxStrToStr(m_connect_ip_text->GetValue()) - , (u16)port, npd, WxStrToStr(m_nickname_text->GetValue())); - if (netplay_ptr->is_connected) - { - npd->Show(); - Destroy(); - } - else - { - npd->Destroy(); - } + MakeNetPlayDiag(port, "", false); } void NetPlaySetupDiag::OnQuit(wxCommandEvent&) @@ -344,7 +352,6 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game } m_memcard_write = new wxCheckBox(panel, wxID_ANY, _("Write memcards (GC)")); - m_memcard_write->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &NetPlayDiag::OnMemcardWriteCheck, this); bottom_szr->Add(m_memcard_write, 0, wxCENTER); bottom_szr->AddStretchSpacer(1); @@ -366,10 +373,15 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game NetPlayDiag::~NetPlayDiag() { - if (netplay_ptr) + if (netplay_client) { - delete netplay_ptr; - netplay_ptr = NULL; + delete netplay_client; + netplay_client = NULL; + } + if (netplay_server) + { + delete netplay_server; + netplay_server = NULL; } npd = NULL; } @@ -380,37 +392,50 @@ void NetPlayDiag::OnChat(wxCommandEvent&) if (s.Length()) { - netplay_ptr->SendChatMessage(WxStrToStr(s)); + netplay_client->SendChatMessage(WxStrToStr(s)); m_chat_text->AppendText(s.Prepend(wxT(" >> ")).Append(wxT('\n'))); m_chat_msg_text->Clear(); } } -void NetPlayDiag::OnStart(wxCommandEvent&) +void NetPlayDiag::GetNetSettings(NetSettings &settings) +{ + SConfig &instance = SConfig::GetInstance(); + settings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE; + settings.m_DSPEnableJIT = instance.m_EnableJIT; + settings.m_WriteToMemcard = m_memcard_write->GetValue(); + + for (unsigned int i = 0; i < 4; ++i) + settings.m_Controllers[i] = SConfig::GetInstance().m_SIDevice[i]; +} + +const 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)) - { - netplay_ptr->StartGame(game->GetFileName()); - return; - } - } + return game->GetFileName(); PanicAlertT("Game not found!"); + return ""; +} + +void NetPlayDiag::OnStart(wxCommandEvent&) +{ + NetSettings settings; + GetNetSettings(settings); + netplay_server->SetNetSettings(settings); + netplay_server->StartGame(FindGame()); } void NetPlayDiag::OnStop(wxCommandEvent&) { - netplay_ptr->StopGame(); + netplay_server->StopGame(); } void NetPlayDiag::BootGame(const std::string& filename) { main_frame->BootGame(filename); - - Core::g_CoreStartupParameter.bEnableMemcardSaving = m_memcard_write->GetValue(); } void NetPlayDiag::StopGame() @@ -452,19 +477,14 @@ void NetPlayDiag::OnMsgStopGame() GetEventHandler()->AddPendingEvent(evt); } -void NetPlayDiag::OnMemcardWriteCheck(wxCommandEvent &event) -{ - netplay_ptr->SetMemcardWriteEnabled(m_memcard_write->GetValue()); -} - void NetPlayDiag::OnAdjustBuffer(wxCommandEvent& event) { const int val = ((wxSpinCtrl*)event.GetEventObject())->GetValue(); - ((NetPlayServer*)netplay_ptr)->AdjustPadBufferSize(val); + netplay_server->AdjustPadBufferSize(val); std::ostringstream ss; ss << "< Pad Buffer: " << val << " >"; - netplay_ptr->SendChatMessage(ss.str()); + netplay_client->SendChatMessage(ss.str()); m_chat_text->AppendText(StrToWxStr(ss.str()).Append(wxT('\n'))); } @@ -479,7 +499,7 @@ void NetPlayDiag::OnThread(wxCommandEvent& event) // player list m_playerids.clear(); std::string tmps; - netplay_ptr->GetPlayerList(tmps, m_playerids); + netplay_client->GetPlayerList(tmps, m_playerids); const int selection = m_player_lbox->GetSelection(); @@ -502,15 +522,13 @@ void NetPlayDiag::OnThread(wxCommandEvent& event) case NP_GUI_EVT_START_GAME : // client start game :/ { - wxCommandEvent evt; - OnStart(evt); + netplay_client->StartGame(FindGame()); } break; case NP_GUI_EVT_STOP_GAME : // client stop game { - wxCommandEvent evt; - OnStop(evt); + netplay_client->StopGame(); } break; } @@ -534,7 +552,7 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent&) if (game_name.length()) { m_selected_game = WxStrToStr(game_name); - netplay_ptr->ChangeGame(m_selected_game); + netplay_server->ChangeGame(m_selected_game); m_game_btn->SetLabel(game_name.Prepend(_(" Game : "))); } } @@ -549,13 +567,13 @@ void NetPlayDiag::OnConfigPads(wxCommandEvent&) return; pid = m_playerids.at(pid); - if (false == ((NetPlayServer*)netplay_ptr)->GetPadMapping(pid, mapping)) + if (false == netplay_server->GetPadMapping(pid, mapping)) return; PadMapDiag pmd(this, mapping); pmd.ShowModal(); - if (false == ((NetPlayServer*)netplay_ptr)->SetPadMapping(pid, mapping)) + if (false == netplay_server->SetPadMapping(pid, mapping)) PanicAlertT("Could not set pads. The player left or the game is currently running!\n" "(setting pads while the game is running is not yet supported)"); } diff --git a/Source/Core/DolphinWX/Src/NetWindow.h b/Source/Core/DolphinWX/Src/NetWindow.h index 76fbc03431..bc61a6df48 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.h +++ b/Source/Core/DolphinWX/Src/NetWindow.h @@ -42,6 +42,8 @@ private: void OnHost(wxCommandEvent& event); void OnQuit(wxCommandEvent& event); + void MakeNetPlayDiag(int port, const std::string &game, bool is_hosting); + wxTextCtrl *m_nickname_text, *m_host_port_text, *m_connect_port_text, @@ -85,11 +87,12 @@ private: void OnChat(wxCommandEvent& event); void OnQuit(wxCommandEvent& event); - void OnMemcardWriteCheck(wxCommandEvent& event); void OnThread(wxCommandEvent& event); void OnChangeGame(wxCommandEvent& event); void OnAdjustBuffer(wxCommandEvent& event); void OnConfigPads(wxCommandEvent& event); + void GetNetSettings(NetSettings &settings); + const std::string& FindGame(); wxListBox* m_player_lbox; wxTextCtrl* m_chat_text; From 9e63cebc935b13192cb5fe567c7413ae9c5ed2b1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 5 Aug 2013 04:56:30 -0400 Subject: [PATCH 3/6] NetPlay: Remove the base NetPlay class It's only used by the NetPlayClient. For now, keep around NetPlay.cpp, but we'll remove that soon. --- Source/Core/Core/Src/BootManager.cpp | 2 +- Source/Core/Core/Src/HW/SI.cpp | 4 +- Source/Core/Core/Src/NetPlay.cpp | 129 ++++++++----------------- Source/Core/Core/Src/NetPlay.h | 54 ++++------- Source/Core/Core/Src/NetPlayClient.cpp | 36 ++++++- 5 files changed, 95 insertions(+), 130 deletions(-) diff --git a/Source/Core/Core/Src/BootManager.cpp b/Source/Core/Core/Src/BootManager.cpp index c9a8568205..fff61f7c1e 100644 --- a/Source/Core/Core/Src/BootManager.cpp +++ b/Source/Core/Core/Src/BootManager.cpp @@ -138,7 +138,7 @@ bool BootCore(const std::string& _rFilename) } } - if (NetPlay::GetNetPlayPtr()) + if (NetPlay::IsNetPlayRunning()) { StartUp.bDSPHLE = g_NetPlaySettings.m_DSPHLE; StartUp.bEnableMemcardSaving = g_NetPlaySettings.m_WriteToMemcard; diff --git a/Source/Core/Core/Src/HW/SI.cpp b/Source/Core/Core/Src/HW/SI.cpp index 85c84f92dd..291215fe1c 100644 --- a/Source/Core/Core/Src/HW/SI.cpp +++ b/Source/Core/Core/Src/HW/SI.cpp @@ -262,7 +262,7 @@ void Init() if (Movie::IsRecordingInput() || Movie::IsPlayingInput()) AddDevice(Movie::IsUsingPad(i) ? (Movie::IsUsingBongo(i) ? SIDEVICE_GC_TARUKONGA : SIDEVICE_GC_CONTROLLER) : SIDEVICE_NONE, i); - else if (NetPlay::GetNetPlayPtr()) + else if (NetPlay::IsNetPlayRunning()) AddDevice((SIDevices) g_NetPlaySettings.m_Controllers[i], i); else AddDevice(SConfig::GetInstance().m_SIDevice[i], i); @@ -644,7 +644,7 @@ void RunSIBuffer() int GetTicksToNextSIPoll() { // Poll for input at regular intervals (once per frame) when playing or recording a movie - if (Movie::IsPlayingInput() || Movie::IsRecordingInput() || NetPlay::GetNetPlayPtr()) + if (Movie::IsPlayingInput() || Movie::IsRecordingInput() || NetPlay::IsNetPlayRunning()) { return SystemTimers::GetTicksPerSecond() / VideoInterface::TargetRefreshRate; } diff --git a/Source/Core/Core/Src/NetPlay.cpp b/Source/Core/Core/Src/NetPlay.cpp index d192a19506..ba0eca0b50 100644 --- a/Source/Core/Core/Src/NetPlay.cpp +++ b/Source/Core/Core/Src/NetPlay.cpp @@ -17,50 +17,19 @@ #include "Core.h" #include "ConfigManager.h" -std::mutex crit_netplay_ptr; -static NetPlay* netplay_ptr = NULL; +std::mutex crit_netplay_client; +static NetPlayClient * netplay_client = NULL; NetSettings g_NetPlaySettings; #define RPT_SIZE_HACK (1 << 16) -// called from ---GUI--- thread -NetPlay::NetPlay(NetPlayUI* dialog) - : m_dialog(dialog), m_is_running(false), m_do_loop(true) -{ - m_target_buffer_size = 20; - ClearBuffers(); -} - -void NetPlay_Enable(NetPlay* const np) -{ - std::lock_guard lk(crit_netplay_ptr); - netplay_ptr = np; -} - -void NetPlay_Disable() -{ - std::lock_guard lk(crit_netplay_ptr); - netplay_ptr = NULL; -} - -// called from ---GUI--- thread -NetPlay::~NetPlay() -{ - std::lock_guard lk(crit_netplay_ptr); - netplay_ptr = NULL; - - // not perfect - if (m_is_running) - StopGame(); -} - -NetPlay::Player::Player() +NetPlayClient::Player::Player() { memset(pad_map, -1, sizeof(pad_map)); } // called from ---GUI--- thread -std::string NetPlay::Player::ToString() const +std::string NetPlayClient::Player::ToString() const { std::ostringstream ss; ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |"; @@ -89,7 +58,7 @@ NetPad::NetPad(const SPADStatus* const pad_status) } // called from ---NETPLAY--- thread -void NetPlay::ClearBuffers() +void NetPlayClient::ClearBuffers() { // clear pad buffers, Clear method isn't thread safe for (unsigned int i=0; i<4; ++i) @@ -105,7 +74,7 @@ void NetPlay::ClearBuffers() } // called from ---CPU--- thread -bool NetPlay::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues) +bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues) { { std::lock_guard lkp(m_crit.players); @@ -161,7 +130,7 @@ bool NetPlay::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, Ne } // called from ---CPU--- thread -void NetPlay::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size) +void NetPlayClient::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size) { //// in game mapping for this local wiimote unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now @@ -176,7 +145,7 @@ void NetPlay::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 } // called from ---CPU--- thread -void NetPlay::WiimoteUpdate(int _number) +void NetPlayClient::WiimoteUpdate(int _number) { { std::lock_guard lkp(m_crit.players); @@ -211,36 +180,8 @@ void NetPlay::WiimoteUpdate(int _number) Core::Callback_WiimoteInterruptChannel(_number, i->channel, &(*i)[0], (u32)i->size() + RPT_SIZE_HACK); } -// called from ---GUI--- thread -bool NetPlay::StartGame(const std::string &path) -{ - if (m_is_running) - { - PanicAlertT("Game is already running!"); - return false; - } - - m_dialog->AppendChat(" -- STARTING GAME -- "); - - m_is_running = true; - NetPlay_Enable(this); - - ClearBuffers(); - - // boot game - m_dialog->BootGame(path); - - // temporary - NetWiimote nw; - for (unsigned int i = 0; i<4; ++i) - for (unsigned int f = 0; f<2; ++f) - m_wiimote_buffer[i].Push(nw); - - return true; -} - // called from ---GUI--- thread and ---NETPLAY--- thread (client side) -bool NetPlay::StopGame() +bool NetPlayClient::StopGame() { std::lock_guard lkg(m_crit.game); @@ -262,7 +203,7 @@ bool NetPlay::StopGame() } // called from ---CPU--- thread -u8 NetPlay::GetPadNum(u8 numPAD) +u8 NetPlayClient::GetPadNum(u8 numPAD) { // TODO: i don't like that this loop is running everytime there is rumble unsigned int i = 0; @@ -279,10 +220,10 @@ u8 NetPlay::GetPadNum(u8 numPAD) // Actual Core function which is called on every frame bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) { - std::lock_guard lk(crit_netplay_ptr); + std::lock_guard lk(crit_netplay_client); - if (netplay_ptr) - return netplay_ptr->GetNetPads(numPAD, &PadStatus, (NetPad*)PADStatus); + if (netplay_client) + return netplay_client->GetNetPads(numPAD, &PadStatus, (NetPad*)PADStatus); else return false; } @@ -301,9 +242,9 @@ bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 * // so all players' games get the same time u32 CEXIIPL::NetPlay_GetGCTime() { - std::lock_guard lk(crit_netplay_ptr); + std::lock_guard lk(crit_netplay_client); - if (netplay_ptr) + if (netplay_client) return 1272737767; // watev else return 0; @@ -313,10 +254,10 @@ u32 CEXIIPL::NetPlay_GetGCTime() // return the local pad num that should rumble given a ingame pad num u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD) { - std::lock_guard lk(crit_netplay_ptr); + std::lock_guard lk(crit_netplay_client); - if (netplay_ptr) - return netplay_ptr->GetPadNum(numPAD); + if (netplay_client) + return netplay_client->GetPadNum(numPAD); else return numPAD; } @@ -336,20 +277,20 @@ u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD) //void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number) void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int) { - //CritLocker crit(crit_netplay_ptr); + //CritLocker crit(crit_netplay_client); - //if (netplay_ptr) - // netplay_ptr->WiimoteUpdate(_number); + //if (netplay_client) + // netplay_client->WiimoteUpdate(_number); } // called from ---CPU--- thread // int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number) { - //CritLocker crit(crit_netplay_ptr); + //CritLocker crit(crit_netplay_client); - //if (netplay_ptr) - // return netplay_ptr->GetPadNum(_number); // just using gcpad mapping for now + //if (netplay_client) + // return netplay_client->GetPadNum(_number); // just using gcpad mapping for now //else return _number; } @@ -359,9 +300,9 @@ int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number) //bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int _number, u16 _channelID, const void* _pData, u32& _Size) bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&) { - std::lock_guard lk(crit_netplay_ptr); + std::lock_guard lk(crit_netplay_client); - if (netplay_ptr) + if (netplay_client) //{ // if (_Size >= RPT_SIZE_HACK) // { @@ -370,7 +311,7 @@ bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&) // } // else // { - // netplay_ptr->WiimoteInput(_number, _channelID, _pData, _Size); + // netplay_client->WiimoteInput(_number, _channelID, _pData, _Size); // // don't use this packet return true; // } @@ -379,7 +320,19 @@ bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&) return false; } -NetPlay* NetPlay::GetNetPlayPtr() +bool NetPlay::IsNetPlayRunning() { - return netplay_ptr; + return netplay_client != NULL; +} + +void NetPlay_Enable(NetPlayClient* const np) +{ + std::lock_guard lk(crit_netplay_client); + netplay_client = np; +} + +void NetPlay_Disable() +{ + std::lock_guard lk(crit_netplay_client); + netplay_client = NULL; } diff --git a/Source/Core/Core/Src/NetPlay.h b/Source/Core/Core/Src/NetPlay.h index 68fb615850..18e98a2b9e 100644 --- a/Source/Core/Core/Src/NetPlay.h +++ b/Source/Core/Core/Src/NetPlay.h @@ -50,33 +50,32 @@ public: extern NetSettings g_NetPlaySettings; -class NetPlay +class NetPlayClient { public: - NetPlay(NetPlayUI* _dialog); - virtual ~NetPlay(); - //virtual void ThreadFunc() = 0; + void ThreadFunc(); + + NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name); + ~NetPlayClient(); + + void GetPlayerList(std::string& list, std::vector& pid_list); bool is_connected; - + + bool StartGame(const std::string &path); + bool StopGame(); + bool ChangeGame(const std::string& game); + void SendChatMessage(const std::string& msg); + // Send and receive pads values void WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size); void WiimoteUpdate(int _number); bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues); - virtual bool ChangeGame(const std::string& game) = 0; - virtual void GetPlayerList(std::string& list, std::vector& pid_list) = 0; - virtual void SendChatMessage(const std::string& msg) = 0; - - virtual bool StartGame(const std::string &path); - virtual bool StopGame(); u8 GetPadNum(u8 numPAD); - static NetPlay* GetNetPlayPtr(); protected: - //void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues); void ClearBuffers(); - virtual void SendPadState(const PadMapping local_nb, const NetPad& np) = 0; struct { @@ -116,26 +115,6 @@ protected: Player* m_local_player; u32 m_current_game; -}; - -void NetPlay_Enable(NetPlay* const np); -void NetPlay_Disable(); - -class NetPlayClient : public NetPlay -{ -public: - void ThreadFunc(); - - NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name); - ~NetPlayClient(); - - void GetPlayerList(std::string& list, std::vector& pid_list); - - // Send and receive pads values - //bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues); - bool StartGame(const std::string &path); - bool ChangeGame(const std::string& game); - void SendChatMessage(const std::string& msg); private: void SendPadState(const PadMapping local_nb, const NetPad& np); @@ -145,4 +124,11 @@ private: std::map m_players; }; +namespace NetPlay { + bool IsNetPlayRunning(); +}; + +void NetPlay_Enable(NetPlayClient* const np); +void NetPlay_Disable(); + #endif diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index 7163be001a..ec3b811034 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -7,16 +7,23 @@ // called from ---GUI--- thread NetPlayClient::~NetPlayClient() { + // not perfect + if (m_is_running) + StopGame(); + if (is_connected) { m_do_loop = false; m_thread.join(); - } + } } // called from ---GUI--- thread -NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name) : NetPlay(dialog) +NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name) : m_dialog(dialog), m_is_running(false), m_do_loop(true) { + m_target_buffer_size = 20; + ClearBuffers(); + is_connected = false; // why is false successful? documentation says true is @@ -328,12 +335,31 @@ bool NetPlayClient::StartGame(const std::string &path) spac << m_current_game; spac << (char *)&g_NetPlaySettings; - if (false == NetPlay::StartGame(path)) - return false; - std::lock_guard lks(m_crit.send); m_socket.Send(spac); + if (m_is_running) + { + PanicAlertT("Game is already running!"); + return false; + } + + m_dialog->AppendChat(" -- STARTING GAME -- "); + + m_is_running = true; + NetPlay_Enable(this); + + ClearBuffers(); + + // boot game + m_dialog->BootGame(path); + + // temporary + NetWiimote nw; + for (unsigned int i = 0; i<4; ++i) + for (unsigned int f = 0; f<2; ++f) + m_wiimote_buffer[i].Push(nw); + return true; } From a3a222bf5b4a19f82d3c4f3122038ae81a56c79b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 5 Aug 2013 05:05:06 -0400 Subject: [PATCH 4/6] NetPlay: Remove NetPlay.h / NetPlay.cpp Now the server and client implementations are entirely separate. --- Source/Core/Core/CMakeLists.txt | 1 - Source/Core/Core/Core.vcxproj | 6 +- Source/Core/Core/Core.vcxproj.filters | 13 +- Source/Core/Core/Src/BootManager.cpp | 2 +- Source/Core/Core/Src/HW/SI.cpp | 2 +- Source/Core/Core/Src/NetPlay.cpp | 338 ------------------ Source/Core/Core/Src/NetPlayClient.cpp | 335 ++++++++++++++++- .../Core/Src/{NetPlay.h => NetPlayClient.h} | 0 Source/Core/DolphinWX/Src/NetWindow.cpp | 2 +- Source/Core/DolphinWX/Src/NetWindow.h | 2 +- 10 files changed, 342 insertions(+), 359 deletions(-) delete mode 100644 Source/Core/Core/Src/NetPlay.cpp rename Source/Core/Core/Src/{NetPlay.h => NetPlayClient.h} (100%) diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 5474083132..bf8d86494e 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -10,7 +10,6 @@ set(SRCS Src/ActionReplay.cpp Src/GeckoCodeConfig.cpp Src/GeckoCode.cpp Src/Movie.cpp - Src/NetPlay.cpp Src/NetPlayClient.cpp Src/NetPlayServer.cpp Src/PatchEngine.cpp diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 53000b2cc9..964a6927e0 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -1,4 +1,4 @@ - + @@ -334,7 +334,6 @@ - @@ -540,7 +539,6 @@ - @@ -599,4 +597,4 @@ - \ No newline at end of file + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 75c592a685..f82b0d8832 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -529,9 +529,6 @@ HW %28Flipper/Hollywood%29\Wiimote - - NetPlay - NetPlay @@ -1014,9 +1011,6 @@ PowerPC - - NetPlay - FifoPlayer @@ -1177,9 +1171,6 @@ {1c21a3e1-b791-4a23-b0d5-ed2b2c34007f} - - {231ceb02-1122-402a-87a8-094a9ed768c2} - {ca7d56f7-4e84-4d15-9aea-7ae6fa7d6586} @@ -1187,4 +1178,4 @@ {3e9e6e83-c1bf-45f9-aeff-231f98f60d29} - \ No newline at end of file + diff --git a/Source/Core/Core/Src/BootManager.cpp b/Source/Core/Core/Src/BootManager.cpp index fff61f7c1e..c4bf6d485a 100644 --- a/Source/Core/Core/Src/BootManager.cpp +++ b/Source/Core/Core/Src/BootManager.cpp @@ -34,7 +34,7 @@ #include "Host.h" #include "VideoBackendBase.h" #include "Movie.h" -#include "NetPlay.h" +#include "NetPlayClient.h" namespace BootManager { diff --git a/Source/Core/Core/Src/HW/SI.cpp b/Source/Core/Core/Src/HW/SI.cpp index 291215fe1c..ebd839a8bf 100644 --- a/Source/Core/Core/Src/HW/SI.cpp +++ b/Source/Core/Core/Src/HW/SI.cpp @@ -7,7 +7,7 @@ #include "../ConfigManager.h" #include "../CoreTiming.h" #include "../Movie.h" -#include "../NetPlay.h" +#include "../NetPlayClient.h" #include "SystemTimers.h" #include "ProcessorInterface.h" diff --git a/Source/Core/Core/Src/NetPlay.cpp b/Source/Core/Core/Src/NetPlay.cpp deleted file mode 100644 index ba0eca0b50..0000000000 --- a/Source/Core/Core/Src/NetPlay.cpp +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 -// Refer to the license.txt file included. - -#include "NetPlay.h" - -// for wiimote -#include "IPC_HLE/WII_IPC_HLE_Device_usb.h" -#include "IPC_HLE/WII_IPC_HLE_WiiMote.h" -// for gcpad -#include "HW/SI_DeviceGCController.h" -#include "HW/SI_DeviceGCSteeringWheel.h" -#include "HW/SI_DeviceDanceMat.h" -// for gctime -#include "HW/EXI_DeviceIPL.h" -// for wiimote/ OSD messages -#include "Core.h" -#include "ConfigManager.h" - -std::mutex crit_netplay_client; -static NetPlayClient * netplay_client = NULL; -NetSettings g_NetPlaySettings; - -#define RPT_SIZE_HACK (1 << 16) - -NetPlayClient::Player::Player() -{ - memset(pad_map, -1, sizeof(pad_map)); -} - -// called from ---GUI--- thread -std::string NetPlayClient::Player::ToString() const -{ - std::ostringstream ss; - ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |"; - for (unsigned int i=0; i<4; ++i) - ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-'); - ss << '|'; - return ss.str(); -} - -NetPad::NetPad() -{ - nHi = 0x00808080; - nLo = 0x80800000; -} - -NetPad::NetPad(const SPADStatus* const pad_status) -{ - nHi = (u32)((u8)pad_status->stickY); - nHi |= (u32)((u8)pad_status->stickX << 8); - nHi |= (u32)((u16)pad_status->button << 16); - nHi |= 0x00800000; - nLo = (u8)pad_status->triggerRight; - nLo |= (u32)((u8)pad_status->triggerLeft << 8); - nLo |= (u32)((u8)pad_status->substickY << 16); - nLo |= (u32)((u8)pad_status->substickX << 24); -} - -// called from ---NETPLAY--- thread -void NetPlayClient::ClearBuffers() -{ - // clear pad buffers, Clear method isn't thread safe - for (unsigned int i=0; i<4; ++i) - { - while (m_pad_buffer[i].Size()) - m_pad_buffer[i].Pop(); - - while (m_wiimote_buffer[i].Size()) - m_wiimote_buffer[i].Pop(); - - m_wiimote_input[i].clear(); - } -} - -// called from ---CPU--- thread -bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues) -{ - { - std::lock_guard lkp(m_crit.players); - - // in game mapping for this local pad - unsigned int in_game_num = m_local_player->pad_map[pad_nb]; - - // does this local pad map in game? - if (in_game_num < 4) - { - NetPad np(pad_status); - - // adjust the buffer either up or down - // inserting multiple padstates or dropping states - while (m_pad_buffer[in_game_num].Size() <= m_target_buffer_size) - { - // add to buffer - m_pad_buffer[in_game_num].Push(np); - - // send - SendPadState(pad_nb, np); - } - } - - } // unlock players - - //Common::Timer bufftimer; - //bufftimer.Start(); - - // get padstate from buffer and send to game - while (!m_pad_buffer[pad_nb].Pop(*netvalues)) - { - // wait for receiving thread to push some data - Common::SleepCurrentThread(1); - - if (false == m_is_running) - return false; - - // TODO: check the time of bufftimer here, - // if it gets pretty high, ask the user if they want to disconnect - - } - - //u64 hangtime = bufftimer.GetTimeElapsed(); - //if (hangtime > 10) - //{ - // std::ostringstream ss; - // ss << "Pad " << (int)pad_nb << ": Had to wait " << hangtime << "ms for pad data. (increase pad Buffer maybe)"; - // Core::DisplayMessage(ss.str(), 1000); - //} - - return true; -} - -// called from ---CPU--- thread -void NetPlayClient::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size) -{ - //// in game mapping for this local wiimote - unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now - - // does this local pad map in game? - if (in_game_num < 4) - { - m_wiimote_input[_number].resize(m_wiimote_input[_number].size() + 1); - m_wiimote_input[_number].back().assign((char*)_pData, (char*)_pData + _Size); - m_wiimote_input[_number].back().channel = _channelID; - } -} - -// called from ---CPU--- thread -void NetPlayClient::WiimoteUpdate(int _number) -{ - { - std::lock_guard lkp(m_crit.players); - - // in game mapping for this local wiimote - unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now - - // does this local pad map in game? - if (in_game_num < 4) - { - m_wiimote_buffer[in_game_num].Push(m_wiimote_input[_number]); - - // TODO: send it - - m_wiimote_input[_number].clear(); - } - - } // unlock players - - if (0 == m_wiimote_buffer[_number].Size()) - { - //PanicAlert("PANIC"); - return; - } - - NetWiimote nw; - m_wiimote_buffer[_number].Pop(nw); - - NetWiimote::const_iterator - i = nw.begin(), e = nw.end(); - for ( ; i!=e; ++i) - Core::Callback_WiimoteInterruptChannel(_number, i->channel, &(*i)[0], (u32)i->size() + RPT_SIZE_HACK); -} - -// called from ---GUI--- thread and ---NETPLAY--- thread (client side) -bool NetPlayClient::StopGame() -{ - std::lock_guard lkg(m_crit.game); - - if (false == m_is_running) - { - PanicAlertT("Game isn't running!"); - return false; - } - - m_dialog->AppendChat(" -- STOPPING GAME -- "); - - m_is_running = false; - NetPlay_Disable(); - - // stop game - m_dialog->StopGame(); - - return true; -} - -// called from ---CPU--- thread -u8 NetPlayClient::GetPadNum(u8 numPAD) -{ - // TODO: i don't like that this loop is running everytime there is rumble - unsigned int i = 0; - for (; i<4; ++i) - if (numPAD == m_local_player->pad_map[i]) - break; - - return i; -} - -// stuff hacked into dolphin - -// called from ---CPU--- thread -// Actual Core function which is called on every frame -bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) -{ - std::lock_guard lk(crit_netplay_client); - - if (netplay_client) - return netplay_client->GetNetPads(numPAD, &PadStatus, (NetPad*)PADStatus); - else - return false; -} - -bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) -{ - return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); -} - -bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) -{ - return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); -} - -// called from ---CPU--- thread -// so all players' games get the same time -u32 CEXIIPL::NetPlay_GetGCTime() -{ - std::lock_guard lk(crit_netplay_client); - - if (netplay_client) - return 1272737767; // watev - else - return 0; -} - -// called from ---CPU--- thread -// return the local pad num that should rumble given a ingame pad num -u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD) -{ - std::lock_guard lk(crit_netplay_client); - - if (netplay_client) - return netplay_client->GetPadNum(numPAD); - else - return numPAD; -} - -u8 CSIDevice_GCSteeringWheel::NetPlay_GetPadNum(u8 numPAD) -{ - return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); -} - -u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD) -{ - return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); -} - -// called from ---CPU--- thread -// wiimote update / used for frame counting -//void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number) -void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int) -{ - //CritLocker crit(crit_netplay_client); - - //if (netplay_client) - // netplay_client->WiimoteUpdate(_number); -} - -// called from ---CPU--- thread -// -int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number) -{ - //CritLocker crit(crit_netplay_client); - - //if (netplay_client) - // return netplay_client->GetPadNum(_number); // just using gcpad mapping for now - //else - return _number; -} - -// called from ---CPU--- thread -// intercept wiimote input callback -//bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int _number, u16 _channelID, const void* _pData, u32& _Size) -bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&) -{ - std::lock_guard lk(crit_netplay_client); - - if (netplay_client) - //{ - // if (_Size >= RPT_SIZE_HACK) - // { - // _Size -= RPT_SIZE_HACK; - // return false; - // } - // else - // { - // netplay_client->WiimoteInput(_number, _channelID, _pData, _Size); - // // don't use this packet - return true; - // } - //} - else - return false; -} - -bool NetPlay::IsNetPlayRunning() -{ - return netplay_client != NULL; -} - -void NetPlay_Enable(NetPlayClient* const np) -{ - std::lock_guard lk(crit_netplay_client); - netplay_client = np; -} - -void NetPlay_Disable() -{ - std::lock_guard lk(crit_netplay_client); - netplay_client = NULL; -} diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index ec3b811034..62d0569ae9 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -2,7 +2,60 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include "NetPlay.h" +#include "NetPlayClient.h" + +// for wiimote +#include "IPC_HLE/WII_IPC_HLE_Device_usb.h" +#include "IPC_HLE/WII_IPC_HLE_WiiMote.h" +// for gcpad +#include "HW/SI_DeviceGCController.h" +#include "HW/SI_DeviceGCSteeringWheel.h" +#include "HW/SI_DeviceDanceMat.h" +// for gctime +#include "HW/EXI_DeviceIPL.h" +// for wiimote/ OSD messages +#include "Core.h" +#include "ConfigManager.h" + +std::mutex crit_netplay_client; +static NetPlayClient * netplay_client = NULL; +NetSettings g_NetPlaySettings; + +#define RPT_SIZE_HACK (1 << 16) + +NetPlayClient::Player::Player() +{ + memset(pad_map, -1, sizeof(pad_map)); +} + +// called from ---GUI--- thread +std::string NetPlayClient::Player::ToString() const +{ + std::ostringstream ss; + ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |"; + for (unsigned int i=0; i<4; ++i) + ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-'); + ss << '|'; + return ss.str(); +} + +NetPad::NetPad() +{ + nHi = 0x00808080; + nLo = 0x80800000; +} + +NetPad::NetPad(const SPADStatus* const pad_status) +{ + nHi = (u32)((u8)pad_status->stickY); + nHi |= (u32)((u8)pad_status->stickX << 8); + nHi |= (u32)((u16)pad_status->button << 16); + nHi |= 0x00800000; + nLo = (u8)pad_status->triggerRight; + nLo |= (u32)((u8)pad_status->triggerLeft << 8); + nLo |= (u32)((u8)pad_status->substickY << 16); + nLo |= (u32)((u8)pad_status->substickX << 24); +} // called from ---GUI--- thread NetPlayClient::~NetPlayClient() @@ -368,3 +421,283 @@ bool NetPlayClient::ChangeGame(const std::string&) { return true; } + +// called from ---NETPLAY--- thread +void NetPlayClient::ClearBuffers() +{ + // clear pad buffers, Clear method isn't thread safe + for (unsigned int i=0; i<4; ++i) + { + while (m_pad_buffer[i].Size()) + m_pad_buffer[i].Pop(); + + while (m_wiimote_buffer[i].Size()) + m_wiimote_buffer[i].Pop(); + + m_wiimote_input[i].clear(); + } +} + +// called from ---CPU--- thread +bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues) +{ + { + std::lock_guard lkp(m_crit.players); + + // in game mapping for this local pad + unsigned int in_game_num = m_local_player->pad_map[pad_nb]; + + // does this local pad map in game? + if (in_game_num < 4) + { + NetPad np(pad_status); + + // adjust the buffer either up or down + // inserting multiple padstates or dropping states + while (m_pad_buffer[in_game_num].Size() <= m_target_buffer_size) + { + // add to buffer + m_pad_buffer[in_game_num].Push(np); + + // send + SendPadState(pad_nb, np); + } + } + + } // unlock players + + //Common::Timer bufftimer; + //bufftimer.Start(); + + // get padstate from buffer and send to game + while (!m_pad_buffer[pad_nb].Pop(*netvalues)) + { + // wait for receiving thread to push some data + Common::SleepCurrentThread(1); + + if (false == m_is_running) + return false; + + // TODO: check the time of bufftimer here, + // if it gets pretty high, ask the user if they want to disconnect + + } + + //u64 hangtime = bufftimer.GetTimeElapsed(); + //if (hangtime > 10) + //{ + // std::ostringstream ss; + // ss << "Pad " << (int)pad_nb << ": Had to wait " << hangtime << "ms for pad data. (increase pad Buffer maybe)"; + // Core::DisplayMessage(ss.str(), 1000); + //} + + return true; +} + +// called from ---CPU--- thread +void NetPlayClient::WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size) +{ + //// in game mapping for this local wiimote + unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now + + // does this local pad map in game? + if (in_game_num < 4) + { + m_wiimote_input[_number].resize(m_wiimote_input[_number].size() + 1); + m_wiimote_input[_number].back().assign((char*)_pData, (char*)_pData + _Size); + m_wiimote_input[_number].back().channel = _channelID; + } +} + +// called from ---CPU--- thread +void NetPlayClient::WiimoteUpdate(int _number) +{ + { + std::lock_guard lkp(m_crit.players); + + // in game mapping for this local wiimote + unsigned int in_game_num = m_local_player->pad_map[_number]; // just using gc pad_map for now + + // does this local pad map in game? + if (in_game_num < 4) + { + m_wiimote_buffer[in_game_num].Push(m_wiimote_input[_number]); + + // TODO: send it + + m_wiimote_input[_number].clear(); + } + + } // unlock players + + if (0 == m_wiimote_buffer[_number].Size()) + { + //PanicAlert("PANIC"); + return; + } + + NetWiimote nw; + m_wiimote_buffer[_number].Pop(nw); + + NetWiimote::const_iterator + i = nw.begin(), e = nw.end(); + for ( ; i!=e; ++i) + Core::Callback_WiimoteInterruptChannel(_number, i->channel, &(*i)[0], (u32)i->size() + RPT_SIZE_HACK); +} + +// called from ---GUI--- thread and ---NETPLAY--- thread (client side) +bool NetPlayClient::StopGame() +{ + std::lock_guard lkg(m_crit.game); + + if (false == m_is_running) + { + PanicAlertT("Game isn't running!"); + return false; + } + + m_dialog->AppendChat(" -- STOPPING GAME -- "); + + m_is_running = false; + NetPlay_Disable(); + + // stop game + m_dialog->StopGame(); + + return true; +} + +// called from ---CPU--- thread +u8 NetPlayClient::GetPadNum(u8 numPAD) +{ + // TODO: i don't like that this loop is running everytime there is rumble + unsigned int i = 0; + for (; i<4; ++i) + if (numPAD == m_local_player->pad_map[i]) + break; + + return i; +} + +// stuff hacked into dolphin + +// called from ---CPU--- thread +// Actual Core function which is called on every frame +bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) +{ + std::lock_guard lk(crit_netplay_client); + + if (netplay_client) + return netplay_client->GetNetPads(numPAD, &PadStatus, (NetPad*)PADStatus); + else + return false; +} + +bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) +{ + return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); +} + +bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) +{ + return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); +} + +// called from ---CPU--- thread +// so all players' games get the same time +u32 CEXIIPL::NetPlay_GetGCTime() +{ + std::lock_guard lk(crit_netplay_client); + + if (netplay_client) + return 1272737767; // watev + else + return 0; +} + +// called from ---CPU--- thread +// return the local pad num that should rumble given a ingame pad num +u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD) +{ + std::lock_guard lk(crit_netplay_client); + + if (netplay_client) + return netplay_client->GetPadNum(numPAD); + else + return numPAD; +} + +u8 CSIDevice_GCSteeringWheel::NetPlay_GetPadNum(u8 numPAD) +{ + return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); +} + +u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD) +{ + return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); +} + +// called from ---CPU--- thread +// wiimote update / used for frame counting +//void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number) +void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int) +{ + //CritLocker crit(crit_netplay_client); + + //if (netplay_client) + // netplay_client->WiimoteUpdate(_number); +} + +// called from ---CPU--- thread +// +int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number) +{ + //CritLocker crit(crit_netplay_client); + + //if (netplay_client) + // return netplay_client->GetPadNum(_number); // just using gcpad mapping for now + //else + return _number; +} + +// called from ---CPU--- thread +// intercept wiimote input callback +//bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int _number, u16 _channelID, const void* _pData, u32& _Size) +bool CWII_IPC_HLE_WiiMote::NetPlay_WiimoteInput(int, u16, const void*, u32&) +{ + std::lock_guard lk(crit_netplay_client); + + if (netplay_client) + //{ + // if (_Size >= RPT_SIZE_HACK) + // { + // _Size -= RPT_SIZE_HACK; + // return false; + // } + // else + // { + // netplay_client->WiimoteInput(_number, _channelID, _pData, _Size); + // // don't use this packet + return true; + // } + //} + else + return false; +} + +bool NetPlay::IsNetPlayRunning() +{ + return netplay_client != NULL; +} + +void NetPlay_Enable(NetPlayClient* const np) +{ + std::lock_guard lk(crit_netplay_client); + netplay_client = np; +} + +void NetPlay_Disable() +{ + std::lock_guard lk(crit_netplay_client); + netplay_client = NULL; +} diff --git a/Source/Core/Core/Src/NetPlay.h b/Source/Core/Core/Src/NetPlayClient.h similarity index 100% rename from Source/Core/Core/Src/NetPlay.h rename to Source/Core/Core/Src/NetPlayClient.h diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 32a6b44453..1c8f0549b9 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -6,7 +6,7 @@ #include #include "WxUtils.h" -#include "NetPlay.h" +#include "NetPlayClient.h" #include "NetPlayServer.h" #include "NetWindow.h" #include "Frame.h" diff --git a/Source/Core/DolphinWX/Src/NetWindow.h b/Source/Core/DolphinWX/Src/NetWindow.h index bc61a6df48..543c164994 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.h +++ b/Source/Core/DolphinWX/Src/NetWindow.h @@ -23,7 +23,7 @@ #include "FifoQueue.h" -#include "NetPlay.h" +#include "NetPlayClient.h" enum { From 59ab60f37f300161f666ec87dad51da123504499 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 5 Aug 2013 05:50:26 -0400 Subject: [PATCH 5/6] NetPlay: Supply every player's ping data to the client This means that we now have feature parity with the combined server before. --- Source/Core/Core/Src/NetPlayClient.cpp | 17 ++++++++++++++++- Source/Core/Core/Src/NetPlayClient.h | 1 + Source/Core/Core/Src/NetPlayProto.h | 3 ++- Source/Core/Core/Src/NetPlayServer.cpp | 8 ++++++++ Source/Core/Core/Src/NetPlayServer.h | 2 +- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index 62d0569ae9..e10cc25186 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -35,7 +35,7 @@ std::string NetPlayClient::Player::ToString() const ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |"; for (unsigned int i=0; i<4; ++i) ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-'); - ss << '|'; + ss << " | " << ping << "ms"; return ss.str(); } @@ -293,6 +293,21 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) } break; + case NP_MSG_PLAYER_PING_DATA: + { + PlayerId pid; + packet >> pid; + + { + std::lock_guard lkp(m_crit.players); + Player& player = m_players[pid]; + packet >> player.ping; + } + + m_dialog->Update(); + } + break; + default : PanicAlertT("Unknown message received with id : %d", mid); break; diff --git a/Source/Core/Core/Src/NetPlayClient.h b/Source/Core/Core/Src/NetPlayClient.h index 18e98a2b9e..d44a4c84b8 100644 --- a/Source/Core/Core/Src/NetPlayClient.h +++ b/Source/Core/Core/Src/NetPlayClient.h @@ -94,6 +94,7 @@ protected: std::string name; PadMapping pad_map[4]; std::string revision; + u32 ping; }; Common::FifoQueue m_pad_buffer[4]; diff --git a/Source/Core/Core/Src/NetPlayProto.h b/Source/Core/Core/Src/NetPlayProto.h index fc2031a0f0..84e2b420fd 100644 --- a/Source/Core/Core/Src/NetPlayProto.h +++ b/Source/Core/Core/Src/NetPlayProto.h @@ -23,7 +23,7 @@ struct Rpt : public std::vector typedef std::vector NetWiimote; -#define NETPLAY_VERSION "Dolphin NetPlay 2013-07-19" +#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-05" // messages enum @@ -50,6 +50,7 @@ enum NP_MSG_PING = 0xE0, NP_MSG_PONG = 0xE1, + NP_MSG_PLAYER_PING_DATA = 0xE2, }; typedef u8 MessageId; diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index affffac1eb..00f35d6ac7 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -456,6 +456,14 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) if (m_ping_key == ping_key) player.ping = ping; + + sf::Packet spac; + spac << (MessageId)NP_MSG_PLAYER_PING_DATA; + spac << player.pid; + spac << player.ping; + + std::lock_guard lks(m_crit.send); + SendToClients(spac); } break; diff --git a/Source/Core/Core/Src/NetPlayServer.h b/Source/Core/Core/Src/NetPlayServer.h index 7bf114205c..95f98e2a73 100644 --- a/Source/Core/Core/Src/NetPlayServer.h +++ b/Source/Core/Core/Src/NetPlayServer.h @@ -61,7 +61,7 @@ private: std::string revision; sf::SocketTCP socket; - u64 ping; + u32 ping; u32 current_game; }; From 9f90cbee1981b90c434a3bc085b074b6121a3451 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 5 Aug 2013 06:20:00 -0400 Subject: [PATCH 6/6] NetPlayServer: Close the socket when we're done with it This would allow a new socket to be created with the same port after we close it. However, we can't reuse it immediately because of the TCP TIME-WAIT state. --- Source/Core/Core/Src/NetPlayServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index 00f35d6ac7..505e6a8f76 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -26,6 +26,7 @@ NetPlayServer::~NetPlayServer() { m_do_loop = false; m_thread.join(); + m_socket.Close(); } #ifdef USE_UPNP