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:
parent
6b9d56bc6b
commit
034e3c72a2
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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++;
|
|
||||||
m_timer.Update();
|
|
||||||
|
|
||||||
// We make sure everyone's pad is enabled
|
// We make sure everyone's pad is enabled
|
||||||
for (char i = 0; i < m_numClients; i++)
|
for (int i = 0; i < m_numClients+1; i++)
|
||||||
SerialInterface::ChangeDevice(SI_GC_CONTROLLER, (int)i);
|
SerialInterface::ChangeDevice(SI_GC_CONTROLLER, i);
|
||||||
|
|
||||||
// Better disable unused ports
|
// Better disable unused ports
|
||||||
for (char i = m_numClients; i < 3; i++)
|
for (int i = m_numClients+1; i < 4; i++)
|
||||||
SerialInterface::ChangeDevice(SI_DUMMY, (int)i);
|
SerialInterface::ChangeDevice(SI_DUMMY, 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)
|
||||||
{
|
{
|
||||||
// First Data has been received !
|
|
||||||
m_Logging->AppendText(_("** Data received from Peer. Starting Sync !"));
|
|
||||||
|
|
||||||
// Set our practical frame delay
|
// Set our practical frame delay
|
||||||
if (recv_value == 0xA1) // init number
|
|
||||||
{
|
|
||||||
m_frameDelay = m_loopframe;
|
m_frameDelay = m_loopframe;
|
||||||
m_loopframe = 0;
|
m_loopframe = 0;
|
||||||
|
|
||||||
|
// First Data has been received !
|
||||||
|
m_Logging->AppendText(_("** Data received from Peer. Starting Sync !"));
|
||||||
m_Logging->AppendText(wxString::Format(wxT(" Frame Delay : %d **\n"), m_frameDelay));
|
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;
|
||||||
}
|
}
|
||||||
|
@ -270,25 +278,33 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
|
||||||
|
|
||||||
// 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)
|
||||||
|
{
|
||||||
|
m_CriticalSection.Enter();
|
||||||
|
if (m_data_received && isVersus)
|
||||||
{
|
{
|
||||||
if (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();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
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)
|
||||||
{
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
m_CriticalSection.Enter();
|
||||||
if (m_data_received)
|
if (m_data_received)
|
||||||
{
|
{
|
||||||
netValues[0] = m_netvalues[client][0];
|
netValues[0] = m_netvalues[client][0];
|
||||||
netValues[1] = m_netvalues[client][1];
|
netValues[1] = m_netvalues[client][1];
|
||||||
|
m_data_received = false;
|
||||||
|
|
||||||
|
m_CriticalSection.Leave();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_CriticalSection.Leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
wxCriticalSectionLocker lock(m_CriticalSection);
|
||||||
}
|
|
||||||
|
|
||||||
return m_data_received;
|
return m_data_received;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,6 +498,7 @@ void GameListPopup::OnButtons(wxCommandEvent& event)
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
case wxID_OK:
|
case wxID_OK:
|
||||||
|
if (m_GameList->GetSelection() != wxNOT_FOUND)
|
||||||
m_netParent->ChangeSelectedGame(std::string(m_GameList_str[m_GameList->GetSelection()].mb_str()));
|
m_netParent->ChangeSelectedGame(std::string(m_GameList_str[m_GameList->GetSelection()].mb_str()));
|
||||||
Destroy();
|
Destroy();
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue