Merge branch 'netplay'
This commit is contained in:
commit
0d2083c670
|
@ -10,7 +10,6 @@ set(SRCS Src/ActionReplay.cpp
|
|||
Src/GeckoCodeConfig.cpp
|
||||
Src/GeckoCode.cpp
|
||||
Src/Movie.cpp
|
||||
Src/NetPlay.cpp
|
||||
Src/NetPlayClient.cpp
|
||||
Src/NetPlayServer.cpp
|
||||
Src/PatchEngine.cpp
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="DebugFast|Win32">
|
||||
|
@ -334,7 +334,6 @@
|
|||
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_WiiMote.cpp" />
|
||||
<ClCompile Include="Src\x64MemTools.cpp" />
|
||||
<ClCompile Include="Src\Movie.cpp" />
|
||||
<ClCompile Include="Src\NetPlay.cpp" />
|
||||
<ClCompile Include="Src\NetPlayClient.cpp" />
|
||||
<ClCompile Include="Src\NetPlayServer.cpp" />
|
||||
<ClCompile Include="Src\PatchEngine.cpp" />
|
||||
|
@ -540,7 +539,6 @@
|
|||
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_WiiMote.h" />
|
||||
<ClInclude Include="Src\MemTools.h" />
|
||||
<ClInclude Include="Src\Movie.h" />
|
||||
<ClInclude Include="Src\NetPlay.h" />
|
||||
<ClInclude Include="Src\PatchEngine.h" />
|
||||
<ClInclude Include="Src\DSPEmulator.h" />
|
||||
<ClInclude Include="Src\PowerPC\CPUCoreBase.h" />
|
||||
|
@ -599,4 +597,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Src\ConfigManager.cpp" />
|
||||
|
@ -529,9 +529,6 @@
|
|||
<ClCompile Include="Src\HW\Wiimote.cpp">
|
||||
<Filter>HW %28Flipper/Hollywood%29\Wiimote</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Src\NetPlay.cpp">
|
||||
<Filter>NetPlay</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Src\NetPlayServer.cpp">
|
||||
<Filter>NetPlay</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1014,9 +1011,6 @@
|
|||
<ClInclude Include="Src\PowerPC\CPUCoreBase.h">
|
||||
<Filter>PowerPC</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Src\NetPlay.h">
|
||||
<Filter>NetPlay</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Src\BootManager.h" />
|
||||
<ClInclude Include="Src\FifoPlayer\FifoDataFile.h">
|
||||
<Filter>FifoPlayer</Filter>
|
||||
|
@ -1177,9 +1171,6 @@
|
|||
<Filter Include="HW %28Flipper/Hollywood%29\Wiimote\Real">
|
||||
<UniqueIdentifier>{1c21a3e1-b791-4a23-b0d5-ed2b2c34007f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="NetPlay">
|
||||
<UniqueIdentifier>{231ceb02-1122-402a-87a8-094a9ed768c2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="FifoPlayer">
|
||||
<UniqueIdentifier>{ca7d56f7-4e84-4d15-9aea-7ae6fa7d6586}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
@ -1187,4 +1178,4 @@
|
|||
<UniqueIdentifier>{3e9e6e83-c1bf-45f9-aeff-231f98f60d29}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "Host.h"
|
||||
#include "VideoBackendBase.h"
|
||||
#include "Movie.h"
|
||||
#include "NetPlay.h"
|
||||
#include "NetPlayClient.h"
|
||||
|
||||
namespace BootManager
|
||||
{
|
||||
|
@ -138,7 +138,7 @@ bool BootCore(const std::string& _rFilename)
|
|||
}
|
||||
}
|
||||
|
||||
if (NetPlay::GetNetPlayPtr())
|
||||
if (NetPlay::IsNetPlayRunning())
|
||||
{
|
||||
StartUp.bDSPHLE = g_NetPlaySettings.m_DSPHLE;
|
||||
StartUp.bEnableMemcardSaving = g_NetPlaySettings.m_WriteToMemcard;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "../ConfigManager.h"
|
||||
#include "../CoreTiming.h"
|
||||
#include "../Movie.h"
|
||||
#include "../NetPlay.h"
|
||||
#include "../NetPlayClient.h"
|
||||
|
||||
#include "SystemTimers.h"
|
||||
#include "ProcessorInterface.h"
|
||||
|
@ -262,7 +262,7 @@ void Init()
|
|||
|
||||
if (Movie::IsRecordingInput() || Movie::IsPlayingInput())
|
||||
AddDevice(Movie::IsUsingPad(i) ? (Movie::IsUsingBongo(i) ? SIDEVICE_GC_TARUKONGA : SIDEVICE_GC_CONTROLLER) : SIDEVICE_NONE, i);
|
||||
else if (NetPlay::GetNetPlayPtr())
|
||||
else if (NetPlay::IsNetPlayRunning())
|
||||
AddDevice((SIDevices) g_NetPlaySettings.m_Controllers[i], i);
|
||||
else
|
||||
AddDevice(SConfig::GetInstance().m_SIDevice[i], i);
|
||||
|
@ -644,7 +644,7 @@ void RunSIBuffer()
|
|||
int GetTicksToNextSIPoll()
|
||||
{
|
||||
// Poll for input at regular intervals (once per frame) when playing or recording a movie
|
||||
if (Movie::IsPlayingInput() || Movie::IsRecordingInput() || NetPlay::GetNetPlayPtr())
|
||||
if (Movie::IsPlayingInput() || Movie::IsRecordingInput() || NetPlay::IsNetPlayRunning())
|
||||
{
|
||||
return SystemTimers::GetTicksPerSecond() / VideoInterface::TargetRefreshRate;
|
||||
}
|
||||
|
|
|
@ -1,401 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "NetPlay.h"
|
||||
|
||||
// for wiimote
|
||||
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
|
||||
#include "IPC_HLE/WII_IPC_HLE_WiiMote.h"
|
||||
// for gcpad
|
||||
#include "HW/SI_DeviceGCController.h"
|
||||
#include "HW/SI_DeviceGCSteeringWheel.h"
|
||||
#include "HW/SI_DeviceDanceMat.h"
|
||||
// for gctime
|
||||
#include "HW/EXI_DeviceIPL.h"
|
||||
// for wiimote/ OSD messages
|
||||
#include "Core.h"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
std::mutex crit_netplay_ptr;
|
||||
static NetPlay* netplay_ptr = NULL;
|
||||
NetSettings g_NetPlaySettings;
|
||||
|
||||
#define RPT_SIZE_HACK (1 << 16)
|
||||
|
||||
// called from ---GUI--- thread
|
||||
NetPlay::NetPlay(NetPlayUI* dialog)
|
||||
: m_dialog(dialog), m_is_running(false), m_do_loop(true)
|
||||
{
|
||||
m_target_buffer_size = 20;
|
||||
ClearBuffers();
|
||||
}
|
||||
|
||||
void NetPlay_Enable(NetPlay* const np)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
|
||||
netplay_ptr = np;
|
||||
}
|
||||
|
||||
void NetPlay_Disable()
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
|
||||
netplay_ptr = NULL;
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
NetPlay::~NetPlay()
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
|
||||
netplay_ptr = NULL;
|
||||
|
||||
// not perfect
|
||||
if (m_is_running)
|
||||
StopGame();
|
||||
}
|
||||
|
||||
NetPlay::Player::Player()
|
||||
{
|
||||
memset(pad_map, -1, sizeof(pad_map));
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
std::string NetPlay::Player::ToString() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |";
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-');
|
||||
ss << '|';
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
NetPad::NetPad()
|
||||
{
|
||||
nHi = 0x00808080;
|
||||
nLo = 0x80800000;
|
||||
}
|
||||
|
||||
NetPad::NetPad(const SPADStatus* const pad_status)
|
||||
{
|
||||
nHi = (u32)((u8)pad_status->stickY);
|
||||
nHi |= (u32)((u8)pad_status->stickX << 8);
|
||||
nHi |= (u32)((u16)pad_status->button << 16);
|
||||
nHi |= 0x00800000;
|
||||
nLo = (u8)pad_status->triggerRight;
|
||||
nLo |= (u32)((u8)pad_status->triggerLeft << 8);
|
||||
nLo |= (u32)((u8)pad_status->substickY << 16);
|
||||
nLo |= (u32)((u8)pad_status->substickX << 24);
|
||||
}
|
||||
|
||||
// called from ---NETPLAY--- thread
|
||||
void NetPlay::ClearBuffers()
|
||||
{
|
||||
// clear pad buffers, Clear method isn't thread safe
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
{
|
||||
while (m_pad_buffer[i].Size())
|
||||
m_pad_buffer[i].Pop();
|
||||
|
||||
while (m_wiimote_buffer[i].Size())
|
||||
m_wiimote_buffer[i].Pop();
|
||||
|
||||
m_wiimote_input[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
bool NetPlay::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
|
||||
// in game mapping for this local pad
|
||||
unsigned int in_game_num = m_local_player->pad_map[pad_nb];
|
||||
|
||||
// does this local pad map in game?
|
||||
if (in_game_num < 4)
|
||||
{
|
||||
NetPad np(pad_status);
|
||||
|
||||
// adjust the buffer either up or down
|
||||
// inserting multiple padstates or dropping states
|
||||
while (m_pad_buffer[in_game_num].Size() <= m_target_buffer_size)
|
||||
{
|
||||
// add to buffer
|
||||
m_pad_buffer[in_game_num].Push(np);
|
||||
|
||||
// send
|
||||
SendPadState(pad_nb, np);
|
||||
}
|
||||
}
|
||||
|
||||
} // unlock players
|
||||
|
||||
//Common::Timer bufftimer;
|
||||
//bufftimer.Start();
|
||||
|
||||
// get padstate from buffer and send to game
|
||||
while (!m_pad_buffer[pad_nb].Pop(*netvalues))
|
||||
{
|
||||
// wait for receiving thread to push some data
|
||||
Common::SleepCurrentThread(1);
|
||||
|
||||
if (false == m_is_running)
|
||||
return false;
|
||||
|
||||
// TODO: check the time of bufftimer here,
|
||||
// if it gets pretty high, ask the user if they want to disconnect
|
||||
|
||||
}
|
||||
|
||||
//u64 hangtime = bufftimer.GetTimeElapsed();
|
||||
//if (hangtime > 10)
|
||||
//{
|
||||
// std::ostringstream ss;
|
||||
// ss << "Pad " << (int)pad_nb << ": Had to wait " << hangtime << "ms for pad data. (increase pad Buffer maybe)";
|
||||
// Core::DisplayMessage(ss.str(), 1000);
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
void NetPlay::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 NetPlay::WiimoteUpdate(int _number)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> 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
|
||||
|
||||
// does this local pad map in game?
|
||||
if (in_game_num < 4)
|
||||
{
|
||||
m_wiimote_buffer[in_game_num].Push(m_wiimote_input[_number]);
|
||||
|
||||
// TODO: send it
|
||||
|
||||
m_wiimote_input[_number].clear();
|
||||
}
|
||||
|
||||
} // unlock players
|
||||
|
||||
if (0 == m_wiimote_buffer[_number].Size())
|
||||
{
|
||||
//PanicAlert("PANIC");
|
||||
return;
|
||||
}
|
||||
|
||||
NetWiimote nw;
|
||||
m_wiimote_buffer[_number].Pop(nw);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
bool NetPlay::StartGame(const std::string &path)
|
||||
{
|
||||
if (m_is_running)
|
||||
{
|
||||
PanicAlertT("Game is already running!");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dialog->AppendChat(" -- STARTING GAME -- ");
|
||||
|
||||
m_is_running = true;
|
||||
NetPlay_Enable(this);
|
||||
|
||||
ClearBuffers();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread and ---NETPLAY--- thread (client side)
|
||||
bool NetPlay::StopGame()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
|
||||
if (false == m_is_running)
|
||||
{
|
||||
PanicAlertT("Game isn't running!");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dialog->AppendChat(" -- STOPPING GAME -- ");
|
||||
|
||||
m_is_running = false;
|
||||
NetPlay_Disable();
|
||||
|
||||
// stop game
|
||||
m_dialog->StopGame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetPlay::SetMemcardWriteEnabled(bool enabled)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
g_NetPlaySettings.m_WriteToMemcard = enabled;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
u8 NetPlay::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)
|
||||
if (numPAD == m_local_player->pad_map[i])
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void NetPlay::GetNetSettings()
|
||||
{
|
||||
SConfig &instance = SConfig::GetInstance();
|
||||
g_NetPlaySettings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE;
|
||||
g_NetPlaySettings.m_DSPEnableJIT = instance.m_EnableJIT;
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
g_NetPlaySettings.m_Controllers[i] = SConfig::GetInstance().m_SIDevice[i];
|
||||
}
|
||||
|
||||
// stuff hacked into dolphin
|
||||
|
||||
// called from ---CPU--- thread
|
||||
// Actual Core function which is called on every frame
|
||||
bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
|
||||
|
||||
if (netplay_ptr)
|
||||
return netplay_ptr->GetNetPads(numPAD, &PadStatus, (NetPad*)PADStatus);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
|
||||
{
|
||||
return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus);
|
||||
}
|
||||
|
||||
bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
|
||||
{
|
||||
return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus);
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
// so all players' games get the same time
|
||||
u32 CEXIIPL::NetPlay_GetGCTime()
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
|
||||
|
||||
if (netplay_ptr)
|
||||
return 1272737767; // watev
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
// return the local pad num that should rumble given a ingame pad num
|
||||
u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_ptr);
|
||||
|
||||
if (netplay_ptr)
|
||||
return netplay_ptr->GetPadNum(numPAD);
|
||||
else
|
||||
return numPAD;
|
||||
}
|
||||
|
||||
u8 CSIDevice_GCSteeringWheel::NetPlay_GetPadNum(u8 numPAD)
|
||||
{
|
||||
return CSIDevice_GCController::NetPlay_GetPadNum(numPAD);
|
||||
}
|
||||
|
||||
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_ptr);
|
||||
|
||||
//if (netplay_ptr)
|
||||
// netplay_ptr->WiimoteUpdate(_number);
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
//
|
||||
int CWII_IPC_HLE_WiiMote::NetPlay_GetWiimoteNum(int _number)
|
||||
{
|
||||
//CritLocker crit(crit_netplay_ptr);
|
||||
|
||||
//if (netplay_ptr)
|
||||
// return netplay_ptr->GetPadNum(_number); // just using gcpad mapping for now
|
||||
//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<std::mutex> lk(crit_netplay_ptr);
|
||||
|
||||
if (netplay_ptr)
|
||||
//{
|
||||
// if (_Size >= RPT_SIZE_HACK)
|
||||
// {
|
||||
// _Size -= RPT_SIZE_HACK;
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// netplay_ptr->WiimoteInput(_number, _channelID, _pData, _Size);
|
||||
// // don't use this packet
|
||||
return true;
|
||||
// }
|
||||
//}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
NetPlay* NetPlay::GetNetPlayPtr()
|
||||
{
|
||||
return netplay_ptr;
|
||||
}
|
|
@ -1,275 +0,0 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef _NETPLAY_H
|
||||
#define _NETPLAY_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "CommonTypes.h"
|
||||
#include "Thread.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <SFML/Network.hpp>
|
||||
|
||||
#include "GCPadStatus.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
|
||||
#include "FifoQueue.h"
|
||||
|
||||
class NetPad
|
||||
{
|
||||
public:
|
||||
NetPad();
|
||||
NetPad(const SPADStatus* const);
|
||||
|
||||
u32 nHi;
|
||||
u32 nLo;
|
||||
};
|
||||
|
||||
struct NetSettings
|
||||
{
|
||||
bool m_DSPHLE;
|
||||
bool m_DSPEnableJIT;
|
||||
bool m_WriteToMemcard;
|
||||
u8 m_Controllers[4];
|
||||
};
|
||||
extern NetSettings g_NetPlaySettings;
|
||||
|
||||
struct Rpt : public std::vector<u8>
|
||||
{
|
||||
u16 channel;
|
||||
};
|
||||
|
||||
typedef std::vector<Rpt> NetWiimote;
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2013-07-22"
|
||||
|
||||
// messages
|
||||
enum
|
||||
{
|
||||
NP_MSG_PLAYER_JOIN = 0x10,
|
||||
NP_MSG_PLAYER_LEAVE = 0x11,
|
||||
|
||||
NP_MSG_CHAT_MESSAGE = 0x30,
|
||||
|
||||
NP_MSG_PAD_DATA = 0x60,
|
||||
NP_MSG_PAD_MAPPING = 0x61,
|
||||
NP_MSG_PAD_BUFFER = 0x62,
|
||||
|
||||
NP_MSG_WIIMOTE_DATA = 0x70,
|
||||
NP_MSG_WIIMOTE_MAPPING = 0x71, // just using pad mapping for now
|
||||
|
||||
NP_MSG_START_GAME = 0xA0,
|
||||
NP_MSG_CHANGE_GAME = 0xA1,
|
||||
NP_MSG_STOP_GAME = 0xA2,
|
||||
NP_MSG_DISABLE_GAME = 0xA3,
|
||||
|
||||
NP_MSG_READY = 0xD0,
|
||||
NP_MSG_NOT_READY = 0xD1,
|
||||
|
||||
NP_MSG_PING = 0xE0,
|
||||
NP_MSG_PONG = 0xE1,
|
||||
};
|
||||
|
||||
typedef u8 MessageId;
|
||||
typedef u8 PlayerId;
|
||||
typedef s8 PadMapping;
|
||||
typedef u32 FrameNum;
|
||||
|
||||
enum
|
||||
{
|
||||
CON_ERR_SERVER_FULL = 1,
|
||||
CON_ERR_GAME_RUNNING,
|
||||
CON_ERR_VERSION_MISMATCH
|
||||
};
|
||||
|
||||
class NetPlayUI
|
||||
{
|
||||
public:
|
||||
virtual ~NetPlayUI() {};
|
||||
|
||||
virtual void BootGame(const std::string& filename) = 0;
|
||||
virtual void StopGame() = 0;
|
||||
|
||||
virtual void Update() = 0;
|
||||
virtual void AppendChat(const std::string& msg) = 0;
|
||||
|
||||
virtual void OnMsgChangeGame(const std::string& filename) = 0;
|
||||
virtual void OnMsgStartGame() = 0;
|
||||
virtual void OnMsgStopGame() = 0;
|
||||
};
|
||||
|
||||
class NetPlay
|
||||
{
|
||||
public:
|
||||
NetPlay(NetPlayUI* _dialog);
|
||||
virtual ~NetPlay();
|
||||
//virtual void ThreadFunc() = 0;
|
||||
|
||||
bool is_connected;
|
||||
|
||||
// Send and receive pads values
|
||||
void WiimoteInput(int _number, u16 _channelID, const void* _pData, u32 _Size);
|
||||
void WiimoteUpdate(int _number);
|
||||
bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
virtual bool ChangeGame(const std::string& game) = 0;
|
||||
virtual void GetPlayerList(std::string& list, std::vector<int>& pid_list) = 0;
|
||||
virtual void SendChatMessage(const std::string& msg) = 0;
|
||||
|
||||
virtual bool StartGame(const std::string &path);
|
||||
virtual bool StopGame();
|
||||
|
||||
virtual void SetMemcardWriteEnabled(bool enabled);
|
||||
//void PushPadStates(unsigned int count);
|
||||
|
||||
u8 GetPadNum(u8 numPAD);
|
||||
static NetPlay* GetNetPlayPtr();
|
||||
|
||||
protected:
|
||||
//void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues);
|
||||
void ClearBuffers();
|
||||
void GetNetSettings();
|
||||
virtual void SendPadState(const PadMapping local_nb, const NetPad& np) = 0;
|
||||
|
||||
struct
|
||||
{
|
||||
std::recursive_mutex game;
|
||||
// lock order
|
||||
std::recursive_mutex players, send;
|
||||
} m_crit;
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
Player();
|
||||
std::string ToString() const;
|
||||
|
||||
PlayerId pid;
|
||||
std::string name;
|
||||
PadMapping pad_map[4];
|
||||
std::string revision;
|
||||
};
|
||||
|
||||
Common::FifoQueue<NetPad> m_pad_buffer[4];
|
||||
Common::FifoQueue<NetWiimote> m_wiimote_buffer[4];
|
||||
|
||||
NetWiimote m_wiimote_input[4];
|
||||
|
||||
NetPlayUI* m_dialog;
|
||||
sf::SocketTCP m_socket;
|
||||
std::thread m_thread;
|
||||
sf::Selector<sf::SocketTCP> m_selector;
|
||||
|
||||
std::string m_selected_game;
|
||||
volatile bool m_is_running;
|
||||
volatile bool m_do_loop;
|
||||
|
||||
unsigned int m_target_buffer_size;
|
||||
|
||||
Player* m_local_player;
|
||||
|
||||
u32 m_current_game;
|
||||
};
|
||||
|
||||
void NetPlay_Enable(NetPlay* const np);
|
||||
void NetPlay_Disable();
|
||||
|
||||
class NetPlayServer : public NetPlay
|
||||
{
|
||||
public:
|
||||
void ThreadFunc();
|
||||
|
||||
NetPlayServer(const u16 port, const std::string& name, NetPlayUI* dialog);
|
||||
~NetPlayServer();
|
||||
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
|
||||
// Send and receive pads values
|
||||
//bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
bool ChangeGame(const std::string& game);
|
||||
void SendChatMessage(const std::string& msg);
|
||||
|
||||
bool StartGame(const std::string &path);
|
||||
bool StopGame();
|
||||
|
||||
bool GetPadMapping(const int pid, int map[]);
|
||||
bool SetPadMapping(const int pid, const int map[]);
|
||||
|
||||
u64 CalculateMinimumBufferTime();
|
||||
void AdjustPadBufferSize(unsigned int size);
|
||||
|
||||
#ifdef USE_UPNP
|
||||
void TryPortmapping(u16 port);
|
||||
#endif
|
||||
|
||||
private:
|
||||
class Client : public Player
|
||||
{
|
||||
public:
|
||||
Client() : ping(0), current_game(0) {}
|
||||
|
||||
sf::SocketTCP socket;
|
||||
u64 ping;
|
||||
u32 current_game;
|
||||
};
|
||||
|
||||
void SendPadState(const PadMapping local_nb, const NetPad& np);
|
||||
void SendToClients(sf::Packet& packet, const PlayerId skip_pid = 0);
|
||||
unsigned int OnConnect(sf::SocketTCP& socket);
|
||||
unsigned int OnDisconnect(sf::SocketTCP& socket);
|
||||
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
|
||||
void UpdatePadMapping();
|
||||
|
||||
std::map<sf::SocketTCP, Client> m_players;
|
||||
|
||||
Common::Timer m_ping_timer;
|
||||
u32 m_ping_key;
|
||||
bool m_update_pings;
|
||||
|
||||
#ifdef USE_UPNP
|
||||
static void mapPortThread(const u16 port);
|
||||
static void unmapPortThread();
|
||||
|
||||
static bool initUPnP();
|
||||
static bool UPnPMapPort(const std::string& addr, const u16 port);
|
||||
static bool UPnPUnmapPort(const u16 port);
|
||||
|
||||
static struct UPNPUrls m_upnp_urls;
|
||||
static struct IGDdatas m_upnp_data;
|
||||
static u16 m_upnp_mapped;
|
||||
static bool m_upnp_inited;
|
||||
static bool m_upnp_error;
|
||||
static std::thread m_upnp_thread;
|
||||
#endif
|
||||
};
|
||||
|
||||
class NetPlayClient : public NetPlay
|
||||
{
|
||||
public:
|
||||
void ThreadFunc();
|
||||
|
||||
NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name);
|
||||
~NetPlayClient();
|
||||
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
|
||||
// Send and receive pads values
|
||||
//bool GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
bool StartGame(const std::string &path);
|
||||
bool ChangeGame(const std::string& game);
|
||||
void SendChatMessage(const std::string& msg);
|
||||
|
||||
private:
|
||||
void SendPadState(const PadMapping local_nb, const NetPad& np);
|
||||
unsigned int OnData(sf::Packet& packet);
|
||||
|
||||
PlayerId m_pid;
|
||||
std::map<PlayerId, Player> m_players;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -2,21 +2,81 @@
|
|||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "NetPlay.h"
|
||||
#include "NetPlayClient.h"
|
||||
|
||||
// for wiimote
|
||||
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
|
||||
#include "IPC_HLE/WII_IPC_HLE_WiiMote.h"
|
||||
// for gcpad
|
||||
#include "HW/SI_DeviceGCController.h"
|
||||
#include "HW/SI_DeviceGCSteeringWheel.h"
|
||||
#include "HW/SI_DeviceDanceMat.h"
|
||||
// for gctime
|
||||
#include "HW/EXI_DeviceIPL.h"
|
||||
// for wiimote/ OSD messages
|
||||
#include "Core.h"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
std::mutex crit_netplay_client;
|
||||
static NetPlayClient * netplay_client = NULL;
|
||||
NetSettings g_NetPlaySettings;
|
||||
|
||||
#define RPT_SIZE_HACK (1 << 16)
|
||||
|
||||
NetPlayClient::Player::Player()
|
||||
{
|
||||
memset(pad_map, -1, sizeof(pad_map));
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
std::string NetPlayClient::Player::ToString() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |";
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-');
|
||||
ss << " | " << ping << "ms";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
NetPad::NetPad()
|
||||
{
|
||||
nHi = 0x00808080;
|
||||
nLo = 0x80800000;
|
||||
}
|
||||
|
||||
NetPad::NetPad(const SPADStatus* const pad_status)
|
||||
{
|
||||
nHi = (u32)((u8)pad_status->stickY);
|
||||
nHi |= (u32)((u8)pad_status->stickX << 8);
|
||||
nHi |= (u32)((u16)pad_status->button << 16);
|
||||
nHi |= 0x00800000;
|
||||
nLo = (u8)pad_status->triggerRight;
|
||||
nLo |= (u32)((u8)pad_status->triggerLeft << 8);
|
||||
nLo |= (u32)((u8)pad_status->substickY << 16);
|
||||
nLo |= (u32)((u8)pad_status->substickX << 24);
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
NetPlayClient::~NetPlayClient()
|
||||
{
|
||||
// not perfect
|
||||
if (m_is_running)
|
||||
StopGame();
|
||||
|
||||
if (is_connected)
|
||||
{
|
||||
m_do_loop = false;
|
||||
m_thread.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name) : NetPlay(dialog)
|
||||
NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name) : m_dialog(dialog), m_is_running(false), m_do_loop(true)
|
||||
{
|
||||
m_target_buffer_size = 20;
|
||||
ClearBuffers();
|
||||
|
||||
is_connected = false;
|
||||
|
||||
// why is false successful? documentation says true is
|
||||
|
@ -233,6 +293,21 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
|||
}
|
||||
break;
|
||||
|
||||
case NP_MSG_PLAYER_PING_DATA:
|
||||
{
|
||||
PlayerId pid;
|
||||
packet >> pid;
|
||||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
Player& player = m_players[pid];
|
||||
packet >> player.ping;
|
||||
}
|
||||
|
||||
m_dialog->Update();
|
||||
}
|
||||
break;
|
||||
|
||||
default :
|
||||
PanicAlertT("Unknown message received with id : %d", mid);
|
||||
break;
|
||||
|
@ -328,12 +403,31 @@ bool NetPlayClient::StartGame(const std::string &path)
|
|||
spac << m_current_game;
|
||||
spac << (char *)&g_NetPlaySettings;
|
||||
|
||||
if (false == NetPlay::StartGame(path))
|
||||
return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
m_socket.Send(spac);
|
||||
|
||||
if (m_is_running)
|
||||
{
|
||||
PanicAlertT("Game is already running!");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dialog->AppendChat(" -- STARTING GAME -- ");
|
||||
|
||||
m_is_running = true;
|
||||
NetPlay_Enable(this);
|
||||
|
||||
ClearBuffers();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -342,3 +436,283 @@ bool NetPlayClient::ChangeGame(const std::string&)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// called from ---NETPLAY--- thread
|
||||
void NetPlayClient::ClearBuffers()
|
||||
{
|
||||
// clear pad buffers, Clear method isn't thread safe
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
{
|
||||
while (m_pad_buffer[i].Size())
|
||||
m_pad_buffer[i].Pop();
|
||||
|
||||
while (m_wiimote_buffer[i].Size())
|
||||
m_wiimote_buffer[i].Pop();
|
||||
|
||||
m_wiimote_input[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
bool NetPlayClient::GetNetPads(const u8 pad_nb, const SPADStatus* const pad_status, NetPad* const netvalues)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
|
||||
// in game mapping for this local pad
|
||||
unsigned int in_game_num = m_local_player->pad_map[pad_nb];
|
||||
|
||||
// does this local pad map in game?
|
||||
if (in_game_num < 4)
|
||||
{
|
||||
NetPad np(pad_status);
|
||||
|
||||
// adjust the buffer either up or down
|
||||
// inserting multiple padstates or dropping states
|
||||
while (m_pad_buffer[in_game_num].Size() <= m_target_buffer_size)
|
||||
{
|
||||
// add to buffer
|
||||
m_pad_buffer[in_game_num].Push(np);
|
||||
|
||||
// send
|
||||
SendPadState(pad_nb, np);
|
||||
}
|
||||
}
|
||||
|
||||
} // unlock players
|
||||
|
||||
//Common::Timer bufftimer;
|
||||
//bufftimer.Start();
|
||||
|
||||
// get padstate from buffer and send to game
|
||||
while (!m_pad_buffer[pad_nb].Pop(*netvalues))
|
||||
{
|
||||
// wait for receiving thread to push some data
|
||||
Common::SleepCurrentThread(1);
|
||||
|
||||
if (false == m_is_running)
|
||||
return false;
|
||||
|
||||
// TODO: check the time of bufftimer here,
|
||||
// if it gets pretty high, ask the user if they want to disconnect
|
||||
|
||||
}
|
||||
|
||||
//u64 hangtime = bufftimer.GetTimeElapsed();
|
||||
//if (hangtime > 10)
|
||||
//{
|
||||
// std::ostringstream ss;
|
||||
// ss << "Pad " << (int)pad_nb << ": Had to wait " << hangtime << "ms for pad data. (increase pad Buffer maybe)";
|
||||
// Core::DisplayMessage(ss.str(), 1000);
|
||||
//}
|
||||
|
||||
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)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> 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
|
||||
|
||||
// does this local pad map in game?
|
||||
if (in_game_num < 4)
|
||||
{
|
||||
m_wiimote_buffer[in_game_num].Push(m_wiimote_input[_number]);
|
||||
|
||||
// TODO: send it
|
||||
|
||||
m_wiimote_input[_number].clear();
|
||||
}
|
||||
|
||||
} // unlock players
|
||||
|
||||
if (0 == m_wiimote_buffer[_number].Size())
|
||||
{
|
||||
//PanicAlert("PANIC");
|
||||
return;
|
||||
}
|
||||
|
||||
NetWiimote nw;
|
||||
m_wiimote_buffer[_number].Pop(nw);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread and ---NETPLAY--- thread (client side)
|
||||
bool NetPlayClient::StopGame()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
|
||||
if (false == m_is_running)
|
||||
{
|
||||
PanicAlertT("Game isn't running!");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dialog->AppendChat(" -- STOPPING GAME -- ");
|
||||
|
||||
m_is_running = false;
|
||||
NetPlay_Disable();
|
||||
|
||||
// stop game
|
||||
m_dialog->StopGame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
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)
|
||||
if (numPAD == m_local_player->pad_map[i])
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// stuff hacked into dolphin
|
||||
|
||||
// called from ---CPU--- thread
|
||||
// Actual Core function which is called on every frame
|
||||
bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_client);
|
||||
|
||||
if (netplay_client)
|
||||
return netplay_client->GetNetPads(numPAD, &PadStatus, (NetPad*)PADStatus);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
|
||||
{
|
||||
return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus);
|
||||
}
|
||||
|
||||
bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
|
||||
{
|
||||
return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus);
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
// so all players' games get the same time
|
||||
u32 CEXIIPL::NetPlay_GetGCTime()
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_client);
|
||||
|
||||
if (netplay_client)
|
||||
return 1272737767; // watev
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
// return the local pad num that should rumble given a ingame pad num
|
||||
u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_client);
|
||||
|
||||
if (netplay_client)
|
||||
return netplay_client->GetPadNum(numPAD);
|
||||
else
|
||||
return numPAD;
|
||||
}
|
||||
|
||||
u8 CSIDevice_GCSteeringWheel::NetPlay_GetPadNum(u8 numPAD)
|
||||
{
|
||||
return CSIDevice_GCController::NetPlay_GetPadNum(numPAD);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//if (netplay_client)
|
||||
// return netplay_client->GetPadNum(_number); // just using gcpad mapping for now
|
||||
//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<std::mutex> 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;
|
||||
}
|
||||
|
||||
void NetPlay_Enable(NetPlayClient* const np)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_client);
|
||||
netplay_client = np;
|
||||
}
|
||||
|
||||
void NetPlay_Disable()
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(crit_netplay_client);
|
||||
netplay_client = NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef _NETPLAY_H
|
||||
#define _NETPLAY_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "CommonTypes.h"
|
||||
#include "Thread.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <SFML/Network.hpp>
|
||||
|
||||
#include "NetPlayProto.h"
|
||||
#include "GCPadStatus.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
|
||||
#include "FifoQueue.h"
|
||||
|
||||
class NetPad
|
||||
{
|
||||
public:
|
||||
NetPad();
|
||||
NetPad(const SPADStatus* const);
|
||||
|
||||
u32 nHi;
|
||||
u32 nLo;
|
||||
};
|
||||
|
||||
class NetPlayUI
|
||||
{
|
||||
public:
|
||||
virtual ~NetPlayUI() {};
|
||||
|
||||
virtual void BootGame(const std::string& filename) = 0;
|
||||
virtual void StopGame() = 0;
|
||||
|
||||
virtual void Update() = 0;
|
||||
virtual void AppendChat(const std::string& msg) = 0;
|
||||
|
||||
virtual void OnMsgChangeGame(const std::string& filename) = 0;
|
||||
virtual void OnMsgStartGame() = 0;
|
||||
virtual void OnMsgStopGame() = 0;
|
||||
};
|
||||
|
||||
extern NetSettings g_NetPlaySettings;
|
||||
|
||||
class NetPlayClient
|
||||
{
|
||||
public:
|
||||
void ThreadFunc();
|
||||
|
||||
NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name);
|
||||
~NetPlayClient();
|
||||
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
|
||||
bool is_connected;
|
||||
|
||||
bool StartGame(const std::string &path);
|
||||
bool StopGame();
|
||||
bool ChangeGame(const std::string& game);
|
||||
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 GetNetPads(const u8 pad_nb, const SPADStatus* const, NetPad* const netvalues);
|
||||
|
||||
u8 GetPadNum(u8 numPAD);
|
||||
|
||||
protected:
|
||||
void ClearBuffers();
|
||||
|
||||
struct
|
||||
{
|
||||
std::recursive_mutex game;
|
||||
// lock order
|
||||
std::recursive_mutex players, send;
|
||||
} m_crit;
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
Player();
|
||||
std::string ToString() const;
|
||||
|
||||
PlayerId pid;
|
||||
std::string name;
|
||||
PadMapping pad_map[4];
|
||||
std::string revision;
|
||||
u32 ping;
|
||||
};
|
||||
|
||||
Common::FifoQueue<NetPad> m_pad_buffer[4];
|
||||
Common::FifoQueue<NetWiimote> m_wiimote_buffer[4];
|
||||
|
||||
NetWiimote m_wiimote_input[4];
|
||||
|
||||
NetPlayUI* m_dialog;
|
||||
sf::SocketTCP m_socket;
|
||||
std::thread m_thread;
|
||||
sf::Selector<sf::SocketTCP> m_selector;
|
||||
|
||||
std::string m_selected_game;
|
||||
volatile bool m_is_running;
|
||||
volatile bool m_do_loop;
|
||||
|
||||
unsigned int m_target_buffer_size;
|
||||
|
||||
Player* m_local_player;
|
||||
|
||||
u32 m_current_game;
|
||||
|
||||
private:
|
||||
void SendPadState(const PadMapping local_nb, const NetPad& np);
|
||||
unsigned int OnData(sf::Packet& packet);
|
||||
|
||||
PlayerId m_pid;
|
||||
std::map<PlayerId, Player> m_players;
|
||||
};
|
||||
|
||||
namespace NetPlay {
|
||||
bool IsNetPlayRunning();
|
||||
};
|
||||
|
||||
void NetPlay_Enable(NetPlayClient* const np);
|
||||
void NetPlay_Disable();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef _NETPLAY_PROTO_H
|
||||
#define _NETPLAY_PROTO_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "CommonTypes.h"
|
||||
|
||||
struct NetSettings
|
||||
{
|
||||
bool m_DSPHLE;
|
||||
bool m_DSPEnableJIT;
|
||||
bool m_WriteToMemcard;
|
||||
u8 m_Controllers[4];
|
||||
};
|
||||
|
||||
struct Rpt : public std::vector<u8>
|
||||
{
|
||||
u16 channel;
|
||||
};
|
||||
|
||||
typedef std::vector<Rpt> NetWiimote;
|
||||
|
||||
#define NETPLAY_VERSION "Dolphin NetPlay 2013-08-05"
|
||||
|
||||
// messages
|
||||
enum
|
||||
{
|
||||
NP_MSG_PLAYER_JOIN = 0x10,
|
||||
NP_MSG_PLAYER_LEAVE = 0x11,
|
||||
|
||||
NP_MSG_CHAT_MESSAGE = 0x30,
|
||||
|
||||
NP_MSG_PAD_DATA = 0x60,
|
||||
NP_MSG_PAD_MAPPING = 0x61,
|
||||
NP_MSG_PAD_BUFFER = 0x62,
|
||||
|
||||
NP_MSG_WIIMOTE_DATA = 0x70,
|
||||
NP_MSG_WIIMOTE_MAPPING = 0x71, // just using pad mapping for now
|
||||
|
||||
NP_MSG_START_GAME = 0xA0,
|
||||
NP_MSG_CHANGE_GAME = 0xA1,
|
||||
NP_MSG_STOP_GAME = 0xA2,
|
||||
NP_MSG_DISABLE_GAME = 0xA3,
|
||||
|
||||
NP_MSG_READY = 0xD0,
|
||||
NP_MSG_NOT_READY = 0xD1,
|
||||
|
||||
NP_MSG_PING = 0xE0,
|
||||
NP_MSG_PONG = 0xE1,
|
||||
NP_MSG_PLAYER_PING_DATA = 0xE2,
|
||||
};
|
||||
|
||||
typedef u8 MessageId;
|
||||
typedef u8 PlayerId;
|
||||
typedef s8 PadMapping;
|
||||
typedef u32 FrameNum;
|
||||
|
||||
enum
|
||||
{
|
||||
CON_ERR_SERVER_FULL = 1,
|
||||
CON_ERR_GAME_RUNNING,
|
||||
CON_ERR_VERSION_MISMATCH
|
||||
};
|
||||
|
||||
#endif
|
|
@ -2,15 +2,31 @@
|
|||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "NetPlay.h"
|
||||
#include "NetPlayServer.h"
|
||||
|
||||
NetPlayServer::Client::Client()
|
||||
{
|
||||
memset(pad_map, -1, sizeof(pad_map));
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
std::string NetPlayServer::Client::ToString() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << name << '[' << (char)(pid+'0') << "] : " << revision << " |";
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
ss << (pad_map[i]>=0 ? (char)(pad_map[i]+'1') : '-');
|
||||
ss << '|';
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
NetPlayServer::~NetPlayServer()
|
||||
{
|
||||
if (is_connected)
|
||||
{
|
||||
m_do_loop = false;
|
||||
m_thread.join();
|
||||
m_socket.Close();
|
||||
}
|
||||
|
||||
#ifdef USE_UPNP
|
||||
|
@ -22,35 +38,15 @@ NetPlayServer::~NetPlayServer()
|
|||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
NetPlayServer::NetPlayServer(const u16 port, const std::string& name, NetPlayUI* dialog) : NetPlay(dialog)
|
||||
NetPlayServer::NetPlayServer(const u16 port) : is_connected(false), m_is_running(false)
|
||||
{
|
||||
m_update_pings = true;
|
||||
|
||||
if (m_socket.Listen(port))
|
||||
{
|
||||
Client player;
|
||||
player.pid = 0;
|
||||
player.revision = netplay_dolphin_ver;
|
||||
player.socket = m_socket;
|
||||
player.name = name;
|
||||
|
||||
// map local pad 1 to game pad 1
|
||||
player.pad_map[0] = 0;
|
||||
|
||||
// add self to player list
|
||||
m_players[m_socket] = player;
|
||||
m_local_player = &m_players[m_socket];
|
||||
//PanicAlertT("Listening");
|
||||
|
||||
m_dialog->Update();
|
||||
|
||||
is_connected = true;
|
||||
|
||||
m_do_loop = true;
|
||||
m_selector.Add(m_socket);
|
||||
m_thread = std::thread(std::mem_fun(&NetPlayServer::ThreadFunc), this);
|
||||
}
|
||||
else
|
||||
is_connected = false;
|
||||
}
|
||||
|
||||
// called from ---NETPLAY--- thread
|
||||
|
@ -258,8 +254,6 @@ unsigned int NetPlayServer::OnConnect(sf::SocketTCP& socket)
|
|||
// add client to selector/ used for receiving
|
||||
m_selector.Add(socket);
|
||||
|
||||
m_dialog->Update();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -271,7 +265,6 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
|||
PanicAlertT("Client disconnect while game is running!! NetPlay is disabled. You must manually stop the game.");
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
m_is_running = false;
|
||||
NetPlay_Disable();
|
||||
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_DISABLE_GAME;
|
||||
|
@ -293,8 +286,6 @@ unsigned int NetPlayServer::OnDisconnect(sf::SocketTCP& socket)
|
|||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac);
|
||||
|
||||
m_dialog->Update();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -357,8 +348,6 @@ bool NetPlayServer::SetPadMapping(const int pid, const int map[])
|
|||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
UpdatePadMapping(); // sync pad mappings with everyone
|
||||
|
||||
m_dialog->Update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -380,29 +369,6 @@ void NetPlayServer::UpdatePadMapping()
|
|||
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread and ---NETPLAY--- thread
|
||||
u64 NetPlayServer::CalculateMinimumBufferTime()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
|
||||
std::map<sf::SocketTCP, Client>::const_iterator
|
||||
i = m_players.begin(),
|
||||
e = m_players.end();
|
||||
std::priority_queue<unsigned int> pings;
|
||||
for ( ;i!=e; ++i)
|
||||
pings.push(i->second.ping/2);
|
||||
|
||||
unsigned int required_ms = pings.top();
|
||||
// if there is more than 1 client, buffersize must be >= (2 highest ping times combined)
|
||||
if (pings.size() > 1)
|
||||
{
|
||||
pings.pop();
|
||||
required_ms += pings.top();
|
||||
}
|
||||
|
||||
return required_ms;
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread and ---NETPLAY--- thread
|
||||
void NetPlayServer::AdjustPadBufferSize(unsigned int size)
|
||||
{
|
||||
|
@ -447,12 +413,6 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac, player.pid);
|
||||
}
|
||||
|
||||
// add to gui
|
||||
std::ostringstream ss;
|
||||
ss << player.name << '[' << (char)(player.pid+'0') << "]: " << msg;
|
||||
|
||||
m_dialog->AppendChat(ss.str());
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -463,8 +423,8 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
break;
|
||||
|
||||
PadMapping map = 0;
|
||||
NetPad np;
|
||||
packet >> map >> np.nHi >> np.nLo;
|
||||
int hi, lo;
|
||||
packet >> map >> hi >> lo;
|
||||
|
||||
// check if client's pad indeed maps in game
|
||||
if (map >= 0 && map < 4)
|
||||
|
@ -477,14 +437,12 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
if (map < 0)
|
||||
return 1;
|
||||
|
||||
// add to pad buffer
|
||||
m_pad_buffer[(unsigned)map].Push(np);
|
||||
|
||||
// relay to clients
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PAD_DATA;
|
||||
spac << map; // in game mapping
|
||||
spac << np.nHi << np.nLo;
|
||||
spac << hi << lo;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac, player.pid);
|
||||
|
@ -498,11 +456,15 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, sf::SocketTCP& socket)
|
|||
packet >> ping_key;
|
||||
|
||||
if (m_ping_key == ping_key)
|
||||
{
|
||||
//PanicAlertT("Good pong");
|
||||
player.ping = ping;
|
||||
}
|
||||
m_dialog->Update();
|
||||
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PLAYER_PING_DATA;
|
||||
spac << player.pid;
|
||||
spac << player.ping;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -573,29 +535,16 @@ bool NetPlayServer::ChangeGame(const std::string &game)
|
|||
return true;
|
||||
}
|
||||
|
||||
// called from ---CPU--- thread
|
||||
void NetPlayServer::SendPadState(const PadMapping local_nb, const NetPad& np)
|
||||
// called from ---GUI--- thread
|
||||
void NetPlayServer::SetNetSettings(const NetSettings &settings)
|
||||
{
|
||||
// send to server
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_PAD_DATA;
|
||||
spac << m_local_player->pad_map[local_nb]; // in-game pad num
|
||||
spac << np.nHi << np.nLo;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac);
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
bool NetPlayServer::StartGame(const std::string &path)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
|
||||
GetNetSettings();
|
||||
if (false == NetPlay::StartGame(path))
|
||||
return false;
|
||||
|
||||
// TODO: i dont like this here
|
||||
m_current_game = Common::Timer::GetTimeMs();
|
||||
|
||||
// no change, just update with clients
|
||||
|
@ -604,17 +553,19 @@ bool NetPlayServer::StartGame(const std::string &path)
|
|||
// tell clients to start game
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_START_GAME;
|
||||
spac << NetPlay::m_current_game;
|
||||
spac << g_NetPlaySettings.m_DSPEnableJIT;
|
||||
spac << g_NetPlaySettings.m_DSPHLE;
|
||||
spac << g_NetPlaySettings.m_WriteToMemcard;
|
||||
spac << m_current_game;
|
||||
spac << m_settings.m_DSPEnableJIT;
|
||||
spac << m_settings.m_DSPHLE;
|
||||
spac << m_settings.m_WriteToMemcard;
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
spac << g_NetPlaySettings.m_Controllers[i];
|
||||
spac << m_settings.m_Controllers[i];
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
std::lock_guard<std::recursive_mutex> lks(m_crit.send);
|
||||
SendToClients(spac);
|
||||
|
||||
m_is_running = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -622,9 +573,6 @@ bool NetPlayServer::StartGame(const std::string &path)
|
|||
// called from ---GUI--- thread
|
||||
bool NetPlayServer::StopGame()
|
||||
{
|
||||
if (false == NetPlay::StopGame())
|
||||
return false;
|
||||
|
||||
// tell clients to stop game
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_STOP_GAME;
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef _NETPLAY_SERVER_H
|
||||
#define _NETPLAY_SERVER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "CommonTypes.h"
|
||||
#include "Thread.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <SFML/Network.hpp>
|
||||
|
||||
#include "NetPlayProto.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
|
||||
class NetPlayServer
|
||||
{
|
||||
public:
|
||||
void ThreadFunc();
|
||||
|
||||
NetPlayServer(const u16 port);
|
||||
~NetPlayServer();
|
||||
|
||||
void GetPlayerList(std::string& list, std::vector<int>& pid_list);
|
||||
|
||||
bool ChangeGame(const std::string& game);
|
||||
void SendChatMessage(const std::string& msg);
|
||||
|
||||
void SetNetSettings(const NetSettings &settings);
|
||||
|
||||
bool StartGame(const std::string &path);
|
||||
bool StopGame();
|
||||
|
||||
bool GetPadMapping(const int pid, int map[]);
|
||||
bool SetPadMapping(const int pid, const int map[]);
|
||||
|
||||
void AdjustPadBufferSize(unsigned int size);
|
||||
|
||||
bool is_connected;
|
||||
|
||||
#ifdef USE_UPNP
|
||||
void TryPortmapping(u16 port);
|
||||
#endif
|
||||
|
||||
private:
|
||||
class Client
|
||||
{
|
||||
public:
|
||||
Client();
|
||||
std::string ToString() const;
|
||||
|
||||
PlayerId pid;
|
||||
std::string name;
|
||||
PadMapping pad_map[4];
|
||||
std::string revision;
|
||||
|
||||
sf::SocketTCP socket;
|
||||
u32 ping;
|
||||
u32 current_game;
|
||||
};
|
||||
|
||||
void SendToClients(sf::Packet& packet, const PlayerId skip_pid = 0);
|
||||
unsigned int OnConnect(sf::SocketTCP& socket);
|
||||
unsigned int OnDisconnect(sf::SocketTCP& socket);
|
||||
unsigned int OnData(sf::Packet& packet, sf::SocketTCP& socket);
|
||||
void UpdatePadMapping();
|
||||
|
||||
NetSettings m_settings;
|
||||
|
||||
bool m_is_running;
|
||||
bool m_do_loop;
|
||||
Common::Timer m_ping_timer;
|
||||
u32 m_ping_key;
|
||||
bool m_update_pings;
|
||||
u32 m_current_game;
|
||||
unsigned int m_target_buffer_size;
|
||||
|
||||
std::map<sf::SocketTCP, Client> m_players;
|
||||
|
||||
struct
|
||||
{
|
||||
std::recursive_mutex game;
|
||||
// lock order
|
||||
std::recursive_mutex players, send;
|
||||
} m_crit;
|
||||
|
||||
std::string m_selected_game;
|
||||
|
||||
sf::SocketTCP m_socket;
|
||||
std::thread m_thread;
|
||||
sf::Selector<sf::SocketTCP> m_selector;
|
||||
|
||||
#ifdef USE_UPNP
|
||||
static void mapPortThread(const u16 port);
|
||||
static void unmapPortThread();
|
||||
|
||||
static bool initUPnP();
|
||||
static bool UPnPMapPort(const std::string& addr, const u16 port);
|
||||
static bool UPnPUnmapPort(const u16 port);
|
||||
|
||||
static struct UPNPUrls m_upnp_urls;
|
||||
static struct IGDdatas m_upnp_data;
|
||||
static u16 m_upnp_mapped;
|
||||
static bool m_upnp_inited;
|
||||
static bool m_upnp_error;
|
||||
static std::thread m_upnp_thread;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
|
@ -6,10 +6,12 @@
|
|||
#include <IniFile.h>
|
||||
|
||||
#include "WxUtils.h"
|
||||
#include "NetPlay.h"
|
||||
#include "NetPlayClient.h"
|
||||
#include "NetPlayServer.h"
|
||||
#include "NetWindow.h"
|
||||
#include "Frame.h"
|
||||
#include "Core.h"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
@ -20,7 +22,8 @@ BEGIN_EVENT_TABLE(NetPlayDiag, wxFrame)
|
|||
EVT_COMMAND(wxID_ANY, wxEVT_THREAD, NetPlayDiag::OnThread)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
static NetPlay* netplay_ptr = NULL;
|
||||
static NetPlayServer* netplay_server = NULL;
|
||||
static NetPlayClient* netplay_client = NULL;
|
||||
extern CFrame* main_frame;
|
||||
NetPlayDiag *NetPlayDiag::npd = NULL;
|
||||
|
||||
|
@ -200,6 +203,28 @@ NetPlaySetupDiag::~NetPlaySetupDiag()
|
|||
main_frame->g_NetPlaySetupDiag = NULL;
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::MakeNetPlayDiag(int port, const std::string &game, bool is_hosting)
|
||||
{
|
||||
NetPlayDiag *&npd = NetPlayDiag::GetInstance();
|
||||
std::string ip;
|
||||
npd = new NetPlayDiag(m_parent, m_game_list, game, is_hosting);
|
||||
if (is_hosting)
|
||||
ip = "127.0.0.1";
|
||||
else
|
||||
ip = WxStrToStr(m_connect_ip_text->GetValue());
|
||||
|
||||
netplay_client = new NetPlayClient(ip, (u16)port, npd, WxStrToStr(m_nickname_text->GetValue()));
|
||||
if (netplay_client->is_connected)
|
||||
{
|
||||
npd->Show();
|
||||
Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
npd->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::OnHost(wxCommandEvent&)
|
||||
{
|
||||
NetPlayDiag *&npd = NetPlayDiag::GetInstance();
|
||||
|
@ -217,25 +242,19 @@ void NetPlaySetupDiag::OnHost(wxCommandEvent&)
|
|||
|
||||
std::string game(WxStrToStr(m_game_lbox->GetStringSelection()));
|
||||
|
||||
npd = new NetPlayDiag(m_parent, m_game_list, game, true);
|
||||
unsigned long port = 0;
|
||||
m_host_port_text->GetValue().ToULong(&port);
|
||||
netplay_ptr = new NetPlayServer(u16(port), WxStrToStr(m_nickname_text->GetValue()), npd);
|
||||
netplay_ptr->ChangeGame(game);
|
||||
if (netplay_ptr->is_connected)
|
||||
netplay_server = new NetPlayServer(u16(port));
|
||||
netplay_server->ChangeGame(game);
|
||||
if (netplay_server->is_connected)
|
||||
{
|
||||
#ifdef USE_UPNP
|
||||
if(m_upnp_chk->GetValue())
|
||||
((NetPlayServer*)netplay_ptr)->TryPortmapping(port);
|
||||
netplay_server->TryPortmapping(port);
|
||||
#endif
|
||||
npd->Show();
|
||||
Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlertT("Failed to Listen!!");
|
||||
npd->Destroy();
|
||||
}
|
||||
|
||||
MakeNetPlayDiag(port, game, true);
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::OnJoin(wxCommandEvent&)
|
||||
|
@ -247,20 +266,9 @@ void NetPlaySetupDiag::OnJoin(wxCommandEvent&)
|
|||
return;
|
||||
}
|
||||
|
||||
npd = new NetPlayDiag(m_parent, m_game_list, "");
|
||||
unsigned long port = 0;
|
||||
m_connect_port_text->GetValue().ToULong(&port);
|
||||
netplay_ptr = new NetPlayClient(WxStrToStr(m_connect_ip_text->GetValue())
|
||||
, (u16)port, npd, WxStrToStr(m_nickname_text->GetValue()));
|
||||
if (netplay_ptr->is_connected)
|
||||
{
|
||||
npd->Show();
|
||||
Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
npd->Destroy();
|
||||
}
|
||||
MakeNetPlayDiag(port, "", false);
|
||||
}
|
||||
|
||||
void NetPlaySetupDiag::OnQuit(wxCommandEvent&)
|
||||
|
@ -344,7 +352,6 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game
|
|||
}
|
||||
|
||||
m_memcard_write = new wxCheckBox(panel, wxID_ANY, _("Write memcards (GC)"));
|
||||
m_memcard_write->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &NetPlayDiag::OnMemcardWriteCheck, this);
|
||||
bottom_szr->Add(m_memcard_write, 0, wxCENTER);
|
||||
|
||||
bottom_szr->AddStretchSpacer(1);
|
||||
|
@ -366,10 +373,15 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game
|
|||
|
||||
NetPlayDiag::~NetPlayDiag()
|
||||
{
|
||||
if (netplay_ptr)
|
||||
if (netplay_client)
|
||||
{
|
||||
delete netplay_ptr;
|
||||
netplay_ptr = NULL;
|
||||
delete netplay_client;
|
||||
netplay_client = NULL;
|
||||
}
|
||||
if (netplay_server)
|
||||
{
|
||||
delete netplay_server;
|
||||
netplay_server = NULL;
|
||||
}
|
||||
npd = NULL;
|
||||
}
|
||||
|
@ -380,37 +392,50 @@ void NetPlayDiag::OnChat(wxCommandEvent&)
|
|||
|
||||
if (s.Length())
|
||||
{
|
||||
netplay_ptr->SendChatMessage(WxStrToStr(s));
|
||||
netplay_client->SendChatMessage(WxStrToStr(s));
|
||||
m_chat_text->AppendText(s.Prepend(wxT(" >> ")).Append(wxT('\n')));
|
||||
m_chat_msg_text->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnStart(wxCommandEvent&)
|
||||
void NetPlayDiag::GetNetSettings(NetSettings &settings)
|
||||
{
|
||||
SConfig &instance = SConfig::GetInstance();
|
||||
settings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE;
|
||||
settings.m_DSPEnableJIT = instance.m_EnableJIT;
|
||||
settings.m_WriteToMemcard = m_memcard_write->GetValue();
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
settings.m_Controllers[i] = SConfig::GetInstance().m_SIDevice[i];
|
||||
}
|
||||
|
||||
const std::string& NetPlayDiag::FindGame()
|
||||
{
|
||||
// find path for selected game, sloppy..
|
||||
for (u32 i = 0 ; auto game = m_game_list->GetISO(i); ++i)
|
||||
{
|
||||
if (m_selected_game == BuildGameName(*game))
|
||||
{
|
||||
netplay_ptr->StartGame(game->GetFileName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
return game->GetFileName();
|
||||
|
||||
PanicAlertT("Game not found!");
|
||||
return "";
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnStart(wxCommandEvent&)
|
||||
{
|
||||
NetSettings settings;
|
||||
GetNetSettings(settings);
|
||||
netplay_server->SetNetSettings(settings);
|
||||
netplay_server->StartGame(FindGame());
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnStop(wxCommandEvent&)
|
||||
{
|
||||
netplay_ptr->StopGame();
|
||||
netplay_server->StopGame();
|
||||
}
|
||||
|
||||
void NetPlayDiag::BootGame(const std::string& filename)
|
||||
{
|
||||
main_frame->BootGame(filename);
|
||||
|
||||
Core::g_CoreStartupParameter.bEnableMemcardSaving = m_memcard_write->GetValue();
|
||||
}
|
||||
|
||||
void NetPlayDiag::StopGame()
|
||||
|
@ -452,19 +477,14 @@ void NetPlayDiag::OnMsgStopGame()
|
|||
GetEventHandler()->AddPendingEvent(evt);
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnMemcardWriteCheck(wxCommandEvent &event)
|
||||
{
|
||||
netplay_ptr->SetMemcardWriteEnabled(m_memcard_write->GetValue());
|
||||
}
|
||||
|
||||
void NetPlayDiag::OnAdjustBuffer(wxCommandEvent& event)
|
||||
{
|
||||
const int val = ((wxSpinCtrl*)event.GetEventObject())->GetValue();
|
||||
((NetPlayServer*)netplay_ptr)->AdjustPadBufferSize(val);
|
||||
netplay_server->AdjustPadBufferSize(val);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "< Pad Buffer: " << val << " >";
|
||||
netplay_ptr->SendChatMessage(ss.str());
|
||||
netplay_client->SendChatMessage(ss.str());
|
||||
m_chat_text->AppendText(StrToWxStr(ss.str()).Append(wxT('\n')));
|
||||
}
|
||||
|
||||
|
@ -479,7 +499,7 @@ void NetPlayDiag::OnThread(wxCommandEvent& event)
|
|||
// player list
|
||||
m_playerids.clear();
|
||||
std::string tmps;
|
||||
netplay_ptr->GetPlayerList(tmps, m_playerids);
|
||||
netplay_client->GetPlayerList(tmps, m_playerids);
|
||||
|
||||
const int selection = m_player_lbox->GetSelection();
|
||||
|
||||
|
@ -502,15 +522,13 @@ void NetPlayDiag::OnThread(wxCommandEvent& event)
|
|||
case NP_GUI_EVT_START_GAME :
|
||||
// client start game :/
|
||||
{
|
||||
wxCommandEvent evt;
|
||||
OnStart(evt);
|
||||
netplay_client->StartGame(FindGame());
|
||||
}
|
||||
break;
|
||||
case NP_GUI_EVT_STOP_GAME :
|
||||
// client stop game
|
||||
{
|
||||
wxCommandEvent evt;
|
||||
OnStop(evt);
|
||||
netplay_client->StopGame();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -534,7 +552,7 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent&)
|
|||
if (game_name.length())
|
||||
{
|
||||
m_selected_game = WxStrToStr(game_name);
|
||||
netplay_ptr->ChangeGame(m_selected_game);
|
||||
netplay_server->ChangeGame(m_selected_game);
|
||||
m_game_btn->SetLabel(game_name.Prepend(_(" Game : ")));
|
||||
}
|
||||
}
|
||||
|
@ -549,13 +567,13 @@ void NetPlayDiag::OnConfigPads(wxCommandEvent&)
|
|||
return;
|
||||
pid = m_playerids.at(pid);
|
||||
|
||||
if (false == ((NetPlayServer*)netplay_ptr)->GetPadMapping(pid, mapping))
|
||||
if (false == netplay_server->GetPadMapping(pid, mapping))
|
||||
return;
|
||||
|
||||
PadMapDiag pmd(this, mapping);
|
||||
pmd.ShowModal();
|
||||
|
||||
if (false == ((NetPlayServer*)netplay_ptr)->SetPadMapping(pid, mapping))
|
||||
if (false == netplay_server->SetPadMapping(pid, mapping))
|
||||
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)");
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "FifoQueue.h"
|
||||
|
||||
#include "NetPlay.h"
|
||||
#include "NetPlayClient.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -42,6 +42,8 @@ private:
|
|||
void OnHost(wxCommandEvent& event);
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
|
||||
void MakeNetPlayDiag(int port, const std::string &game, bool is_hosting);
|
||||
|
||||
wxTextCtrl *m_nickname_text,
|
||||
*m_host_port_text,
|
||||
*m_connect_port_text,
|
||||
|
@ -85,11 +87,12 @@ private:
|
|||
|
||||
void OnChat(wxCommandEvent& event);
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
void OnMemcardWriteCheck(wxCommandEvent& event);
|
||||
void OnThread(wxCommandEvent& event);
|
||||
void OnChangeGame(wxCommandEvent& event);
|
||||
void OnAdjustBuffer(wxCommandEvent& event);
|
||||
void OnConfigPads(wxCommandEvent& event);
|
||||
void GetNetSettings(NetSettings &settings);
|
||||
const std::string& FindGame();
|
||||
|
||||
wxListBox* m_player_lbox;
|
||||
wxTextCtrl* m_chat_text;
|
||||
|
|
Loading…
Reference in New Issue