dolphin/Source/Core/DolphinWX/Src/NetPlay.h

262 lines
5.6 KiB
C
Raw Normal View History

#ifndef _NETPLAY_H
#define _NETPLAY_H
#include "Common.h"
#include "CommonTypes.h"
//#define WIN32_LEAN_AND_MEAN
#include "Thread.h"
#include "Timer.h"
// hax, i hope something like this isn't needed on non-windows
#define _WINSOCK2API_
#include <SFML/Network.hpp>
#include "pluginspecs_pad.h"
#include "svnrev.h"
//#include <wx/wx.h>
#include <map>
#include <queue>
#include <sstream>
class NetPlayDiag;
class NetPad
{
public:
NetPad();
NetPad(const SPADStatus* const);
u32 nHi;
u32 nLo;
};
class NetWiimote
{
public:
NetWiimote& operator=(const NetWiimote&);
NetWiimote(const u32 _size) : size(_size), data(new u8[size]) {}
const u32 size;
u8* const data;
};
#define NETPLAY_VERSION "Dolphin NetPlay 2.2"
#ifdef _M_X64
#define NP_ARCH "x64"
#else
#define NP_ARCH "x86"
#endif
#ifdef _WIN32
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" W"NP_ARCH
#elif __APPLE__
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" M"NP_ARCH
#else
#define NETPLAY_DOLPHIN_VER SVN_REV_STR" L"NP_ARCH
#endif
// messages
#define NP_MSG_PLAYER_JOIN 0x10
#define NP_MSG_PLAYER_LEAVE 0x11
#define NP_MSG_CHAT_MESSAGE 0x30
#define NP_MSG_PAD_DATA 0x60
#define NP_MSG_PAD_MAPPING 0x61
#define NP_MSG_PAD_BUFFER 0x62
#define NP_MSG_WIIMOTE_DATA 0x70
#define NP_MSG_WIIMOTE_MAPPING 0x71 // just using pad mapping for now
#define NP_MSG_START_GAME 0xA0
#define NP_MSG_CHANGE_GAME 0xA1
#define NP_MSG_STOP_GAME 0xA2
#define NP_MSG_DISABLE_GAME 0xA3
#define NP_MSG_READY 0xD0
#define NP_MSG_NOT_READY 0xD1
#define NP_MSG_PING 0xE0
#define NP_MSG_PONG 0xE1
// end messages
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
};
THREAD_RETURN NetPlayThreadFunc(void* arg);
// something like this should be in Common stuff
class CritLocker
{
public:
//CritLocker(const CritLocker&);
CritLocker& operator=(const CritLocker&);
CritLocker(Common::CriticalSection& crit) : m_crit(crit) { m_crit.Enter(); }
~CritLocker() { m_crit.Leave(); }
private:
Common::CriticalSection& m_crit;
};
class NetPlay
{
public:
NetPlay();
virtual ~NetPlay();
virtual void Entry() = 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) = 0;
virtual void SendChatMessage(const std::string& msg) = 0;
virtual bool StartGame(const std::string &path);
virtual bool StopGame();
//void PushPadStates(unsigned int count);
u8 GetPadNum(u8 numPAD);
protected:
//NetPlay(Common::ThreadFunc entry, void* arg) : m_thread(entry, arg) {}
//void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues);
void ClearBuffers();
void UpdateGUI();
void AppendChatGUI(const std::string& msg);
virtual void SendPadState(const PadMapping local_nb, const NetPad& np) = 0;
struct
{
Common::CriticalSection game;
// lock order
Common::CriticalSection players, buffer, send;
} m_crit;
class Player
{
public:
Player();
std::string ToString() const;
PlayerId pid;
std::string name;
PadMapping pad_map[4];
std::string revision;
};
//LockingQueue<NetPad> m_pad_buffer[4];
std::queue<NetPad> m_pad_buffer[4];
std::map<FrameNum, NetWiimote> m_wiimote_buffer[4];
FrameNum m_wiimote_update_frame;
NetPlayDiag* m_dialog;
sf::SocketTCP m_socket;
Common::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_on_game;
private:
};
void NetPlay_Enable(NetPlay* const np);
void NetPlay_Disable();
class NetPlayServer : public NetPlay
{
public:
void Entry();
NetPlayServer(const u16 port, const std::string& name, NetPlayDiag* const npd = NULL, const std::string& game = "");
~NetPlayServer();
void GetPlayerList(std::string& 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();
u64 CalculateMinimumBufferTime();
void AdjustPadBufferSize(unsigned int size);
private:
class Client : public Player
{
public:
Client() : ping(0), on_game(0) {}
sf::SocketTCP socket;
u64 ping;
u32 on_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);
std::map<sf::SocketTCP, Client> m_players;
Common::Timer m_ping_timer;
u32 m_ping_key;
bool m_update_pings;
};
class NetPlayClient : public NetPlay
{
public:
void Entry();
NetPlayClient(const std::string& address, const u16 port, const std::string& name, NetPlayDiag* const npd = NULL);
~NetPlayClient();
void GetPlayerList(std::string& 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