// called from ---CPU--- thread void NetPlayClient::SendWiimoteState(const PadMapping in_game_pad, const NetWiimote& nw) { sf::Packet* spac = new sf::Packet; *spac << (MessageId)NP_MSG_WIIMOTE_DATA; *spac << in_game_pad; *spac << (u8)nw.size(); for (auto it : nw) { *spac << it; } SendAsync(spac); }
// called from ---CPU--- thread void NetPlayClient::SendWiimoteState(const int in_game_pad, const NetWiimote& nw) { auto spac = std::make_unique<sf::Packet>(); *spac << static_cast<MessageId>(NP_MSG_WIIMOTE_DATA); *spac << static_cast<PadMapping>(in_game_pad); *spac << static_cast<u8>(nw.size()); for (auto it : nw) { *spac << it; } SendAsync(std::move(spac)); }
// called from ---CPU--- thread bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size) { NetWiimote nw; static u8 previousSize[4] = { 4, 4, 4, 4 }; { std::lock_guard<std::recursive_mutex> lkp(m_crit.players); // in game mapping for this local Wiimote unsigned int in_game_num = LocalWiimoteToInGameWiimote(_number); // does this local Wiimote map in game? if (in_game_num < 4) { if (previousSize[in_game_num] == size) { nw.assign(data, data + size); do { // add to buffer m_wiimote_buffer[in_game_num].Push(nw); SendWiimoteState(in_game_num, nw); } 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); m_wiimote_buffer[in_game_num].Push(nw); m_wiimote_buffer[in_game_num].Push(nw); m_wiimote_buffer[in_game_num].Push(nw); 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; } } } // unlock players while (previousSize[_number] == size && !m_wiimote_buffer[_number].Pop(nw)) { // wait for receiving thread to push some data Common::SleepCurrentThread(1); if (!m_is_running.load()) return false; } // Use a blank input, since we may not have any valid input. if (previousSize[_number] != size) { nw.resize(size, 0); m_wiimote_buffer[_number].Push(nw); m_wiimote_buffer[_number].Push(nw); m_wiimote_buffer[_number].Push(nw); 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, since we probably just changed reporting mode. while (nw.size() != size) { while (!m_wiimote_buffer[_number].Pop(nw)) { Common::SleepCurrentThread(1); if (!m_is_running.load()) return false; } ++tries; if (tries > m_target_buffer_size * 200 / 120) break; } // If it still mismatches, it surely desynced if (size != nw.size()) { PanicAlertT("Netplay has desynced. There is no way to recover from this."); return false; } } previousSize[_number] = size; memcpy(data, nw.data(), size); return true; }