NetPlay: Add blank inputs when reporting mode changes, so the buffer isn't empty if wiimote 1 isn't polled next.

This commit is contained in:
Rachel Bryk 2013-08-19 13:45:02 -04:00
parent 894e29b809
commit d3c437819d
3 changed files with 64 additions and 30 deletions

View File

@ -480,6 +480,19 @@ bool NetPlayClient::StartGame(const std::string &path)
// boot game // boot game
m_dialog->BootGame(path); 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; return true;
} }
@ -561,9 +574,10 @@ bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_stat
// called from ---CPU--- thread // 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; NetWiimote nw;
static u8 previousSize[4] = {4,4,4,4};
{ {
std::lock_guard<std::recursive_mutex> lkp(m_crit.players); std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
@ -573,30 +587,39 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size)
// does this local wiimote map in game? // does this local wiimote map in game?
if (in_game_num < 4) if (in_game_num < 4)
{ {
static u8 previousSize = 0; nw.data.assign(data, data + size);
nw.size = size;
if (previousSize[in_game_num] == size)
do
{
// add to buffer
m_wiimote_buffer[in_game_num].Push(nw);
while (previousSize != size && m_wiimote_buffer[in_game_num].Size() > 0) 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. // Reporting mode changed, so previous buffer is no good.
m_wiimote_buffer[in_game_num].Pop(); m_wiimote_buffer[in_game_num].Pop();
} }
nw.data.assign(data, data + size); nw.data.resize(size);
nw.size = size; memset(nw.data.data(), 0, size);
while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size) // Not sure if this is necessary, but it might be.
{
// add to buffer
m_wiimote_buffer[in_game_num].Push(nw); m_wiimote_buffer[in_game_num].Push(nw);
m_wiimote_buffer[in_game_num].Push(nw);
// send m_wiimote_buffer[in_game_num].Push(nw);
SendWiimoteState(_number, nw); previousSize[in_game_num] = size;
} }
previousSize = size;
} }
} // unlock players } // 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 // wait for receiving thread to push some data
Common::SleepCurrentThread(1); Common::SleepCurrentThread(1);
@ -604,12 +627,22 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size)
return false; return false;
} }
// This is either a desync, or the reporting mode changed. No way to really be sure... // Use a blank input.
if (size != nw.size) 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; u8 tries = 0;
// Clear the buffer and wait for new input, in case it was just the reporting mode changing as expected. // 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)) while (!m_wiimote_buffer[_number].Pop(nw))
{ {
@ -618,19 +651,20 @@ bool NetPlayClient::WiimoteUpdate(int _number, u8* data, u8 size)
return false; return false;
} }
++tries; ++tries;
if (tries > m_target_buffer_size +1) //if (tries > m_target_buffer_size)
break; //break;
} while (nw.size != size); }
// If it still mismatches, it surely desynced // 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..."); //PanicAlert("Netplay has desynced. There is no way to handle this. Self destructing in 3...2...1...");
StopGame(); //StopGame();
return false; //return false;
} }
} }
previousSize[_number] = size;
memcpy(data, nw.data.data(), size); memcpy(data, nw.data.data(), size);
return true; return true;
} }

View File

@ -68,7 +68,7 @@ public:
void SendChatMessage(const std::string& msg); void SendChatMessage(const std::string& msg);
// Send and receive pads values // 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); bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
u8 GetPadNum(u8 numPAD); u8 GetPadNum(u8 numPAD);

View File

@ -197,15 +197,15 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
{ {
for (i = m_players.begin(); i!=e; ++i) for (i = m_players.begin(); i!=e; ++i)
{ {
if (i->second.pad_map[m] >= 0) if (i->second.wiimote_map[m] >= 0)
is_mapped[(unsigned)i->second.pad_map[m]] = true; is_mapped[(unsigned)i->second.wiimote_map[m]] = true;
} }
} }
for (unsigned int m = 0; m<4; ++m) for (unsigned int m = 0; m<4; ++m)
if (false == is_mapped[m]) if (false == is_mapped[m])
{ {
player.pad_map[0] = m; player.wiimote_map[0] = m;
break; break;
} }