Fixed some crashes in netplay, so it actually works :p

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3233 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
sl1nk3.s 2009-05-14 18:53:59 +00:00
parent 6b9d56bc6b
commit 034e3c72a2
7 changed files with 85 additions and 52 deletions

View File

@ -214,8 +214,8 @@ IPAddress IPAddress::GetPublicAddress()
std::string PageBody; std::string PageBody;
// Connect to the web server and get its index page // Connect to the web server and get its index page
// www.whatismyip.org is so slow that it time outs after ~60s // www.whatismyip.org is so slow that it times out after ~60s
// better use this one instead, it is must faster... here :P // better use this one instead, it is much faster... at least here :P
Http Server("www.monip.org"); Http Server("www.monip.org");
Http::Request Request(Http::Request::Get, "/"); Http::Request Request(Http::Request::Get, "/");
Http::Response Page = Server.SendRequest(Request); Http::Response Page = Server.SendRequest(Request);

View File

@ -137,10 +137,9 @@ CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
{ {
_Hi = netValues[0]; // first 4 bytes _Hi = netValues[0]; // first 4 bytes
_Low = netValues[1]; // last 4 bytes _Low = netValues[1]; // last 4 bytes
return true;
} }
else
return false; return true;
} }
#endif #endif
_Hi = (u32)((u8)PadStatus.stickY); _Hi = (u32)((u8)PadStatus.stickY);

View File

@ -135,6 +135,7 @@ void ClientSide::OnClientData(unsigned char data)
{ {
m_socket.Receive((char*)m_netvalues[0], 8, recv_size); m_socket.Receive((char*)m_netvalues[0], 8, recv_size);
m_data_received = true; m_data_received = true;
#ifdef NET_DEBUG #ifdef NET_DEBUG
char sent[64]; char sent[64];
sprintf(sent, "Received Values: 0x%08x : 0x%08x \n", m_netvalues[0][0], m_netvalues[0][1]); sprintf(sent, "Received Values: 0x%08x : 0x%08x \n", m_netvalues[0][0], m_netvalues[0][1]);

View File

@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "NetWindow.h" #include "NetWindow.h"
#include "HW/SI_DeviceGCController.h"
NetPlay *NetClass_ptr = NULL; NetPlay *NetClass_ptr = NULL;
@ -77,6 +78,7 @@ void NetPlay::OnNetEvent(wxCommandEvent& event)
case HOST_NEWPLAYER: case HOST_NEWPLAYER:
{ {
m_numClients++; m_numClients++;
m_NetModel = event.GetInt();
} }
break; break;
case CLIENTS_READY: case CLIENTS_READY:
@ -159,6 +161,7 @@ void NetPlay::LoadGame()
// Enable // Enable
NetClass_ptr = this; NetClass_ptr = this;
m_timer.Start(); m_timer.Start();
m_data_received = false;
// Find corresponding game path // Find corresponding game path
for (int i=0; i < (int)m_paths.size(); i++) for (int i=0; i < (int)m_paths.size(); i++)
@ -189,43 +192,44 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
netValues[1] |= (u32)((u8)PadStatus.substickY << 16); netValues[1] |= (u32)((u8)PadStatus.substickY << 16);
netValues[1] |= (u32)((u8)PadStatus.substickX << 24); netValues[1] |= (u32)((u8)PadStatus.substickX << 24);
// TODO : actually show this on the GUI :p if (m_frame == 0)
// Update the timer and increment total frame number {
m_frame++; // We make sure everyone's pad is enabled
m_timer.Update(); for (int i = 0; i < m_numClients+1; i++)
SerialInterface::ChangeDevice(SI_GC_CONTROLLER, i);
// We make sure everyone's pad is enabled // Better disable unused ports
for (char i = 0; i < m_numClients; i++) for (int i = m_numClients+1; i < 4; i++)
SerialInterface::ChangeDevice(SI_GC_CONTROLLER, (int)i); SerialInterface::ChangeDevice(SI_DUMMY, i);
}
// Better disable unused ports
for (char i = m_numClients; i < 3; i++)
SerialInterface::ChangeDevice(SI_DUMMY, (int)i);
if (m_NetModel == 0 && m_numClients == 1) // Use P2P Model if (m_NetModel == 0 && m_numClients == 1) // Use P2P Model
{ {
if (padnb == 0) if (padnb == 0)
{ {
// TODO : actually show this on the GUI :p
// Update the timer and increment total frame number
m_frame++;
m_timer.Update();
#ifdef NET_DEBUG #ifdef NET_DEBUG
char sent[64]; char sent[64];
sprintf(sent, "Sent Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]); sprintf(sent, "Sent Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]);
m_Logging->AppendText(wxString::FromAscii(sent)); m_Logging->AppendText(wxString::FromAscii(sent));
#endif #endif
unsigned char init_value = 0xA1; unsigned char init_value = 0xA1;
unsigned char recv_value = 0;
unsigned char player = 0; unsigned char player = 0;
if (m_isHosting == 1) { if (m_isHosting == 1) {
// Send pads values // Send pads values
m_sock_server->Write(0, (const char*)&init_value, 1); m_sock_server->Write(0, (const char*)&init_value, 1);
m_sock_server->Write(0, (const char*)netValues, 8); m_sock_server->Write(0, (const char*)netValues, 8);
player = 0; // Host is player 1
} }
else { else {
// Send pads values // Send pads values
m_sock_client->Write((const char*)&init_value, 1); m_sock_client->Write((const char*)&init_value, 1);
m_sock_client->Write((const char*)netValues, 8); m_sock_client->Write((const char*)netValues, 8);
player = 1; // Client is player 2 player = 1;
} }
if (!m_data_received) if (!m_data_received)
@ -236,24 +240,28 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
// Try to read from peer... // Try to read from peer...
if (m_isHosting == 1) if (m_isHosting == 1)
m_data_received = m_sock_server->isNewPadData(0, m_data_received); m_data_received = m_sock_server->isNewPadData(0, false);
else else
m_data_received = m_sock_client->isNewPadData(0, m_data_received); m_data_received = m_sock_client->isNewPadData(0, false);
if (m_data_received) if (m_data_received)
{ {
// Set our practical frame delay
m_frameDelay = m_loopframe;
m_loopframe = 0;
// First Data has been received ! // First Data has been received !
m_Logging->AppendText(_("** Data received from Peer. Starting Sync !")); m_Logging->AppendText(_("** Data received from Peer. Starting Sync !"));
m_Logging->AppendText(wxString::Format(wxT(" Frame Delay : %d **\n"), m_frameDelay));
// Set our practical frame delay
if (recv_value == 0xA1) // init number
{
m_frameDelay = m_loopframe;
m_loopframe = 0;
m_Logging->AppendText(wxString::Format(wxT(" Frame Delay : %d **\n"), m_frameDelay));
}
} }
else { else {
if (m_loopframe > 126)
{
m_Logging->AppendText(_("** Ping too high (>2000ms) or connection lost ! \n"));
m_Logging->AppendText(_("** Stopping game... \n"));
BootManager::Stop();
}
m_loopframe++; m_loopframe++;
return false; return false;
} }
@ -269,26 +277,34 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
// (i.e : framerate is too low) we have to wait for it thus slowing down emulation // (i.e : framerate is too low) we have to wait for it thus slowing down emulation
// Save current pad values, it will be used in 'm_frameDelay' frames :D // Save current pad values, it will be used in 'm_frameDelay' frames :D
int saveslot = (m_loopframe-1 < 0 ? m_frameDelay : m_loopframe-1); int saveslot = (m_loopframe - 1 < 0 ? m_frameDelay : m_loopframe - 1);
u32 recvedValues[2];
m_pads[player].nHi[saveslot] = netValues[0]; m_pads[player].nHi[saveslot] = netValues[0];
m_pads[player].nLow[saveslot] = netValues[1]; m_pads[player].nLow[saveslot] = netValues[1];
// Read the socket for pad values // Read the socket for pad values
if (m_isHosting == 1) if (m_isHosting == 1)
while (!m_sock_server->isNewPadData(netValues, 1)) { /* Wait Data */ } m_sock_server->isNewPadData(recvedValues, true);
else else
while (!m_sock_client->isNewPadData(netValues, 1)) { } m_sock_client->isNewPadData(recvedValues, true);
if (player == 0) if (player == 0)
{ {
// Store received peer values // Store received peer values
m_pads[1].nHi[m_loopframe] = netValues[0]; m_pads[1].nHi[m_loopframe] = recvedValues[0];
m_pads[1].nLow[m_loopframe] = netValues[1]; m_pads[1].nLow[m_loopframe] = recvedValues[1];
// Apply synced pad values // Apply synced pad values
netValues[0] = m_pads[0].nHi[m_loopframe]; netValues[0] = m_pads[0].nHi[m_loopframe];
netValues[1] = m_pads[0].nLow[m_loopframe]; netValues[1] = m_pads[0].nLow[m_loopframe];
} }
else
{
// Apply received pad values
netValues[0] = recvedValues[0];
netValues[1] = recvedValues[1];
}
} }
#ifdef NET_DEBUG #ifdef NET_DEBUG
@ -388,38 +404,54 @@ void NetPlay::OnDisconnect(wxCommandEvent& WXUNUSED(event))
bool ClientSide::isNewPadData(u32 *netValues, bool current, bool isVersus) bool ClientSide::isNewPadData(u32 *netValues, bool current, bool isVersus)
{ {
// TODO : adapt it to more than 2 players // TODO : adapt it to more than 2 players
wxCriticalSectionLocker lock(m_CriticalSection);
if (current) if (current)
{ {
if (m_data_received) while (1)
{ {
if (isVersus) { m_CriticalSection.Enter();
if (m_data_received && isVersus)
{
netValues[0] = m_netvalues[0][0]; netValues[0] = m_netvalues[0][0];
netValues[1] = m_netvalues[0][1]; netValues[1] = m_netvalues[0][1];
m_data_received = false;
m_CriticalSection.Leave();
break;
} }
m_CriticalSection.Leave();
} }
else
return false; return true;
} }
else
wxCriticalSectionLocker lock(m_CriticalSection);
return m_data_received; return m_data_received;
} }
bool ServerSide::isNewPadData(u32 *netValues, bool current, char client) bool ServerSide::isNewPadData(u32 *netValues, bool current, char client)
{ {
wxCriticalSectionLocker lock(m_CriticalSection);
if (current) if (current)
{ {
if (m_data_received) while (1)
{ {
netValues[0] = m_netvalues[client][0]; m_CriticalSection.Enter();
netValues[1] = m_netvalues[client][1]; if (m_data_received)
{
netValues[0] = m_netvalues[client][0];
netValues[1] = m_netvalues[client][1];
m_data_received = false;
m_CriticalSection.Leave();
break;
}
m_CriticalSection.Leave();
} }
else
return false; return true;
} }
else
wxCriticalSectionLocker lock(m_CriticalSection);
return m_data_received; return m_data_received;
} }

View File

@ -326,7 +326,7 @@ void *ClientSide::Entry()
} }
m_netptr->ChangeSelectedGame(m_selectedgame); m_netptr->ChangeSelectedGame(m_selectedgame);
Event->SendEvent(HOST_NEWPLAYER); Event->SendEvent(HOST_NEWPLAYER, "NULL", m_netmodel);
Event->SendEvent(GUI_UPDATE); Event->SendEvent(GUI_UPDATE);
m_selector.Add(m_socket); m_selector.Add(m_socket);

View File

@ -43,7 +43,7 @@ NetPlay::NetPlay(wxWindow* parent, std::string GamePaths, std::string GameNames)
m_selectedGame = 'a'; m_hostaddr = 'a'; m_selectedGame = 'a'; m_hostaddr = 'a';
m_games = GameNames; m_paths = GamePaths; m_games = GameNames; m_paths = GamePaths;
m_isHosting = 2; m_ready = m_clients_ready = false; m_isHosting = 2; m_ready = m_clients_ready = false;
m_loopframe = m_frame = 0; m_loopframe = m_frame = m_NetModel = m_numClients = 0;
DrawGUI(); DrawGUI();
} }
@ -498,7 +498,8 @@ void GameListPopup::OnButtons(wxCommandEvent& event)
switch (event.GetId()) switch (event.GetId())
{ {
case wxID_OK: case wxID_OK:
m_netParent->ChangeSelectedGame(std::string(m_GameList_str[m_GameList->GetSelection()].mb_str())); if (m_GameList->GetSelection() != wxNOT_FOUND)
m_netParent->ChangeSelectedGame(std::string(m_GameList_str[m_GameList->GetSelection()].mb_str()));
Destroy(); Destroy();
break; break;
case wxID_CANCEL: case wxID_CANCEL:

View File

@ -90,7 +90,7 @@ class ServerSide : public wxThread
NetEvent *Event; NetEvent *Event;
u32 m_netvalues[3][2]; u32 m_netvalues[3][2];
bool m_data_received; // New Pad data received ? bool m_data_received; // New Pad data received ?
unsigned char m_numplayers; unsigned char m_numplayers;
int m_netmodel; int m_netmodel;
@ -123,7 +123,7 @@ class ClientSide : public wxThread
NetEvent *Event; NetEvent *Event;
u32 m_netvalues[3][2]; u32 m_netvalues[3][2];
bool m_data_received; // New Pad data received ? bool m_data_received; // New Pad data received ?
unsigned char m_numplayers; unsigned char m_numplayers;
int m_netmodel; int m_netmodel;