NetPlay: Allow controller selection for host & clients + Spectator mode
This commit is contained in:
parent
361f4b8025
commit
3e798af865
27 changed files with 594 additions and 55 deletions
|
@ -12,8 +12,10 @@ public:
|
|||
uint8_t* AvatarData;
|
||||
uint32_t AvatarSize;
|
||||
|
||||
ClientConnectionData(string host, uint16_t port, string playerName, uint8_t* avatarData, uint32_t avatarSize) :
|
||||
Host(host), Port(port), PlayerName(playerName), AvatarSize(avatarSize)
|
||||
bool Spectator;
|
||||
|
||||
ClientConnectionData(string host, uint16_t port, string playerName, uint8_t* avatarData, uint32_t avatarSize, bool spectator) :
|
||||
Host(host), Port(port), PlayerName(playerName), AvatarSize(avatarSize), Spectator(spectator)
|
||||
{
|
||||
if(avatarSize > 0) {
|
||||
AvatarData = new uint8_t[avatarSize];
|
||||
|
|
|
@ -407,9 +407,11 @@
|
|||
<ClInclude Include="MMC3_52.h" />
|
||||
<ClInclude Include="MMC3_ChrRam.h" />
|
||||
<ClInclude Include="ModChannel.h" />
|
||||
<ClInclude Include="PlayerListMessage.h" />
|
||||
<ClInclude Include="RomData.h" />
|
||||
<ClInclude Include="NtdecTc112.h" />
|
||||
<ClInclude Include="Rambo1.h" />
|
||||
<ClInclude Include="SelectControllerMessage.h" />
|
||||
<ClInclude Include="SoundMixer.h" />
|
||||
<ClInclude Include="Namco108.h" />
|
||||
<ClInclude Include="Namco108_154.h" />
|
||||
|
|
|
@ -539,6 +539,12 @@
|
|||
<ClInclude Include="BaseControlDevice.h">
|
||||
<Filter>Nes\Controllers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PlayerListMessage.h">
|
||||
<Filter>NetPlay\Messages</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SelectControllerMessage.h">
|
||||
<Filter>NetPlay\Messages</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
|
|
@ -85,5 +85,34 @@ void GameClient::ProcessNotification(ConsoleNotificationType type, void* paramet
|
|||
|
||||
uint8_t GameClient::GetControllerState(uint8_t port)
|
||||
{
|
||||
return Instance->_connection->GetControllerState(port);
|
||||
if(Instance && Instance->_connection) {
|
||||
return Instance->_connection->GetControllerState(port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GameClient::SelectController(uint8_t port)
|
||||
{
|
||||
if(Instance && Instance->_connection) {
|
||||
Instance->_connection->SelectController(port);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GameClient::GetAvailableControllers()
|
||||
{
|
||||
if(Instance && Instance->_connection) {
|
||||
return Instance->_connection->GetAvailableControllers();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t GameClient::GetControllerPort()
|
||||
{
|
||||
if(Instance && Instance->_connection) {
|
||||
return Instance->_connection->GetControllerPort();
|
||||
}
|
||||
|
||||
return GameConnection::SpectatorPort;
|
||||
}
|
|
@ -29,6 +29,10 @@ public:
|
|||
static void Connect(shared_ptr<ClientConnectionData> connectionData);
|
||||
static void Disconnect();
|
||||
|
||||
static void SelectController(uint8_t port);
|
||||
static uint8_t GetControllerPort();
|
||||
static uint8_t GetAvailableControllers();
|
||||
|
||||
static uint8_t GetControllerState(uint8_t port);
|
||||
|
||||
void ProcessNotification(ConsoleNotificationType type, void* parameter);
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "ControlManager.h"
|
||||
#include "ClientConnectionData.h"
|
||||
#include "StandardController.h"
|
||||
#include "SelectControllerMessage.h"
|
||||
#include "PlayerListMessage.h"
|
||||
|
||||
GameClientConnection::GameClientConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData) : GameConnection(socket, connectionData)
|
||||
{
|
||||
|
@ -28,7 +30,13 @@ GameClientConnection::~GameClientConnection()
|
|||
|
||||
void GameClientConnection::SendHandshake()
|
||||
{
|
||||
HandShakeMessage message(_connectionData->PlayerName, _connectionData->AvatarData, _connectionData->AvatarSize);
|
||||
HandShakeMessage message(_connectionData->PlayerName, _connectionData->AvatarData, _connectionData->AvatarSize, _connectionData->Spectator);
|
||||
SendNetMessage(message);
|
||||
}
|
||||
|
||||
void GameClientConnection::SendControllerSelection(uint8_t port)
|
||||
{
|
||||
SelectControllerMessage message(port);
|
||||
SendNetMessage(message);
|
||||
}
|
||||
|
||||
|
@ -57,21 +65,31 @@ void GameClientConnection::ProcessMessage(NetMessage* message)
|
|||
case ControllerType::Zapper: _controlDevice = ControlManager::GetControlDevice(_controllerPort); break;
|
||||
}
|
||||
Console::Resume();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case MessageType::MovieData:
|
||||
if(_gameLoaded) {
|
||||
PushControllerState(((MovieDataMessage*)message)->GetPortNumber(), ((MovieDataMessage*)message)->GetInputState());
|
||||
}
|
||||
break;
|
||||
|
||||
case MessageType::PlayerList:
|
||||
_playerList = ((PlayerListMessage*)message)->GetPlayerList();
|
||||
break;
|
||||
|
||||
case MessageType::GameInformation:
|
||||
DisableControllers();
|
||||
Console::Pause();
|
||||
gameInfo = (GameInformationMessage*)message;
|
||||
if(gameInfo->GetPort() != _controllerPort) {
|
||||
_controllerPort = gameInfo->GetPort();
|
||||
MessageManager::DisplayMessage("Net Play", string("Connected as player ") + std::to_string(_controllerPort + 1));
|
||||
|
||||
if(_controllerPort == GameConnection::SpectatorPort) {
|
||||
MessageManager::DisplayMessage("Net Play", "Connected as spectator");
|
||||
} else {
|
||||
MessageManager::DisplayMessage("Net Play", string("Connected as player ") + std::to_string(_controllerPort + 1));
|
||||
}
|
||||
}
|
||||
|
||||
ClearInputData();
|
||||
|
@ -160,4 +178,25 @@ void GameClientConnection::SendInput()
|
|||
_lastInputSent = inputState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameClientConnection::SelectController(uint8_t port)
|
||||
{
|
||||
SendControllerSelection(port);
|
||||
}
|
||||
|
||||
uint8_t GameClientConnection::GetAvailableControllers()
|
||||
{
|
||||
uint8_t availablePorts = 0x0F;
|
||||
for(PlayerInfo &playerInfo : _playerList) {
|
||||
if(playerInfo.ControllerPort < 4) {
|
||||
availablePorts &= ~(1 << playerInfo.ControllerPort);
|
||||
}
|
||||
}
|
||||
return availablePorts;
|
||||
}
|
||||
|
||||
uint8_t GameClientConnection::GetControllerPort()
|
||||
{
|
||||
return _controllerPort;
|
||||
}
|
|
@ -19,13 +19,16 @@ private:
|
|||
atomic<bool> _enableControllers = false;
|
||||
atomic<uint32_t> _minimumQueueSize = 3;
|
||||
|
||||
vector<PlayerInfo> _playerList;
|
||||
|
||||
shared_ptr<BaseControlDevice> _controlDevice;
|
||||
uint32_t _lastInputSent = 0x00;
|
||||
bool _gameLoaded = false;
|
||||
uint8_t _controllerPort = 255;
|
||||
uint8_t _controllerPort = GameConnection::SpectatorPort;
|
||||
|
||||
private:
|
||||
void SendHandshake();
|
||||
void SendControllerSelection(uint8_t port);
|
||||
void ClearInputData();
|
||||
void PushControllerState(uint8_t port, uint8_t state);
|
||||
void DisableControllers();
|
||||
|
@ -39,4 +42,8 @@ public:
|
|||
|
||||
uint8_t GetControllerState(uint8_t port);
|
||||
void SendInput();
|
||||
|
||||
void SelectController(uint8_t port);
|
||||
uint8_t GetAvailableControllers();
|
||||
uint8_t GetControllerPort();
|
||||
};
|
|
@ -5,6 +5,8 @@
|
|||
#include "MovieDataMessage.h"
|
||||
#include "GameInformationMessage.h"
|
||||
#include "SaveStateMessage.h"
|
||||
#include "PlayerListMessage.h"
|
||||
#include "SelectControllerMessage.h"
|
||||
#include "ClientConnectionData.h"
|
||||
|
||||
GameConnection::GameConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData)
|
||||
|
@ -54,6 +56,8 @@ NetMessage* GameConnection::ReadMessage()
|
|||
case MessageType::InputData: return new InputDataMessage(_messageBuffer, messageLength);
|
||||
case MessageType::MovieData: return new MovieDataMessage(_messageBuffer, messageLength);
|
||||
case MessageType::GameInformation: return new GameInformationMessage(_messageBuffer, messageLength);
|
||||
case MessageType::PlayerList: return new PlayerListMessage(_messageBuffer, messageLength);
|
||||
case MessageType::SelectController: return new SelectControllerMessage(_messageBuffer, messageLength);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
|
|
@ -6,6 +6,13 @@ class Socket;
|
|||
class NetMessage;
|
||||
class ClientConnectionData;
|
||||
|
||||
struct PlayerInfo
|
||||
{
|
||||
string Name;
|
||||
uint8_t ControllerPort;
|
||||
bool IsHost;
|
||||
};
|
||||
|
||||
class GameConnection
|
||||
{
|
||||
protected:
|
||||
|
@ -24,14 +31,11 @@ private:
|
|||
|
||||
virtual void ProcessMessage(NetMessage* message) = 0;
|
||||
|
||||
protected:
|
||||
void SendNetMessage(NetMessage &message);
|
||||
|
||||
public:
|
||||
static const uint8_t SpectatorPort = 0xFF;
|
||||
GameConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData);
|
||||
|
||||
bool ConnectionError();
|
||||
|
||||
void ProcessMessages();
|
||||
|
||||
void SendNetMessage(NetMessage &message);
|
||||
};
|
|
@ -6,11 +6,15 @@ using std::thread;
|
|||
#include "GameServer.h"
|
||||
#include "Console.h"
|
||||
#include "../Utilities/Socket.h"
|
||||
#include "PlayerListMessage.h"
|
||||
|
||||
unique_ptr<GameServer> GameServer::Instance;
|
||||
|
||||
GameServer::GameServer()
|
||||
GameServer::GameServer(uint16_t listenPort, string hostPlayerName)
|
||||
{
|
||||
_port = listenPort;
|
||||
_hostPlayerName = hostPlayerName;
|
||||
_hostControllerPort = 0;
|
||||
ControlManager::RegisterBroadcaster(this);
|
||||
}
|
||||
|
||||
|
@ -29,7 +33,7 @@ void GameServer::AcceptConnections()
|
|||
while(true) {
|
||||
shared_ptr<Socket> socket = _listener->Accept();
|
||||
if(!socket->ConnectionError()) {
|
||||
_openConnections.push_back(shared_ptr<GameServerConnection>(new GameServerConnection(socket, 1)));
|
||||
_openConnections.push_back(shared_ptr<GameServerConnection>(new GameServerConnection(socket)));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -53,6 +57,15 @@ void GameServer::UpdateConnections()
|
|||
}
|
||||
}
|
||||
|
||||
list<shared_ptr<GameServerConnection>> GameServer::GetConnectionList()
|
||||
{
|
||||
if(GameServer::Started()) {
|
||||
return Instance->_openConnections;
|
||||
} else {
|
||||
return list<shared_ptr<GameServerConnection>>();
|
||||
}
|
||||
}
|
||||
|
||||
void GameServer::Exec()
|
||||
{
|
||||
_listener.reset(new Socket());
|
||||
|
@ -77,10 +90,9 @@ void GameServer::Stop()
|
|||
MessageManager::DisplayMessage("Net Play", "Server stopped");
|
||||
}
|
||||
|
||||
void GameServer::StartServer(uint16_t port)
|
||||
void GameServer::StartServer(uint16_t port, string hostPlayerName)
|
||||
{
|
||||
Instance.reset(new GameServer());
|
||||
Instance->_port = port;
|
||||
Instance.reset(new GameServer(port, hostPlayerName));
|
||||
Instance->_serverThread.reset(new thread(&GameServer::Exec, Instance.get()));
|
||||
}
|
||||
|
||||
|
@ -108,4 +120,75 @@ void GameServer::BroadcastInput(uint8_t inputData, uint8_t port)
|
|||
connection->SendMovieData(inputData, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string GameServer::GetHostPlayerName()
|
||||
{
|
||||
if(GameServer::Started()) {
|
||||
return Instance->_hostPlayerName;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
uint8_t GameServer::GetHostControllerPort()
|
||||
{
|
||||
if(GameServer::Started()) {
|
||||
return Instance->_hostControllerPort;
|
||||
}
|
||||
return GameConnection::SpectatorPort;
|
||||
}
|
||||
|
||||
void GameServer::SetHostControllerPort(uint8_t port)
|
||||
{
|
||||
if(GameServer::Started()) {
|
||||
Console::Pause();
|
||||
if(port == GameConnection::SpectatorPort || GetAvailableControllers() & (1 << port)) {
|
||||
//Port is available
|
||||
Instance->_hostControllerPort = port;
|
||||
SendPlayerList();
|
||||
}
|
||||
Console::Resume();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GameServer::GetAvailableControllers()
|
||||
{
|
||||
uint8_t availablePorts = 0x0F;
|
||||
for(PlayerInfo &playerInfo : GetPlayerList()) {
|
||||
if(playerInfo.ControllerPort < 4) {
|
||||
availablePorts &= ~(1 << playerInfo.ControllerPort);
|
||||
}
|
||||
}
|
||||
return availablePorts;
|
||||
}
|
||||
|
||||
vector<PlayerInfo> GameServer::GetPlayerList()
|
||||
{
|
||||
vector<PlayerInfo> playerList;
|
||||
|
||||
PlayerInfo playerInfo;
|
||||
playerInfo.Name = GetHostPlayerName();
|
||||
playerInfo.ControllerPort = GetHostControllerPort();
|
||||
playerInfo.IsHost = true;
|
||||
playerList.push_back(playerInfo);
|
||||
|
||||
for(shared_ptr<GameServerConnection> &connection : GetConnectionList()) {
|
||||
playerInfo.Name = connection->GetPlayerName();
|
||||
playerInfo.ControllerPort = connection->GetControllerPort();
|
||||
playerInfo.IsHost = false;
|
||||
playerList.push_back(playerInfo);
|
||||
}
|
||||
|
||||
return playerList;
|
||||
}
|
||||
|
||||
void GameServer::SendPlayerList()
|
||||
{
|
||||
vector<PlayerInfo> playerList = GetPlayerList();
|
||||
|
||||
for(shared_ptr<GameServerConnection> &connection : GetConnectionList()) {
|
||||
//Send player list update to all connections
|
||||
PlayerListMessage message(playerList);
|
||||
connection->SendNetMessage(message);
|
||||
}
|
||||
}
|
|
@ -18,6 +18,9 @@ private:
|
|||
list<shared_ptr<GameServerConnection>> _openConnections;
|
||||
bool _initialized = false;
|
||||
|
||||
string _hostPlayerName;
|
||||
uint8_t _hostControllerPort;
|
||||
|
||||
void AcceptConnections();
|
||||
void UpdateConnections();
|
||||
|
||||
|
@ -25,12 +28,21 @@ private:
|
|||
void Stop();
|
||||
|
||||
public:
|
||||
GameServer();
|
||||
GameServer(uint16_t port, string hostPlayerName);
|
||||
~GameServer();
|
||||
|
||||
static void StartServer(uint16_t port);
|
||||
static void StartServer(uint16_t port, string hostPlayerName);
|
||||
static void StopServer();
|
||||
static bool Started();
|
||||
|
||||
static string GetHostPlayerName();
|
||||
static uint8_t GetHostControllerPort();
|
||||
static void SetHostControllerPort(uint8_t port);
|
||||
static uint8_t GetAvailableControllers();
|
||||
static vector<PlayerInfo> GetPlayerList();
|
||||
static void SendPlayerList();
|
||||
|
||||
static list<shared_ptr<GameServerConnection>> GetConnectionList();
|
||||
|
||||
virtual void BroadcastInput(uint8_t inputData, uint8_t port);
|
||||
};
|
|
@ -11,13 +11,16 @@
|
|||
#include "ClientConnectionData.h"
|
||||
#include "EmulationSettings.h"
|
||||
#include "StandardController.h"
|
||||
#include "SelectControllerMessage.h"
|
||||
#include "PlayerListMessage.h"
|
||||
#include "GameServer.h"
|
||||
|
||||
GameServerConnection* GameServerConnection::_netPlayDevices[4] = { nullptr,nullptr,nullptr, nullptr };
|
||||
GameServerConnection* GameServerConnection::_netPlayDevices[4] = { nullptr,nullptr,nullptr,nullptr };
|
||||
|
||||
GameServerConnection::GameServerConnection(shared_ptr<Socket> socket, int controllerPort) : GameConnection(socket, nullptr)
|
||||
GameServerConnection::GameServerConnection(shared_ptr<Socket> socket) : GameConnection(socket, nullptr)
|
||||
{
|
||||
//Server-side connection
|
||||
_controllerPort = controllerPort;
|
||||
_controllerPort = GameConnection::SpectatorPort;
|
||||
MessageManager::RegisterNotificationListener(this);
|
||||
}
|
||||
|
||||
|
@ -72,34 +75,75 @@ uint32_t GameServerConnection::GetState()
|
|||
return stateData;
|
||||
}
|
||||
|
||||
void GameServerConnection::ProcessHandshakeResponse(HandShakeMessage* message)
|
||||
{
|
||||
//Send the game's current state to the client and register the controller
|
||||
if(message->IsValid()) {
|
||||
Console::Pause();
|
||||
|
||||
_controllerPort = message->IsSpectator() ? GameConnection::SpectatorPort : GetFirstFreeControllerPort();
|
||||
_connectionData.reset(new ClientConnectionData("", 0, message->GetPlayerName(), message->GetAvatarData(), message->GetAvatarSize(), false));
|
||||
|
||||
string playerPortMessage = _controllerPort == GameConnection::SpectatorPort ? "Spectator" : "Player " + std::to_string(_controllerPort + 1);
|
||||
|
||||
MessageManager::DisplayToast("Net Play", _connectionData->PlayerName + " (" + playerPortMessage + ") connected.", _connectionData->AvatarData, _connectionData->AvatarSize);
|
||||
|
||||
if(Console::GetROMPath().size() > 0) {
|
||||
SendGameInformation();
|
||||
}
|
||||
|
||||
_handshakeCompleted = true;
|
||||
RegisterNetPlayDevice(this, _controllerPort);
|
||||
GameServer::SendPlayerList();
|
||||
Console::Resume();
|
||||
}
|
||||
}
|
||||
|
||||
void GameServerConnection::ProcessMessage(NetMessage* message)
|
||||
{
|
||||
switch(message->GetType()) {
|
||||
case MessageType::HandShake:
|
||||
//Send the game's current state to the client and register the controller
|
||||
if(((HandShakeMessage*)message)->IsValid()) {
|
||||
Console::Pause();
|
||||
_connectionData.reset(new ClientConnectionData("", 0, ((HandShakeMessage*)message)->GetPlayerName(), ((HandShakeMessage*)message)->GetAvatarData(), ((HandShakeMessage*)message)->GetAvatarSize()));
|
||||
|
||||
MessageManager::DisplayToast("Net Play", _connectionData->PlayerName + " (Player " + std::to_string(_controllerPort + 1) + ") connected.", _connectionData->AvatarData, _connectionData->AvatarSize);
|
||||
|
||||
if(Console::GetROMPath().size() > 0) {
|
||||
SendGameInformation();
|
||||
}
|
||||
|
||||
_handshakeCompleted = true;
|
||||
RegisterNetPlayDevice(this, _controllerPort);
|
||||
Console::Resume();
|
||||
}
|
||||
ProcessHandshakeResponse((HandShakeMessage*)message);
|
||||
break;
|
||||
|
||||
case MessageType::InputData:
|
||||
PushState(((InputDataMessage*)message)->GetInputState());
|
||||
break;
|
||||
|
||||
case MessageType::SelectController:
|
||||
SelectControllerPort(((SelectControllerMessage*)message)->GetPortNumber());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GameServerConnection::SelectControllerPort(uint8_t port)
|
||||
{
|
||||
Console::Pause();
|
||||
if(port == GameConnection::SpectatorPort) {
|
||||
//Client wants to be a spectator, make sure we are not using any controller
|
||||
UnregisterNetPlayDevice(this);
|
||||
_controllerPort = port;
|
||||
} else {
|
||||
GameServerConnection* netPlayDevice = GetNetPlayDevice(port);
|
||||
if(netPlayDevice == this) {
|
||||
//Nothing to do, we're already this player
|
||||
} else if(netPlayDevice == nullptr) {
|
||||
//This port is free, we can switch
|
||||
UnregisterNetPlayDevice(this);
|
||||
RegisterNetPlayDevice(this, port);
|
||||
_controllerPort = port;
|
||||
} else {
|
||||
//Another player is using this port, we can't use it
|
||||
}
|
||||
}
|
||||
SendGameInformation();
|
||||
GameServer::SendPlayerList();
|
||||
Console::Resume();
|
||||
}
|
||||
|
||||
void GameServerConnection::ProcessNotification(ConsoleNotificationType type, void* parameter)
|
||||
{
|
||||
switch(type) {
|
||||
|
@ -138,4 +182,29 @@ void GameServerConnection::UnregisterNetPlayDevice(GameServerConnection* device)
|
|||
GameServerConnection* GameServerConnection::GetNetPlayDevice(uint8_t port)
|
||||
{
|
||||
return GameServerConnection::_netPlayDevices[port];
|
||||
}
|
||||
|
||||
uint8_t GameServerConnection::GetFirstFreeControllerPort()
|
||||
{
|
||||
uint8_t hostPost = GameServer::GetHostControllerPort();
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(hostPost != i && GameServerConnection::_netPlayDevices[i] == nullptr) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return GameConnection::SpectatorPort;
|
||||
}
|
||||
|
||||
string GameServerConnection::GetPlayerName()
|
||||
{
|
||||
if(_connectionData) {
|
||||
return _connectionData->PlayerName;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GameServerConnection::GetControllerPort()
|
||||
{
|
||||
return _controllerPort;
|
||||
}
|
|
@ -6,29 +6,39 @@
|
|||
#include "IGameBroadcaster.h"
|
||||
#include "INotificationListener.h"
|
||||
|
||||
class HandShakeMessage;
|
||||
|
||||
class GameServerConnection : public GameConnection, public INotificationListener
|
||||
{
|
||||
private:
|
||||
static GameServerConnection* _netPlayDevices[4];
|
||||
|
||||
list<uint32_t> _inputData;
|
||||
int _controllerPort;
|
||||
bool _handshakeCompleted = false;
|
||||
void PushState(uint32_t state);
|
||||
void SendGameInformation();
|
||||
void SelectControllerPort(uint8_t port);
|
||||
|
||||
void ProcessHandshakeResponse(HandShakeMessage* message);
|
||||
|
||||
static void RegisterNetPlayDevice(GameServerConnection* connection, uint8_t port);
|
||||
static void UnregisterNetPlayDevice(GameServerConnection* device);
|
||||
static uint8_t GetFirstFreeControllerPort();
|
||||
|
||||
protected:
|
||||
void ProcessMessage(NetMessage* message);
|
||||
|
||||
public:
|
||||
GameServerConnection(shared_ptr<Socket> socket, int controllerPort);
|
||||
GameServerConnection(shared_ptr<Socket> socket);
|
||||
~GameServerConnection();
|
||||
|
||||
uint32_t GetState();
|
||||
void SendMovieData(uint8_t state, uint8_t port);
|
||||
|
||||
string GetPlayerName();
|
||||
uint8_t GetControllerPort();
|
||||
|
||||
virtual void ProcessNotification(ConsoleNotificationType type, void* parameter);
|
||||
|
||||
static GameServerConnection* GetNetPlayDevice(uint8_t port);
|
||||
|
|
|
@ -11,6 +11,7 @@ private:
|
|||
uint32_t _playerNameLength = 0;
|
||||
void* _avatarData = nullptr;
|
||||
uint32_t _avatarSize = 0;
|
||||
bool _spectator = false;
|
||||
|
||||
protected:
|
||||
virtual void ProtectedStreamState()
|
||||
|
@ -18,16 +19,18 @@ protected:
|
|||
Stream<uint32_t>(_protocolVersion);
|
||||
StreamArray((void**)&_playerName, _playerNameLength);
|
||||
StreamArray(&_avatarData, _avatarSize);
|
||||
Stream<bool>(_spectator);
|
||||
}
|
||||
|
||||
public:
|
||||
HandShakeMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) { }
|
||||
HandShakeMessage(string playerName, uint8_t* avatarData, uint32_t avatarSize) : NetMessage(MessageType::HandShake)
|
||||
HandShakeMessage(string playerName, uint8_t* avatarData, uint32_t avatarSize, bool spectator) : NetMessage(MessageType::HandShake)
|
||||
{
|
||||
_protocolVersion = 1;
|
||||
CopyString(&_playerName, _playerNameLength, playerName);
|
||||
_avatarSize = avatarSize;
|
||||
_avatarData = avatarData;
|
||||
_spectator = spectator;
|
||||
}
|
||||
|
||||
string GetPlayerName()
|
||||
|
@ -49,4 +52,9 @@ public:
|
|||
{
|
||||
return _protocolVersion == CurrentVersion;
|
||||
}
|
||||
|
||||
bool IsSpectator()
|
||||
{
|
||||
return _spectator;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,4 +8,6 @@ enum class MessageType : uint8_t
|
|||
InputData = 2,
|
||||
MovieData = 3,
|
||||
GameInformation = 4,
|
||||
PlayerList = 5,
|
||||
SelectController = 6,
|
||||
};
|
|
@ -28,6 +28,13 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void StreamArray(void* value, uint32_t length)
|
||||
{
|
||||
void* pointer = value;
|
||||
uint32_t len = length;
|
||||
StreamArray(&pointer, len);
|
||||
}
|
||||
|
||||
void StreamArray(void** value, uint32_t &length)
|
||||
{
|
||||
if(_sending) {
|
||||
|
|
63
Core/PlayerListMessage.h
Normal file
63
Core/PlayerListMessage.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "NetMessage.h"
|
||||
|
||||
class PlayerListMessage : public NetMessage
|
||||
{
|
||||
private:
|
||||
static const uint32_t PlayerNameMaxLength = 50;
|
||||
vector<PlayerInfo> _playerList;
|
||||
|
||||
protected:
|
||||
virtual void ProtectedStreamState()
|
||||
{
|
||||
uint32_t nameLength = PlayerNameMaxLength + 1;
|
||||
char playerName[PlayerNameMaxLength + 1];
|
||||
uint8_t playerPort;
|
||||
bool isHost;
|
||||
|
||||
if(_sending) {
|
||||
uint32_t playerCount = (uint32_t)_playerList.size();
|
||||
Stream<uint32_t>(playerCount);
|
||||
for(uint32_t i = 0; i < playerCount; i++) {
|
||||
memset(playerName, 0, nameLength);
|
||||
memcpy(playerName, _playerList[i].Name.c_str(), std::min((uint32_t)_playerList[i].Name.size(), PlayerNameMaxLength));
|
||||
playerPort = _playerList[i].ControllerPort;
|
||||
|
||||
StreamArray(playerName, nameLength);
|
||||
Stream<uint8_t>(playerPort);
|
||||
Stream<bool>(isHost);
|
||||
}
|
||||
} else {
|
||||
uint32_t playerCount;
|
||||
Stream<uint32_t>(playerCount);
|
||||
|
||||
for(uint32_t i = 0; i < playerCount; i++) {
|
||||
memset(playerName, 0, nameLength);
|
||||
StreamArray(playerName, nameLength);
|
||||
Stream<uint8_t>(playerPort);
|
||||
Stream<bool>(isHost);
|
||||
|
||||
PlayerInfo playerInfo;
|
||||
playerInfo.Name = playerName;
|
||||
playerInfo.ControllerPort = playerPort;
|
||||
playerInfo.IsHost = isHost;
|
||||
|
||||
_playerList.push_back(playerInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
PlayerListMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) { }
|
||||
|
||||
PlayerListMessage(vector<PlayerInfo> playerList) : NetMessage(MessageType::PlayerList)
|
||||
{
|
||||
_playerList = playerList;
|
||||
}
|
||||
|
||||
vector<PlayerInfo> GetPlayerList()
|
||||
{
|
||||
return _playerList;
|
||||
}
|
||||
};
|
28
Core/SelectControllerMessage.h
Normal file
28
Core/SelectControllerMessage.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "NetMessage.h"
|
||||
|
||||
class SelectControllerMessage : public NetMessage
|
||||
{
|
||||
private:
|
||||
uint8_t _portNumber;
|
||||
|
||||
protected:
|
||||
virtual void ProtectedStreamState()
|
||||
{
|
||||
Stream<uint8_t>(_portNumber);
|
||||
}
|
||||
|
||||
public:
|
||||
SelectControllerMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) { }
|
||||
|
||||
SelectControllerMessage(uint8_t port) : NetMessage(MessageType::SelectController)
|
||||
{
|
||||
_portNumber = port;
|
||||
}
|
||||
|
||||
uint8_t GetPortNumber()
|
||||
{
|
||||
return _portNumber;
|
||||
}
|
||||
};
|
|
@ -10,5 +10,6 @@ namespace Mesen.GUI.Config
|
|||
{
|
||||
public string Host = "localhost";
|
||||
public UInt16 Port = 8888;
|
||||
public bool Spectator = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,9 +135,10 @@ namespace Mesen.GUI.Config
|
|||
|
||||
InteropEmu.SetConsoleType(inputInfo.ConsoleType);
|
||||
InteropEmu.SetExpansionDevice(inputInfo.ExpansionPortDevice);
|
||||
InteropEmu.SetFlag(EmulationFlags.HasFourScore, (inputInfo.ConsoleType == ConsoleType.Nes && inputInfo.UseFourScore) || (inputInfo.ConsoleType == ConsoleType.Famicom && expansionDevice == InteropEmu.ExpansionPortDevice.FourPlayerAdapter));
|
||||
bool hasFourScore = (inputInfo.ConsoleType == ConsoleType.Nes && inputInfo.UseFourScore) || (inputInfo.ConsoleType == ConsoleType.Famicom && expansionDevice == InteropEmu.ExpansionPortDevice.FourPlayerAdapter);
|
||||
InteropEmu.SetFlag(EmulationFlags.HasFourScore, hasFourScore);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
InteropEmu.SetControllerType(i, inputInfo.Controllers[i].ControllerType);
|
||||
InteropEmu.SetControllerType(i, i < 2 || hasFourScore ? inputInfo.Controllers[i].ControllerType : InteropEmu.ControllerType.None);
|
||||
InteropEmu.SetControllerKeys(i, inputInfo.Controllers[i].GetKeyMappingSet());
|
||||
}
|
||||
}
|
||||
|
|
10
GUI.NET/Forms/NetPlay/frmClientConfig.Designer.cs
generated
10
GUI.NET/Forms/NetPlay/frmClientConfig.Designer.cs
generated
|
@ -36,6 +36,11 @@
|
|||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// baseConfigPanel
|
||||
//
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 111);
|
||||
this.baseConfigPanel.Size = new System.Drawing.Size(290, 29);
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
|
@ -54,7 +59,7 @@
|
|||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(290, 110);
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(290, 111);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// txtPort
|
||||
|
@ -99,7 +104,6 @@
|
|||
//
|
||||
this.chkSpectator.AutoSize = true;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.chkSpectator, 2);
|
||||
this.chkSpectator.Enabled = false;
|
||||
this.chkSpectator.Location = new System.Drawing.Point(3, 55);
|
||||
this.chkSpectator.Name = "chkSpectator";
|
||||
this.chkSpectator.Size = new System.Drawing.Size(106, 17);
|
||||
|
@ -119,9 +123,9 @@
|
|||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(306, 178);
|
||||
this.Name = "frmClientConfig";
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Connect...";
|
||||
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
|
||||
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
|
|
|
@ -18,13 +18,16 @@ namespace Mesen.GUI.Forms.NetPlay
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.txtHost.Text = ConfigManager.Config.ClientConnectionInfo.Host;
|
||||
Entity = ConfigManager.Config.ClientConnectionInfo;
|
||||
|
||||
AddBinding("Host", this.txtHost);
|
||||
AddBinding("Spectator", chkSpectator);
|
||||
this.txtPort.Text = ConfigManager.Config.ClientConnectionInfo.Port.ToString();
|
||||
}
|
||||
|
||||
protected override void UpdateConfig()
|
||||
{
|
||||
ConfigManager.Config.ClientConnectionInfo = new ClientConnectionInfo() { Host = this.txtHost.Text, Port = Convert.ToUInt16(this.txtPort.Text) };
|
||||
((ClientConnectionInfo)Entity).Port = Convert.ToUInt16(this.txtPort.Text);
|
||||
}
|
||||
|
||||
private void Field_TextChanged(object sender, EventArgs e)
|
||||
|
|
|
@ -117,4 +117,7 @@
|
|||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
68
GUI.NET/Forms/frmMain.Designer.cs
generated
68
GUI.NET/Forms/frmMain.Designer.cs
generated
|
@ -91,6 +91,13 @@
|
|||
this.mnuNetPlay = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuStartServer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuConnect = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuNetPlaySelectController = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuNetPlayPlayer1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuNetPlayPlayer2 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuNetPlayPlayer3 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuNetPlayPlayer4 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuNetPlaySpectator = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuFindServer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuProfile = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -556,6 +563,7 @@
|
|||
this.mnuNetPlay.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuStartServer,
|
||||
this.mnuConnect,
|
||||
this.mnuNetPlaySelectController,
|
||||
this.toolStripMenuItem2,
|
||||
this.mnuFindServer,
|
||||
this.mnuProfile});
|
||||
|
@ -578,6 +586,59 @@
|
|||
this.mnuConnect.Text = "Connect to Server";
|
||||
this.mnuConnect.Click += new System.EventHandler(this.mnuConnect_Click);
|
||||
//
|
||||
// mnuNetPlaySelectController
|
||||
//
|
||||
this.mnuNetPlaySelectController.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuNetPlayPlayer1,
|
||||
this.mnuNetPlayPlayer2,
|
||||
this.mnuNetPlayPlayer3,
|
||||
this.mnuNetPlayPlayer4,
|
||||
this.toolStripMenuItem3,
|
||||
this.mnuNetPlaySpectator});
|
||||
this.mnuNetPlaySelectController.Name = "mnuNetPlaySelectController";
|
||||
this.mnuNetPlaySelectController.Size = new System.Drawing.Size(177, 22);
|
||||
this.mnuNetPlaySelectController.Text = "Select Controller";
|
||||
//
|
||||
// mnuNetPlayPlayer1
|
||||
//
|
||||
this.mnuNetPlayPlayer1.Name = "mnuNetPlayPlayer1";
|
||||
this.mnuNetPlayPlayer1.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuNetPlayPlayer1.Text = "Player 1";
|
||||
this.mnuNetPlayPlayer1.Click += new System.EventHandler(this.mnuNetPlayPlayer1_Click);
|
||||
//
|
||||
// mnuNetPlayPlayer2
|
||||
//
|
||||
this.mnuNetPlayPlayer2.Name = "mnuNetPlayPlayer2";
|
||||
this.mnuNetPlayPlayer2.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuNetPlayPlayer2.Text = "Player 2";
|
||||
this.mnuNetPlayPlayer2.Click += new System.EventHandler(this.mnuNetPlayPlayer2_Click);
|
||||
//
|
||||
// mnuNetPlayPlayer3
|
||||
//
|
||||
this.mnuNetPlayPlayer3.Name = "mnuNetPlayPlayer3";
|
||||
this.mnuNetPlayPlayer3.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuNetPlayPlayer3.Text = "Player 3";
|
||||
this.mnuNetPlayPlayer3.Click += new System.EventHandler(this.mnuNetPlayPlayer3_Click);
|
||||
//
|
||||
// mnuNetPlayPlayer4
|
||||
//
|
||||
this.mnuNetPlayPlayer4.Name = "mnuNetPlayPlayer4";
|
||||
this.mnuNetPlayPlayer4.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuNetPlayPlayer4.Text = "Player 4";
|
||||
this.mnuNetPlayPlayer4.Click += new System.EventHandler(this.mnuNetPlayPlayer4_Click);
|
||||
//
|
||||
// toolStripMenuItem3
|
||||
//
|
||||
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
|
||||
this.toolStripMenuItem3.Size = new System.Drawing.Size(149, 6);
|
||||
//
|
||||
// mnuNetPlaySpectator
|
||||
//
|
||||
this.mnuNetPlaySpectator.Name = "mnuNetPlaySpectator";
|
||||
this.mnuNetPlaySpectator.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuNetPlaySpectator.Text = "Spectator";
|
||||
this.mnuNetPlaySpectator.Click += new System.EventHandler(this.mnuNetPlaySpectator_Click);
|
||||
//
|
||||
// toolStripMenuItem2
|
||||
//
|
||||
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
||||
|
@ -904,6 +965,13 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuRegionDendy;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem12;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNetPlaySelectController;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNetPlayPlayer1;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNetPlayPlayer2;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNetPlayPlayer3;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNetPlayPlayer4;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNetPlaySpectator;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -334,6 +334,27 @@ namespace Mesen.GUI.Forms
|
|||
|
||||
mnuStartServer.Enabled = !isNetPlayClient;
|
||||
mnuConnect.Enabled = !InteropEmu.IsServerRunning();
|
||||
mnuNetPlaySelectController.Enabled = isNetPlayClient || InteropEmu.IsServerRunning();
|
||||
if(mnuNetPlaySelectController.Enabled) {
|
||||
int availableControllers = InteropEmu.NetPlayGetAvailableControllers();
|
||||
int currentControllerPort = InteropEmu.NetPlayGetControllerPort();
|
||||
mnuNetPlayPlayer1.Enabled = (availableControllers & 0x01) == 0x01;
|
||||
mnuNetPlayPlayer2.Enabled = (availableControllers & 0x02) == 0x02;
|
||||
mnuNetPlayPlayer3.Enabled = (availableControllers & 0x04) == 0x04;
|
||||
mnuNetPlayPlayer4.Enabled = (availableControllers & 0x08) == 0x08;
|
||||
mnuNetPlayPlayer1.Text = "Player 1 (" + InteropEmu.NetPlayGetControllerType(0).ToString() + ")";
|
||||
mnuNetPlayPlayer2.Text = "Player 2 (" + InteropEmu.NetPlayGetControllerType(1).ToString() + ")";
|
||||
mnuNetPlayPlayer3.Text = "Player 3 (" + InteropEmu.NetPlayGetControllerType(2).ToString() + ")";
|
||||
mnuNetPlayPlayer4.Text = "Player 4 (" + InteropEmu.NetPlayGetControllerType(3).ToString() + ")";
|
||||
|
||||
mnuNetPlayPlayer1.Checked = (currentControllerPort == 0);
|
||||
mnuNetPlayPlayer2.Checked = (currentControllerPort == 1);
|
||||
mnuNetPlayPlayer3.Checked = (currentControllerPort == 2);
|
||||
mnuNetPlayPlayer4.Checked = (currentControllerPort == 3);
|
||||
mnuNetPlaySpectator.Checked = (currentControllerPort == 0xFF);
|
||||
|
||||
mnuNetPlaySpectator.Enabled = true;
|
||||
}
|
||||
|
||||
mnuStartServer.Text = InteropEmu.IsServerRunning() ? "Stop Server" : "Start Server";
|
||||
mnuConnect.Text = isNetPlayClient ? "Disconnect" : "Connect to Server";
|
||||
|
@ -510,7 +531,7 @@ namespace Mesen.GUI.Forms
|
|||
} else {
|
||||
frmServerConfig frm = new frmServerConfig();
|
||||
if(frm.ShowDialog(sender) == System.Windows.Forms.DialogResult.OK) {
|
||||
InteropEmu.StartServer(ConfigManager.Config.ServerInfo.Port);
|
||||
InteropEmu.StartServer(ConfigManager.Config.ServerInfo.Port, ConfigManager.Config.Profile.PlayerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -522,7 +543,7 @@ namespace Mesen.GUI.Forms
|
|||
} else {
|
||||
frmClientConfig frm = new frmClientConfig();
|
||||
if(frm.ShowDialog(sender) == System.Windows.Forms.DialogResult.OK) {
|
||||
InteropEmu.Connect(ConfigManager.Config.ClientConnectionInfo.Host, ConfigManager.Config.ClientConnectionInfo.Port, ConfigManager.Config.Profile.PlayerName, ConfigManager.Config.Profile.PlayerAvatar, (UInt16)ConfigManager.Config.Profile.PlayerAvatar.Length);
|
||||
InteropEmu.Connect(ConfigManager.Config.ClientConnectionInfo.Host, ConfigManager.Config.ClientConnectionInfo.Port, ConfigManager.Config.Profile.PlayerName, ConfigManager.Config.Profile.PlayerAvatar, (UInt16)ConfigManager.Config.Profile.PlayerAvatar.Length, ConfigManager.Config.ClientConnectionInfo.Spectator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -876,5 +897,30 @@ namespace Mesen.GUI.Forms
|
|||
e.Effect = DragDropEffects.Copy;
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuNetPlayPlayer1_Click(object sender, EventArgs e)
|
||||
{
|
||||
InteropEmu.NetPlaySelectController(0);
|
||||
}
|
||||
|
||||
private void mnuNetPlayPlayer2_Click(object sender, EventArgs e)
|
||||
{
|
||||
InteropEmu.NetPlaySelectController(1);
|
||||
}
|
||||
|
||||
private void mnuNetPlayPlayer3_Click(object sender, EventArgs e)
|
||||
{
|
||||
InteropEmu.NetPlaySelectController(2);
|
||||
}
|
||||
|
||||
private void mnuNetPlayPlayer4_Click(object sender, EventArgs e)
|
||||
{
|
||||
InteropEmu.NetPlaySelectController(3);
|
||||
}
|
||||
|
||||
private void mnuNetPlaySpectator_Click(object sender, EventArgs e)
|
||||
{
|
||||
InteropEmu.NetPlaySelectController(0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,13 +43,18 @@ namespace Mesen.GUI
|
|||
[DllImport(DLLPath)] public static extern void Stop();
|
||||
[DllImport(DLLPath, EntryPoint="GetROMPath")] private static extern IntPtr GetROMPathWrapper();
|
||||
[DllImport(DLLPath)] public static extern void Reset();
|
||||
[DllImport(DLLPath)] public static extern void StartServer(UInt16 port);
|
||||
[DllImport(DLLPath)] public static extern void StartServer(UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string hostPlayerName);
|
||||
[DllImport(DLLPath)] public static extern void StopServer();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsServerRunning();
|
||||
[DllImport(DLLPath)] public static extern void Connect([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string host, UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string playerName, byte[] avatarData, UInt32 avatarSize);
|
||||
[DllImport(DLLPath)] public static extern void Connect([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string host, UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string playerName, byte[] avatarData, UInt32 avatarSize, [MarshalAs(UnmanagedType.I1)]bool spectator);
|
||||
[DllImport(DLLPath)] public static extern void Disconnect();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsConnected();
|
||||
|
||||
|
||||
[DllImport(DLLPath)] public static extern Int32 NetPlayGetAvailableControllers();
|
||||
[DllImport(DLLPath)] public static extern void NetPlaySelectController(Int32 controllerPort);
|
||||
[DllImport(DLLPath)] public static extern ControllerType NetPlayGetControllerType(Int32 controllerPort);
|
||||
[DllImport(DLLPath)] public static extern Int32 NetPlayGetControllerPort();
|
||||
|
||||
[DllImport(DLLPath)] public static extern void TakeScreenshot();
|
||||
|
||||
[DllImport(DLLPath)] public static extern IntPtr RegisterNotificationCallback(NotificationListener.NotificationCallback callback);
|
||||
|
|
|
@ -111,25 +111,54 @@ namespace InteropEmu {
|
|||
|
||||
DllExport void __stdcall Reset() { Console::Reset(); }
|
||||
|
||||
DllExport void __stdcall StartServer(uint16_t port) { GameServer::StartServer(port); }
|
||||
DllExport void __stdcall StartServer(uint16_t port, char* hostPlayerName) { GameServer::StartServer(port, hostPlayerName); }
|
||||
DllExport void __stdcall StopServer() { GameServer::StopServer(); }
|
||||
DllExport bool __stdcall IsServerRunning() { return GameServer::Started(); }
|
||||
|
||||
DllExport void __stdcall Connect(char* host, uint16_t port, char* playerName, uint8_t* avatarData, uint32_t avatarSize)
|
||||
DllExport void __stdcall Connect(char* host, uint16_t port, char* playerName, uint8_t* avatarData, uint32_t avatarSize, bool spectator)
|
||||
{
|
||||
shared_ptr<ClientConnectionData> connectionData(new ClientConnectionData(
|
||||
host,
|
||||
port,
|
||||
playerName,
|
||||
avatarData,
|
||||
avatarSize
|
||||
));
|
||||
avatarSize,
|
||||
spectator
|
||||
));
|
||||
|
||||
GameClient::Connect(connectionData);
|
||||
}
|
||||
|
||||
DllExport void __stdcall Disconnect() { GameClient::Disconnect(); }
|
||||
DllExport bool __stdcall IsConnected() { return GameClient::Connected(); }
|
||||
DllExport ControllerType __stdcall NetPlayGetControllerType(int32_t port) { return EmulationSettings::GetControllerType(port); }
|
||||
|
||||
DllExport int32_t __stdcall NetPlayGetAvailableControllers()
|
||||
{
|
||||
if(GameServer::Started()) {
|
||||
return GameServer::GetAvailableControllers();
|
||||
} else {
|
||||
return GameClient::GetAvailableControllers();
|
||||
}
|
||||
}
|
||||
|
||||
DllExport void __stdcall NetPlaySelectController(int32_t port)
|
||||
{
|
||||
if(GameServer::Started()) {
|
||||
return GameServer::SetHostControllerPort(port);
|
||||
} else {
|
||||
return GameClient::SelectController(port);
|
||||
}
|
||||
}
|
||||
|
||||
DllExport int32_t __stdcall NetPlayGetControllerPort()
|
||||
{
|
||||
if(GameServer::Started()) {
|
||||
return GameServer::GetHostControllerPort();
|
||||
} else {
|
||||
return GameClient::GetControllerPort();
|
||||
}
|
||||
}
|
||||
|
||||
DllExport void __stdcall Pause()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue