From d0f05291e7eee2c58f9beaa85e4f8933965773f2 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Tue, 6 Aug 2013 23:48:52 -0400 Subject: [PATCH 1/7] Add wiimote support to netplay. --- .../Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp | 11 +- .../Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.h | 1 + .../Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp | 1 - .../Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp | 2 - Source/Core/Core/Src/NetPlayClient.cpp | 189 +++++++++++++----- Source/Core/Core/Src/NetPlayClient.h | 5 +- Source/Core/Core/Src/NetPlayProto.h | 11 +- Source/Core/Core/Src/NetPlayServer.cpp | 125 +++++++++++- Source/Core/Core/Src/NetPlayServer.h | 5 + Source/Core/DolphinWX/Src/NetWindow.cpp | 38 +++- Source/Core/DolphinWX/Src/NetWindow.h | 5 +- 11 files changed, 317 insertions(+), 76 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp index eb5ebc2be5..94e7d88cd6 100644 --- a/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp @@ -27,6 +27,7 @@ inline double round(double x) { return (x-floor(x))>0.5 ? ceil(x) : floor(x); } #include "MatrixMath.h" #include "../../Movie.h" +#include "NetPlayClient.h" namespace { @@ -339,7 +340,7 @@ bool Wiimote::Step() m_rumble->controls[0]->control_ref->State(m_rumble_on); // when a movie is active, this button status update is disabled (moved), because movies only record data reports. - if(!(Movie::IsPlayingInput() || Movie::IsRecordingInput())) + if(!(Movie::IsPlayingInput() || Movie::IsRecordingInput()) || NetPlay::IsNetPlayRunning()) { UpdateButtonsStatus(has_focus); } @@ -397,7 +398,7 @@ void Wiimote::UpdateButtonsStatus(bool has_focus) void Wiimote::GetCoreData(u8* const data) { // when a movie is active, the button update happens here instead of Wiimote::Step, to avoid potential desync issues. - if(Movie::IsPlayingInput() || Movie::IsRecordingInput()) + if(Movie::IsPlayingInput() || Movie::IsRecordingInput() || NetPlay::IsNetPlayRunning()) { UpdateButtonsStatus(HAS_FOCUS); } @@ -770,6 +771,12 @@ void Wiimote::Update() } } } + if (NetPlay::IsNetPlayRunning()) + { + NetPlay_GetWiimoteData(m_index, data, rptf.size); + if (rptf.core) + m_status.buttons = *(wm_core*)(data + rptf.core); + } if (!Movie::IsPlayingInput()) { Movie::CheckWiimoteStatus(m_index, data, rptf, m_reg_ir.mode); diff --git a/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.h index 2fd471978e..9ed58f8b48 100644 --- a/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.h @@ -158,6 +158,7 @@ private: void WriteData(const wm_write_data* const wd); void SendReadDataReply(ReadRequest& _request); void SpeakerData(wm_speaker_data* sd); + bool NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size); // control groups Buttons *m_buttons, *m_dpad, *m_shake; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index 9bef545257..a2d5768039 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -494,7 +494,6 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() for (unsigned int i = 0; i < m_WiiMotes.size(); i++) if (m_WiiMotes[i].IsConnected()) { - NetPlay_WiimoteUpdate(i); Wiimote::Update(i); } m_last_ticks = now; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp index 9386682106..4adec84469 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp @@ -862,8 +862,6 @@ void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLeng void CWII_IPC_HLE_WiiMote::ReceiveL2capData(u16 scid, const void* _pData, u32 _Size) { - if (NetPlay_WiimoteInput(m_ConnectionHandle & 0xFF, scid, _pData, _Size)) - return; // Allocate DataFrame u8 DataFrame[1024]; diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index e10cc25186..cefb0ebe16 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -16,6 +16,7 @@ // for wiimote/ OSD messages #include "Core.h" #include "ConfigManager.h" +#include "HW/WiimoteEmu/WiimoteEmu.h" std::mutex crit_netplay_client; static NetPlayClient * netplay_client = NULL; @@ -26,6 +27,7 @@ NetSettings g_NetPlaySettings; NetPlayClient::Player::Player() { memset(pad_map, -1, sizeof(pad_map)); + memset(wiimote_map, -1, sizeof(wiimote_map)); } // called from ---GUI--- thread @@ -35,6 +37,8 @@ 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') : '-'); + for (unsigned int i=0; i<4; ++i) + ss << (wiimote_map[i]>=0 ? (char)(wiimote_map[i]+'1') : '-'); ss << " | " << ping << "ms"; return ss.str(); } @@ -215,6 +219,23 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) } break; + case NP_MSG_WIIMOTE_MAPPING : + { + PlayerId pid; + packet >> pid; + + { + std::lock_guard lkp(m_crit.players); + Player& player = m_players[pid]; + + for (unsigned int i=0; i<4; ++i) + packet >> player.wiimote_map[i]; + } + + m_dialog->Update(); + } + break; + case NP_MSG_PAD_DATA : { PadMapping map = 0; @@ -227,6 +248,27 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) } break; + case NP_MSG_WIIMOTE_DATA : + { + PadMapping map = 0; + NetWiimote nw; + u8 size; + packet >> map >> size; + + nw.size = size; + u8* data = new u8[size]; + for (unsigned int i = 0; i < size; ++i) + packet >> data[i]; + nw.data.assign(data,data+size); + delete[] data; + + // trusting server for good map value (>=0 && <4) + // add to pad buffer + m_wiimote_buffer[(unsigned)map].Push(nw); + } + break; + + case NP_MSG_PAD_BUFFER : { u32 size = 0; @@ -392,11 +434,34 @@ void NetPlayClient::SendPadState(const PadMapping local_nb, const NetPad& np) m_socket.Send(spac); } +// called from ---CPU--- thread +void NetPlayClient::SendWiimoteState(const PadMapping local_nb, const NetWiimote& nw) +{ + // send to server + sf::Packet spac; + spac << (MessageId)NP_MSG_WIIMOTE_DATA; + spac << local_nb; // local pad num + u8 size = nw.size; + spac << size; + for (unsigned int i = 0; i < size; ++i) + spac << nw.data.data()[i]; + + std::lock_guard lks(m_crit.send); + m_socket.Send(spac); +} + // called from ---GUI--- thread bool NetPlayClient::StartGame(const std::string &path) { std::lock_guard lkg(m_crit.game); + //wtf? + if (m_target_buffer_size > 100) + { + m_target_buffer_size = 20; + NOTICE_LOG(NETPLAY,"WHYYYYYYYYYYYY"); + } + // tell server i started the game sf::Packet spac; spac << (MessageId)NP_MSG_START_GAME; @@ -423,10 +488,10 @@ bool NetPlayClient::StartGame(const std::string &path) 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); + //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; } @@ -449,7 +514,7 @@ void NetPlayClient::ClearBuffers() while (m_wiimote_buffer[i].Size()) m_wiimote_buffer[i].Pop(); - m_wiimote_input[i].clear(); + m_wiimote_input[i].data.clear(); } } @@ -509,55 +574,77 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_stat 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) +bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) { { 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 + unsigned int in_game_num = m_local_player->wiimote_map[_number]; // does this local pad map in game? if (in_game_num < 4) { - m_wiimote_buffer[in_game_num].Push(m_wiimote_input[_number]); + static u8 previousSize = 0; - // TODO: send it + if (previousSize != size && m_wiimote_buffer[in_game_num].Size() > 0) + { + // Reporting mode changed, so previous buffer is no good. + m_wiimote_buffer[_number].Clear(); + } + + //m_wiimote_input[in_game_num].data.resize(m_wiimote_input[_number].size + 1); + m_wiimote_input[in_game_num].data.assign(data, data + size); + m_wiimote_input[in_game_num].size = size; + while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size) + { + // add to buffer + m_wiimote_buffer[in_game_num].Push(m_wiimote_input[in_game_num]); - m_wiimote_input[_number].clear(); + // send + SendWiimoteState(_number, m_wiimote_input[_number]); + } + previousSize = size; } } // unlock players - if (0 == m_wiimote_buffer[_number].Size()) + NetWiimote nw; + while (!m_wiimote_buffer[_number].Pop(nw)) { - //PanicAlert("PANIC"); - return; + // wait for receiving thread to push some data + Common::SleepCurrentThread(1); + if (false == m_is_running) + return false; } - NetWiimote nw; - m_wiimote_buffer[_number].Pop(nw); + // This is either a desync, or the reporting mode changed. No way to really be sure... + if (size != nw.size) + { + // Clear the buffer and wait for new input, in case it was just the reporting mode changing as expected. + do + { + m_wiimote_buffer[_number].Pop(nw); + Common::SleepCurrentThread(1); + if (false == m_is_running) + return false; - 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); + // TODO: break if this runs too long; it probably desynced if it runs for longer than the buffer size + } while (nw.size != size); + + // If it still mismatches, it surely desynced + if (size != nw.size) + { + PanicAlert("Netplay has desynced. There is no way to handle this. Self destructing in 3...2...1..."); + StopGame(); + return false; + } + } + + memcpy(data, nw.data.data(), size); + return true; } // called from ---GUI--- thread and ---NETPLAY--- thread (client side) @@ -586,12 +673,9 @@ bool NetPlayClient::StopGame() 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) + for (unsigned int i = 0; i<4; ++i) if (numPAD == m_local_player->pad_map[i]) - break; - - return i; + return i; } // stuff hacked into dolphin @@ -608,6 +692,16 @@ bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u return false; } +bool WiimoteEmu::Wiimote::NetPlay_GetWiimoteData(int wiimote, u8* data, u8 size) +{ + std::lock_guard lk(crit_netplay_client); + + if (netplay_client) + return netplay_client->WiimoteUpdate(wiimote, data, size); + else + return false; +} + bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) { return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); @@ -652,26 +746,15 @@ 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); +// std::lock_guard lk(crit_netplay_client); - //if (netplay_client) - // return netplay_client->GetPadNum(_number); // just using gcpad mapping for now - //else +// if (netplay_client) +// return netplay_client->GetPadNum(_number+4); +// else return _number; } diff --git a/Source/Core/Core/Src/NetPlayClient.h b/Source/Core/Core/Src/NetPlayClient.h index d44a4c84b8..625c20b951 100644 --- a/Source/Core/Core/Src/NetPlayClient.h +++ b/Source/Core/Core/Src/NetPlayClient.h @@ -68,8 +68,7 @@ public: 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 WiimoteUpdate(int _number, u8* data, u8 size); bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues); u8 GetPadNum(u8 numPAD); @@ -93,6 +92,7 @@ protected: PlayerId pid; std::string name; PadMapping pad_map[4]; + PadMapping wiimote_map[4]; std::string revision; u32 ping; }; @@ -119,6 +119,7 @@ protected: private: void SendPadState(const PadMapping local_nb, const NetPad& np); + void SendWiimoteState(const PadMapping local_nb, const NetWiimote& nw); unsigned int OnData(sf::Packet& packet); PlayerId m_pid; diff --git a/Source/Core/Core/Src/NetPlayProto.h b/Source/Core/Core/Src/NetPlayProto.h index 84e2b420fd..b1c4c481d9 100644 --- a/Source/Core/Core/Src/NetPlayProto.h +++ b/Source/Core/Core/Src/NetPlayProto.h @@ -16,14 +16,13 @@ struct NetSettings u8 m_Controllers[4]; }; -struct Rpt : public std::vector +struct NetWiimote { - u16 channel; + u8 size; + std::vector data; }; -typedef std::vector NetWiimote; - -#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-05" +#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-06 now with wiimote(TM)" // messages enum @@ -38,7 +37,7 @@ enum NP_MSG_PAD_BUFFER = 0x62, NP_MSG_WIIMOTE_DATA = 0x70, - NP_MSG_WIIMOTE_MAPPING = 0x71, // just using pad mapping for now + NP_MSG_WIIMOTE_MAPPING = 0x71, NP_MSG_START_GAME = 0xA0, NP_MSG_CHANGE_GAME = 0xA1, diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index 505e6a8f76..5eb5288c15 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -7,6 +7,7 @@ NetPlayServer::Client::Client() { memset(pad_map, -1, sizeof(pad_map)); + memset(wiimote_map, -1, sizeof(wiimote_map)); } // called from ---GUI--- thread @@ -16,6 +17,8 @@ std::string NetPlayServer::Client::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') : '-'); + for (unsigned int i=0; i<4; ++i) + ss << (wiimote_map[i]>=0 ? (char)(wiimote_map[i]+'1') : '-'); ss << '|'; return ss.str(); } @@ -311,6 +314,27 @@ bool NetPlayServer::GetPadMapping(const int pid, int map[]) return true; } +bool NetPlayServer::GetWiimoteMapping(const int pid, int map[]) +{ + std::lock_guard lkp(m_crit.players); + std::map::const_iterator + i = m_players.begin(), + e = m_players.end(); + for (; i!=e; ++i) + if (pid == i->second.pid) + break; + + // player not found + if (i == e) + return false; + + // get pad mapping + for (unsigned int m = 0; m<4; ++m) + map[m] = i->second.wiimote_map[m]; + + return true; +} + // called from ---GUI--- thread bool NetPlayServer::SetPadMapping(const int pid, const int map[]) { @@ -351,6 +375,46 @@ bool NetPlayServer::SetPadMapping(const int pid, const int map[]) return true; } +// called from ---GUI--- thread +bool NetPlayServer::SetWiimoteMapping(const int pid, const int map[]) +{ + std::lock_guard lkg(m_crit.game); + if (m_is_running) + return false; + + std::lock_guard lkp(m_crit.players); + std::map::iterator + i = m_players.begin(), + e = m_players.end(); + for (; i!=e; ++i) + if (pid == i->second.pid) + break; + + // player not found + if (i == e) + return false; + + Client& player = i->second; + + // set pad mapping + for (unsigned int m = 0; m<4; ++m) + { + player.wiimote_map[m] = (PadMapping)map[m]; + + // remove duplicate mappings + for (i = m_players.begin(); i!=e; ++i) + for (unsigned int p = 0; p<4; ++p) + if (p != m || i->second.pid != pid) + if (player.wiimote_map[m] == i->second.wiimote_map[p]) + i->second.wiimote_map[p] = -1; + } + + std::lock_guard lks(m_crit.send); + UpdateWiimoteMapping(); // sync pad mappings with everyone + + return true; +} + // called from ---NETPLAY--- thread void NetPlayServer::UpdatePadMapping() { @@ -369,6 +433,24 @@ void NetPlayServer::UpdatePadMapping() } +// called from ---NETPLAY--- thread +void NetPlayServer::UpdateWiimoteMapping() +{ + std::map::const_iterator + i = m_players.begin(), + e = m_players.end(); + for (; i!=e; ++i) + { + sf::Packet spac; + spac << (MessageId)NP_MSG_WIIMOTE_MAPPING; + spac << i->second.pid; + for (unsigned int pm = 0; pm<4; ++pm) + spac << i->second.wiimote_map[pm]; + SendToClients(spac); + } + +} + // called from ---GUI--- thread and ---NETPLAY--- thread void NetPlayServer::AdjustPadBufferSize(unsigned int size) { @@ -431,12 +513,12 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) map = player.pad_map[(unsigned)map]; else map = -1; - + // if not, they are hacking, so disconnect them // this could happen right after a pad map change, but that isn't implemented yet if (map < 0) return 1; - + // relay to clients sf::Packet spac; @@ -449,6 +531,45 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) } break; + case NP_MSG_WIIMOTE_DATA : + { + // if this is pad data from the last game still being received, ignore it + if (player.current_game != m_current_game) + break; + + PadMapping map = 0; + u8 size; + packet >> map >> size; + u8* data = new u8[size]; + for (unsigned int i = 0; i < size; ++i) + packet >> data[i]; + + // check if client's pad indeed maps in game + if (map >= 0 && map < 4) + map = player.wiimote_map[(unsigned)map]; + else + map = -1; + + // if not, they are hacking, so disconnect them + // this could happen right after a pad map change, but that isn't implemented yet + if (map < 0) + return 1; + + // relay to clients + sf::Packet spac; + spac << (MessageId)NP_MSG_WIIMOTE_DATA; + spac << map; // in game mapping + spac << size; + for (unsigned int i = 0; i < size; ++i) + spac << data[i]; + + delete[] data; + + std::lock_guard lks(m_crit.send); + SendToClients(spac, player.pid); + } + break; + case NP_MSG_PONG : { const u32 ping = m_ping_timer.GetTimeElapsed(); diff --git a/Source/Core/Core/Src/NetPlayServer.h b/Source/Core/Core/Src/NetPlayServer.h index 95f98e2a73..1d3735277d 100644 --- a/Source/Core/Core/Src/NetPlayServer.h +++ b/Source/Core/Core/Src/NetPlayServer.h @@ -40,6 +40,9 @@ public: bool GetPadMapping(const int pid, int map[]); bool SetPadMapping(const int pid, const int map[]); + bool GetWiimoteMapping(const int pid, int map[]); + bool SetWiimoteMapping(const int pid, const int map[]); + void AdjustPadBufferSize(unsigned int size); bool is_connected; @@ -58,6 +61,7 @@ private: PlayerId pid; std::string name; PadMapping pad_map[4]; + PadMapping wiimote_map[4]; std::string revision; sf::SocketTCP socket; @@ -70,6 +74,7 @@ private: unsigned int OnDisconnect(sf::SocketTCP& socket); unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket); void UpdatePadMapping(); + void UpdateWiimoteMapping(); NetSettings m_settings; diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 1c8f0549b9..86650b3588 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -106,11 +106,11 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* " - DSP Emulator Engine Must be the same on all computers!\n" " - DSP on Dedicated Thread [OFF]\n" " - Framelimit NOT set to [Audio]\n" - " - Manually set the exact number of controllers to be used to [Standard Controller]\n" + " - Manually set the exact number of wiimotes to be used to [Emulated 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 has not been implemented!\n" + "Wiimote support is probably terrible. Don't use it.\n" "\n" "The host must have the chosen TCP port open/forwarded!\n"), wxDefaultPosition, wxDefaultSize); @@ -560,6 +560,7 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent&) void NetPlayDiag::OnConfigPads(wxCommandEvent&) { int mapping[4]; + int wiimotemapping[4]; // get selected player id int pid = m_player_lbox->GetSelection(); @@ -569,11 +570,13 @@ void NetPlayDiag::OnConfigPads(wxCommandEvent&) if (false == netplay_server->GetPadMapping(pid, mapping)) return; + if (false == netplay_server->GetWiimoteMapping(pid, wiimotemapping)) + return; - PadMapDiag pmd(this, mapping); + PadMapDiag pmd(this, mapping, wiimotemapping); pmd.ShowModal(); - if (false == netplay_server->SetPadMapping(pid, mapping)) + if (false == netplay_server->SetPadMapping(pid, mapping) || false == netplay_server->SetWiimoteMapping(pid, wiimotemapping)) 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)"); } @@ -605,9 +608,9 @@ void ChangeGameDiag::OnPick(wxCommandEvent& event) EndModal(wxID_OK); } -PadMapDiag::PadMapDiag(wxWindow* const parent, int map[]) +PadMapDiag::PadMapDiag(wxWindow* const parent, int map[], int wiimotemap[]) : wxDialog(parent, wxID_ANY, _("Configure Pads"), wxDefaultPosition, wxDefaultSize) - , m_mapping(map) + , m_mapping(map), m_wiimapping(wiimotemap) { wxBoxSizer* const h_szr = new wxBoxSizer(wxHORIZONTAL); @@ -627,6 +630,11 @@ PadMapDiag::PadMapDiag(wxWindow* const parent, int map[]) for (unsigned int i=1; i<5; ++i) pad_names[i] = wxString(_("Pad ")) + (wxChar)(wxT('0')+i); + wxString wiimote_names[5]; + wiimote_names[0] = _("None"); + for (unsigned int i=1; i < 5; ++i) + wiimote_names[i] = wxString(_("Wiimote ")) + (wxChar)(wxT('0')+i); + for (unsigned int i=0; i<4; ++i) { wxChoice* const pad_cbox = m_map_cbox[i] @@ -642,6 +650,21 @@ PadMapDiag::PadMapDiag(wxWindow* const parent, int map[]) h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20); } + for (unsigned int i=0; i<4; ++i) + { + wxChoice* const wiimote_cbox = m_map_cbox[i+4] + = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 5, wiimote_names); + wiimote_cbox->Select(m_wiimapping[i] + 1); + + wiimote_cbox->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &PadMapDiag::OnAdjust, this); + + wxBoxSizer* const v_szr = new wxBoxSizer(wxVERTICAL); + v_szr->Add(new wxStaticText(this,wxID_ANY, wiimote_names[i + 1]), 1, wxALIGN_CENTER_HORIZONTAL); + v_szr->Add(wiimote_cbox, 1); + + h_szr->Add(v_szr, 1, wxTOP | wxEXPAND, 20); + } + h_szr->AddSpacer(20); wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); @@ -657,5 +680,8 @@ void PadMapDiag::OnAdjust(wxCommandEvent& event) { (void)event; for (unsigned int i=0; i<4; ++i) + { m_mapping[i] = m_map_cbox[i]->GetSelection() - 1; + m_wiimapping[i] = m_map_cbox[i+4]->GetSelection() - 1; + } } diff --git a/Source/Core/DolphinWX/Src/NetWindow.h b/Source/Core/DolphinWX/Src/NetWindow.h index 543c164994..89bf66fee2 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.h +++ b/Source/Core/DolphinWX/Src/NetWindow.h @@ -124,13 +124,14 @@ private: class PadMapDiag : public wxDialog { public: - PadMapDiag(wxWindow* const parent, int map[]); + PadMapDiag(wxWindow* const parent, int map[], int wiimotemap[]); private: void OnAdjust(wxCommandEvent& event); - wxChoice* m_map_cbox[4]; + wxChoice* m_map_cbox[8]; int* const m_mapping; + int* const m_wiimapping; }; #endif // _NETWINDOW_H_ From 011bcfee347d0ec913fe502f5f93ff3286883418 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Wed, 7 Aug 2013 10:10:40 -0400 Subject: [PATCH 2/7] Misc netplay cleanup. --- .../Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp | 2 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h | 1 - Source/Core/Core/Src/NetPlayClient.cpp | 73 ++++--------------- Source/Core/Core/Src/NetPlayServer.cpp | 1 + 4 files changed, 15 insertions(+), 62 deletions(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp index 4adec84469..9b57f96a2c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp @@ -265,7 +265,7 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size) _dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->dcid), "L2CAP: SendACLPacket to unknown channel %i", pHeader->dcid); CChannelMap::iterator itr= m_Channel.find(pHeader->dcid); - const int number = NetPlay_GetWiimoteNum(m_ConnectionHandle & 0xFF); + const int number = m_ConnectionHandle & 0xFF; if (itr != m_Channel.end()) { diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h index 691fc84011..397841a2f0 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h @@ -56,7 +56,6 @@ public: void ReceiveL2capData(u16 scid, const void* _pData, u32 _Size); // From wiimote int NetPlay_GetWiimoteNum(int _number); - bool NetPlay_WiimoteInput(int _number, u16 _channelID, const void* _pData, u32& _Size); void EventConnectionAccepted(); void EventDisconnect(); diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index cefb0ebe16..6a8086869a 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -263,7 +263,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) delete[] data; // trusting server for good map value (>=0 && <4) - // add to pad buffer + // add to wiimote buffer m_wiimote_buffer[(unsigned)map].Push(nw); } break; @@ -455,13 +455,6 @@ bool NetPlayClient::StartGame(const std::string &path) { std::lock_guard lkg(m_crit.game); - //wtf? - if (m_target_buffer_size > 100) - { - m_target_buffer_size = 20; - NOTICE_LOG(NETPLAY,"WHYYYYYYYYYYYY"); - } - // tell server i started the game sf::Packet spac; spac << (MessageId)NP_MSG_START_GAME; @@ -487,12 +480,6 @@ bool NetPlayClient::StartGame(const std::string &path) // 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; } @@ -584,7 +571,7 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) // in game mapping for this local wiimote unsigned int in_game_num = m_local_player->wiimote_map[_number]; - // does this local pad map in game? + // does this local wiimote map in game? if (in_game_num < 4) { static u8 previousSize = 0; @@ -594,8 +581,7 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) // Reporting mode changed, so previous buffer is no good. m_wiimote_buffer[_number].Clear(); } - - //m_wiimote_input[in_game_num].data.resize(m_wiimote_input[_number].size + 1); + m_wiimote_input[in_game_num].data.assign(data, data + size); m_wiimote_input[in_game_num].size = size; while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size) @@ -623,15 +609,19 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) // This is either a desync, or the reporting mode changed. No way to really be sure... if (size != nw.size) { + u8 tries = 0; // Clear the buffer and wait for new input, in case it was just the reporting mode changing as expected. do { - m_wiimote_buffer[_number].Pop(nw); - Common::SleepCurrentThread(1); - if (false == m_is_running) - return false; - - // TODO: break if this runs too long; it probably desynced if it runs for longer than the buffer size + while (!m_wiimote_buffer[_number].Pop(nw)) + { + Common::SleepCurrentThread(1); + if (false == m_is_running) + return false; + } + ++tries; + if (tries > m_target_buffer_size) + break; } while (nw.size != size); // If it still mismatches, it surely desynced @@ -746,43 +736,6 @@ u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD) return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); } -// called from ---CPU--- thread -// -int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number) -{ -// std::lock_guard lk(crit_netplay_client); - -// if (netplay_client) -// return netplay_client->GetPadNum(_number+4); -// 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; diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index 5eb5288c15..0d68ac64ef 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -49,6 +49,7 @@ NetPlayServer::NetPlayServer(const u16 port) : is_connected(false), m_is_running m_do_loop = true; m_selector.Add(m_socket); m_thread = std::thread(std::mem_fun(&NetPlayServer::ThreadFunc), this); + m_target_buffer_size = 20; } } From f51cb0b7eb9c0f261abd3f5d68707ba1f93e3888 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Wed, 7 Aug 2013 18:00:38 -0400 Subject: [PATCH 3/7] Fix multiplayer wiimote netplay. --- Source/Core/Core/Src/NetPlayClient.cpp | 14 ++++++-------- Source/Core/Core/Src/NetPlayClient.h | 2 -- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index 6a8086869a..1504498c1f 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -500,8 +500,6 @@ void NetPlayClient::ClearBuffers() while (m_wiimote_buffer[i].Size()) m_wiimote_buffer[i].Pop(); - - m_wiimote_input[i].data.clear(); } } @@ -565,6 +563,7 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_stat // called from ---CPU--- thread bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) { + NetWiimote nw; { std::lock_guard lkp(m_crit.players); @@ -579,25 +578,24 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) if (previousSize != size && m_wiimote_buffer[in_game_num].Size() > 0) { // Reporting mode changed, so previous buffer is no good. - m_wiimote_buffer[_number].Clear(); + m_wiimote_buffer[in_game_num].Clear(); } - m_wiimote_input[in_game_num].data.assign(data, data + size); - m_wiimote_input[in_game_num].size = size; + nw.data.assign(data, data + size); + nw.size = size; while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size) { // add to buffer - m_wiimote_buffer[in_game_num].Push(m_wiimote_input[in_game_num]); + m_wiimote_buffer[in_game_num].Push(nw); // send - SendWiimoteState(_number, m_wiimote_input[_number]); + SendWiimoteState(_number, nw); } previousSize = size; } } // unlock players - NetWiimote nw; while (!m_wiimote_buffer[_number].Pop(nw)) { // wait for receiving thread to push some data diff --git a/Source/Core/Core/Src/NetPlayClient.h b/Source/Core/Core/Src/NetPlayClient.h index 625c20b951..0783fdf439 100644 --- a/Source/Core/Core/Src/NetPlayClient.h +++ b/Source/Core/Core/Src/NetPlayClient.h @@ -100,8 +100,6 @@ protected: Common::FifoQueue m_pad_buffer[4]; Common::FifoQueue m_wiimote_buffer[4]; - NetWiimote m_wiimote_input[4]; - NetPlayUI* m_dialog; sf::SocketTCP m_socket; std::thread m_thread; From c7025989f8cbd1e20505a17515cf6d99ec96d2c9 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Thu, 15 Aug 2013 22:31:36 -0400 Subject: [PATCH 4/7] Probably worthless commit that may fix wiimote netplay buffer problems. --- Source/Core/Core/Src/NetPlayClient.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index 1504498c1f..a2a06e03e0 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -575,10 +575,10 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) { static u8 previousSize = 0; - if (previousSize != size && m_wiimote_buffer[in_game_num].Size() > 0) + while (previousSize != size && m_wiimote_buffer[in_game_num].Size() > 0) { // Reporting mode changed, so previous buffer is no good. - m_wiimote_buffer[in_game_num].Clear(); + m_wiimote_buffer[in_game_num].Pop(); } nw.data.assign(data, data + size); @@ -618,7 +618,7 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) return false; } ++tries; - if (tries > m_target_buffer_size) + if (tries > m_target_buffer_size +1) break; } while (nw.size != size); From 894e29b80929dd9ae1e837eeae8e327e6e499368 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Sun, 18 Aug 2013 05:17:06 -0400 Subject: [PATCH 5/7] Fix comments, and send wiimote mapping to new users. --- Source/Core/Core/Src/NetPlayServer.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index c5d77c0f23..29dc86411d 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -193,7 +193,7 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) { bool is_mapped[4] = {false,false,false,false}; - for ( unsigned int m = 0; m<4; ++m) + for (unsigned int m = 0; m<4; ++m) { for (i = m_players.begin(); i!=e; ++i) { @@ -202,7 +202,7 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) } } - for ( unsigned int m = 0; m<4; ++m) + for (unsigned int m = 0; m<4; ++m) if (false == is_mapped[m]) { player.pad_map[0] = m; @@ -252,6 +252,7 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) m_players[socket] = player; std::lock_guard lks(m_crit.send); UpdatePadMapping(); // sync pad mappings with everyone + UpdateWiimoteMapping(); } @@ -329,7 +330,7 @@ bool NetPlayServer::GetWiimoteMapping(const int pid, int map[]) if (i == e) return false; - // get pad mapping + // get wiimote mapping for (unsigned int m = 0; m<4; ++m) map[m] = i->second.wiimote_map[m]; @@ -397,7 +398,7 @@ bool NetPlayServer::SetWiimoteMapping(const int pid, const int map[]) Client& player = i->second; - // set pad mapping + // set wiimote mapping for (unsigned int m = 0; m<4; ++m) { player.wiimote_map[m] = (PadMapping)map[m]; @@ -411,7 +412,7 @@ bool NetPlayServer::SetWiimoteMapping(const int pid, const int map[]) } std::lock_guard lks(m_crit.send); - UpdateWiimoteMapping(); // sync pad mappings with everyone + UpdateWiimoteMapping(); // sync wiimote mappings with everyone return true; } @@ -534,7 +535,7 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) case NP_MSG_WIIMOTE_DATA : { - // if this is pad data from the last game still being received, ignore it + // if this is wiimote data from the last game still being received, ignore it if (player.current_game != m_current_game) break; @@ -545,14 +546,14 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket) for (unsigned int i = 0; i < size; ++i) packet >> data[i]; - // check if client's pad indeed maps in game + // check if client's wiimote indeed maps in game if (map >= 0 && map < 4) map = player.wiimote_map[(unsigned)map]; else map = -1; // if not, they are hacking, so disconnect them - // this could happen right after a pad map change, but that isn't implemented yet + // this could happen right after a wiimote map change, but that isn't implemented yet if (map < 0) return 1; From d3c437819d5c2128c84b9f271aa0a2fe39be7ea4 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Mon, 19 Aug 2013 13:45:02 -0400 Subject: [PATCH 6/7] NetPlay: Add blank inputs when reporting mode changes, so the buffer isn't empty if wiimote 1 isn't polled next. --- Source/Core/Core/Src/NetPlayClient.cpp | 86 ++++++++++++++++++-------- Source/Core/Core/Src/NetPlayClient.h | 2 +- Source/Core/Core/Src/NetPlayServer.cpp | 6 +- 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index a2a06e03e0..b03278d1a3 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -480,6 +480,19 @@ bool NetPlayClient::StartGame(const std::string &path) // boot game m_dialog->BootGame(path); + // Needed to prevent locking up at boot if (when) the wiimotes connect out of order. + NetWiimote nw; + nw.size = 4; + nw.data.resize(4); + memset(nw.data.data(), 0, 4); + + for (unsigned int w = 0; w < 4; ++w) + { + // probably overkill, but whatever + for (unsigned int i = 0; i < 7; ++i) + m_wiimote_buffer[w].Push(nw); + } + return true; } @@ -561,9 +574,10 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_stat // called from ---CPU--- thread -bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) +bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size) { NetWiimote nw; + static u8 previousSize[4] = {4,4,4,4}; { std::lock_guard lkp(m_crit.players); @@ -573,30 +587,39 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) // does this local wiimote map in game? if (in_game_num < 4) { - static u8 previousSize = 0; - - while (previousSize != size && m_wiimote_buffer[in_game_num].Size() > 0) - { - // Reporting mode changed, so previous buffer is no good. - m_wiimote_buffer[in_game_num].Pop(); - } - nw.data.assign(data, data + size); nw.size = size; - while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size) - { - // add to buffer - m_wiimote_buffer[in_game_num].Push(nw); + if (previousSize[in_game_num] == size) + do + { + // add to buffer + m_wiimote_buffer[in_game_num].Push(nw); - // send - SendWiimoteState(_number, nw); + SendWiimoteState(_number, nw); + } while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size /*&& previousSize[in_game_num] == size*/); + + if (previousSize[in_game_num] != size) + { + + while (m_wiimote_buffer[in_game_num].Size() > 0) + { + // Reporting mode changed, so previous buffer is no good. + m_wiimote_buffer[in_game_num].Pop(); + } + + nw.data.resize(size); + memset(nw.data.data(), 0, size); + // Not sure if this is necessary, but it might be. + m_wiimote_buffer[in_game_num].Push(nw); + m_wiimote_buffer[in_game_num].Push(nw); + m_wiimote_buffer[in_game_num].Push(nw); + previousSize[in_game_num] = size; } - previousSize = size; } } // unlock players - while (!m_wiimote_buffer[_number].Pop(nw)) + while (previousSize[_number] == size && !m_wiimote_buffer[_number].Pop(nw)) { // wait for receiving thread to push some data Common::SleepCurrentThread(1); @@ -604,12 +627,22 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) return false; } - // This is either a desync, or the reporting mode changed. No way to really be sure... - if (size != nw.size) + // Use a blank input. + if (previousSize[_number] != size) + { + nw.size = size; + nw.data.resize(size); + memset(nw.data.data(), 0, size); + m_wiimote_buffer[_number].Push(nw); + m_wiimote_buffer[_number].Push(nw); + } + + // We should have used a blank input last time, so now we just need to pop through the old buffer, until we reach a good input + if (nw.size != size) { u8 tries = 0; // Clear the buffer and wait for new input, in case it was just the reporting mode changing as expected. - do + while (nw.size != size) { while (!m_wiimote_buffer[_number].Pop(nw)) { @@ -618,19 +651,20 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size) return false; } ++tries; - if (tries > m_target_buffer_size +1) - break; - } while (nw.size != size); + //if (tries > m_target_buffer_size) + //break; + } // If it still mismatches, it surely desynced if (size != nw.size) { - PanicAlert("Netplay has desynced. There is no way to handle this. Self destructing in 3...2...1..."); - StopGame(); - return false; + //PanicAlert("Netplay has desynced. There is no way to handle this. Self destructing in 3...2...1..."); + //StopGame(); + //return false; } } + previousSize[_number] = size; memcpy(data, nw.data.data(), size); return true; } diff --git a/Source/Core/Core/Src/NetPlayClient.h b/Source/Core/Core/Src/NetPlayClient.h index 0783fdf439..ff6712fc91 100644 --- a/Source/Core/Core/Src/NetPlayClient.h +++ b/Source/Core/Core/Src/NetPlayClient.h @@ -68,7 +68,7 @@ public: void SendChatMessage(const std::string& msg); // Send and receive pads values - bool WiimoteUpdate(int _number, u8* data, u8 size); + bool WiimoteUpdate(int _number, u8* data, const u8 size); bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues); u8 GetPadNum(u8 numPAD); diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index 29dc86411d..dc9849297b 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -197,15 +197,15 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) { for (i = m_players.begin(); i!=e; ++i) { - if (i->second.pad_map[m] >= 0) - is_mapped[(unsigned)i->second.pad_map[m]] = true; + if (i->second.wiimote_map[m] >= 0) + is_mapped[(unsigned)i->second.wiimote_map[m]] = true; } } for (unsigned int m = 0; m<4; ++m) if (false == is_mapped[m]) { - player.pad_map[0] = m; + player.wiimote_map[0] = m; break; } From d3894a05949c938295ca1587cf9d777a50ca9c60 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Thu, 22 Aug 2013 11:37:38 -0400 Subject: [PATCH 7/7] Clean up wiimote-netplay. --- Source/Core/Core/Src/NetPlayClient.cpp | 52 +++++++++++--------------- Source/Core/Core/Src/NetPlayProto.h | 6 +-- Source/Core/Core/Src/NetPlayServer.cpp | 1 + 3 files changed, 24 insertions(+), 35 deletions(-) diff --git a/Source/Core/Core/Src/NetPlayClient.cpp b/Source/Core/Core/Src/NetPlayClient.cpp index b03278d1a3..660d0d83dd 100644 --- a/Source/Core/Core/Src/NetPlayClient.cpp +++ b/Source/Core/Core/Src/NetPlayClient.cpp @@ -255,11 +255,11 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) u8 size; packet >> map >> size; - nw.size = size; + nw.resize(size); u8* data = new u8[size]; for (unsigned int i = 0; i < size; ++i) packet >> data[i]; - nw.data.assign(data,data+size); + nw.assign(data,data+size); delete[] data; // trusting server for good map value (>=0 && <4) @@ -441,10 +441,10 @@ void NetPlayClient::SendWiimoteState(const PadMapping local_nb, const NetWiimote sf::Packet spac; spac << (MessageId)NP_MSG_WIIMOTE_DATA; spac << local_nb; // local pad num - u8 size = nw.size; + u8 size = nw.size(); spac << size; for (unsigned int i = 0; i < size; ++i) - spac << nw.data.data()[i]; + spac << nw.data()[i]; std::lock_guard lks(m_crit.send); m_socket.Send(spac); @@ -482,9 +482,7 @@ bool NetPlayClient::StartGame(const std::string &path) // Needed to prevent locking up at boot if (when) the wiimotes connect out of order. NetWiimote nw; - nw.size = 4; - nw.data.resize(4); - memset(nw.data.data(), 0, 4); + nw.resize(4, 0); for (unsigned int w = 0; w < 4; ++w) { @@ -587,29 +585,26 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size) // does this local wiimote map in game? if (in_game_num < 4) { - nw.data.assign(data, data + size); - nw.size = size; if (previousSize[in_game_num] == size) + { + nw.assign(data, data + size); do { // add to buffer m_wiimote_buffer[in_game_num].Push(nw); SendWiimoteState(_number, nw); - } while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size /*&& previousSize[in_game_num] == size*/); - - if (previousSize[in_game_num] != size) + } while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size * 200 / 120); // TODO: add a seperate setting for wiimote buffer + } + else { - while (m_wiimote_buffer[in_game_num].Size() > 0) { // Reporting mode changed, so previous buffer is no good. m_wiimote_buffer[in_game_num].Pop(); } + nw.resize(size, 0); - nw.data.resize(size); - memset(nw.data.data(), 0, size); - // Not sure if this is necessary, but it might be. m_wiimote_buffer[in_game_num].Push(nw); m_wiimote_buffer[in_game_num].Push(nw); m_wiimote_buffer[in_game_num].Push(nw); @@ -627,22 +622,20 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size) return false; } - // Use a blank input. + // Use a blank input, since we may not have any valid input. if (previousSize[_number] != size) { - nw.size = size; - nw.data.resize(size); - memset(nw.data.data(), 0, size); + nw.resize(size, 0); m_wiimote_buffer[_number].Push(nw); m_wiimote_buffer[_number].Push(nw); } // We should have used a blank input last time, so now we just need to pop through the old buffer, until we reach a good input - if (nw.size != size) + if (nw.size() != size) { u8 tries = 0; - // Clear the buffer and wait for new input, in case it was just the reporting mode changing as expected. - while (nw.size != size) + // Clear the buffer and wait for new input, since we probably just changed reporting mode. + while (nw.size() != size) { while (!m_wiimote_buffer[_number].Pop(nw)) { @@ -651,21 +644,20 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size) return false; } ++tries; - //if (tries > m_target_buffer_size) - //break; + if (tries > m_target_buffer_size) + break; } // If it still mismatches, it surely desynced - if (size != nw.size) + if (size != nw.size()) { - //PanicAlert("Netplay has desynced. There is no way to handle this. Self destructing in 3...2...1..."); - //StopGame(); - //return false; + PanicAlert("Netplay has desynced. There is no way to recover from this."); + return false; } } previousSize[_number] = size; - memcpy(data, nw.data.data(), size); + memcpy(data, nw.data(), size); return true; } diff --git a/Source/Core/Core/Src/NetPlayProto.h b/Source/Core/Core/Src/NetPlayProto.h index b1c4c481d9..f722b211f7 100644 --- a/Source/Core/Core/Src/NetPlayProto.h +++ b/Source/Core/Core/Src/NetPlayProto.h @@ -16,11 +16,7 @@ struct NetSettings u8 m_Controllers[4]; }; -struct NetWiimote -{ - u8 size; - std::vector data; -}; +typedef std::vector NetWiimote; #define NETPLAY_VERSION "Dolphin NetPlay 2013-08-06 now with wiimote(TM)" diff --git a/Source/Core/Core/Src/NetPlayServer.cpp b/Source/Core/Core/Src/NetPlayServer.cpp index dc9849297b..ff7f35af2b 100644 --- a/Source/Core/Core/Src/NetPlayServer.cpp +++ b/Source/Core/Core/Src/NetPlayServer.cpp @@ -190,6 +190,7 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket) // TODO: this is crappy // try to automatically assign new user a pad + // TODO: change back to assigning pads instead of wiimotes before merging wiimote-netplay { bool is_mapped[4] = {false,false,false,false};