2014-07-09 23:05:07 +00:00
# include "stdafx.h"
# include "GameClientConnection.h"
# include "HandShakeMessage.h"
# include "InputDataMessage.h"
# include "MovieDataMessage.h"
# include "GameInformationMessage.h"
# include "SaveStateMessage.h"
# include "Console.h"
2015-07-18 00:58:57 +00:00
# include "EmulationSettings.h"
2014-07-09 23:05:07 +00:00
# include "ControlManager.h"
2015-07-02 03:17:14 +00:00
# include "ClientConnectionData.h"
2016-02-06 04:14:27 +00:00
# include "StandardController.h"
2017-11-20 04:08:23 +00:00
# include "Zapper.h"
# include "ArkanoidController.h"
# include "BandaiHyperShot.h"
2016-02-06 20:33:45 +00:00
# include "SelectControllerMessage.h"
# include "PlayerListMessage.h"
2016-02-11 04:07:42 +00:00
# include "ForceDisconnectMessage.h"
2014-07-09 23:05:07 +00:00
2015-07-02 03:17:14 +00:00
GameClientConnection : : GameClientConnection ( shared_ptr < Socket > socket , shared_ptr < ClientConnectionData > connectionData ) : GameConnection ( socket , connectionData )
2014-07-09 23:05:07 +00:00
{
2016-12-11 15:56:23 +00:00
_shutdown = false ;
_enableControllers = false ;
_minimumQueueSize = 3 ;
2016-02-11 00:48:15 +00:00
MessageManager : : RegisterNotificationListener ( this ) ;
2016-02-19 18:05:04 +00:00
MessageManager : : DisplayMessage ( " NetPlay " , " ConnectedToServer " ) ;
2017-11-20 04:08:23 +00:00
ControlManager : : RegisterInputProvider ( this ) ;
2014-07-09 23:05:07 +00:00
SendHandshake ( ) ;
}
GameClientConnection : : ~ GameClientConnection ( )
{
2017-11-14 05:00:00 +00:00
Shutdown ( ) ;
}
void GameClientConnection : : Shutdown ( )
{
if ( ! _shutdown ) {
_shutdown = true ;
DisableControllers ( ) ;
2016-02-06 04:14:27 +00:00
2017-11-20 04:08:23 +00:00
ControlManager : : UnregisterInputProvider ( this ) ;
2017-11-14 05:00:00 +00:00
MessageManager : : UnregisterNotificationListener ( this ) ;
MessageManager : : SendNotification ( ConsoleNotificationType : : DisconnectedFromServer ) ;
MessageManager : : DisplayMessage ( " NetPlay " , " ConnectionLost " ) ;
2017-11-20 04:08:23 +00:00
EmulationSettings : : ClearFlags ( EmulationFlags : : ForceMaxSpeed ) ;
2017-11-14 05:00:00 +00:00
}
2014-07-09 23:05:07 +00:00
}
void GameClientConnection : : SendHandshake ( )
{
2016-09-03 14:44:01 +00:00
HandShakeMessage message ( _connectionData - > PlayerName , _connectionData - > Spectator ) ;
2016-02-06 20:33:45 +00:00
SendNetMessage ( message ) ;
}
void GameClientConnection : : SendControllerSelection ( uint8_t port )
{
SelectControllerMessage message ( port ) ;
2015-08-29 01:01:18 +00:00
SendNetMessage ( message ) ;
2014-07-09 23:05:07 +00:00
}
2016-02-06 04:14:27 +00:00
void GameClientConnection : : ClearInputData ( )
2014-07-10 01:48:54 +00:00
{
2017-11-14 05:00:00 +00:00
LockHandler lock = _writeLock . AcquireSafe ( ) ;
2017-11-20 04:08:23 +00:00
for ( int i = 0 ; i < BaseControlDevice : : PortCount ; i + + ) {
2016-02-06 04:14:27 +00:00
_inputSize [ i ] = 0 ;
_inputData [ i ] . clear ( ) ;
2014-07-10 01:48:54 +00:00
}
}
2014-07-09 23:05:07 +00:00
void GameClientConnection : : ProcessMessage ( NetMessage * message )
{
2014-07-10 01:11:02 +00:00
GameInformationMessage * gameInfo ;
2015-07-02 03:17:14 +00:00
switch ( message - > GetType ( ) ) {
2014-07-09 23:05:07 +00:00
case MessageType : : SaveState :
if ( _gameLoaded ) {
2016-02-06 04:14:27 +00:00
DisableControllers ( ) ;
2014-07-09 23:05:07 +00:00
Console : : Pause ( ) ;
2016-02-06 04:14:27 +00:00
ClearInputData ( ) ;
2014-07-09 23:05:07 +00:00
( ( SaveStateMessage * ) message ) - > LoadState ( ) ;
2016-02-06 04:14:27 +00:00
_enableControllers = true ;
2017-11-20 04:08:23 +00:00
InitControlDevice ( ) ;
2014-07-09 23:05:07 +00:00
Console : : Resume ( ) ;
}
break ;
2016-02-06 20:33:45 +00:00
2014-07-09 23:05:07 +00:00
case MessageType : : MovieData :
if ( _gameLoaded ) {
2016-02-06 04:14:27 +00:00
PushControllerState ( ( ( MovieDataMessage * ) message ) - > GetPortNumber ( ) , ( ( MovieDataMessage * ) message ) - > GetInputState ( ) ) ;
2014-07-09 23:05:07 +00:00
}
break ;
2016-02-06 20:33:45 +00:00
2016-02-11 04:07:42 +00:00
case MessageType : : ForceDisconnect :
2016-02-19 18:05:04 +00:00
MessageManager : : DisplayMessage ( " NetPlay " , ( ( ForceDisconnectMessage * ) message ) - > GetMessage ( ) ) ;
2016-02-11 04:07:42 +00:00
break ;
2016-02-06 20:33:45 +00:00
case MessageType : : PlayerList :
_playerList = ( ( PlayerListMessage * ) message ) - > GetPlayerList ( ) ;
break ;
2014-07-09 23:05:07 +00:00
case MessageType : : GameInformation :
2016-02-06 04:14:27 +00:00
DisableControllers ( ) ;
Console : : Pause ( ) ;
2014-07-09 23:05:07 +00:00
gameInfo = ( GameInformationMessage * ) message ;
2015-07-02 03:17:14 +00:00
if ( gameInfo - > GetPort ( ) ! = _controllerPort ) {
_controllerPort = gameInfo - > GetPort ( ) ;
2016-02-06 20:33:45 +00:00
if ( _controllerPort = = GameConnection : : SpectatorPort ) {
2016-02-19 18:05:04 +00:00
MessageManager : : DisplayMessage ( " NetPlay " , " ConnectedAsSpectator " ) ;
2016-02-06 20:33:45 +00:00
} else {
2016-02-19 18:05:04 +00:00
MessageManager : : DisplayMessage ( " NetPlay " , " ConnectedAsPlayer " , std : : to_string ( _controllerPort + 1 ) ) ;
2016-02-06 20:33:45 +00:00
}
2014-07-10 01:11:02 +00:00
}
2014-07-10 01:48:54 +00:00
2016-02-06 04:14:27 +00:00
ClearInputData ( ) ;
2014-07-10 01:48:54 +00:00
2014-07-09 23:05:07 +00:00
_gameLoaded = gameInfo - > AttemptLoadGame ( ) ;
2015-07-02 03:17:14 +00:00
if ( gameInfo - > IsPaused ( ) ) {
2015-07-18 00:58:57 +00:00
EmulationSettings : : SetFlags ( EmulationFlags : : Paused ) ;
2014-07-10 01:48:54 +00:00
} else {
2015-07-18 00:58:57 +00:00
EmulationSettings : : ClearFlags ( EmulationFlags : : Paused ) ;
2014-07-10 01:48:54 +00:00
}
2016-02-06 04:14:27 +00:00
Console : : Resume ( ) ;
2015-08-29 01:01:18 +00:00
break ;
default :
2014-07-09 23:05:07 +00:00
break ;
}
}
2016-02-06 04:14:27 +00:00
2017-11-20 04:08:23 +00:00
void GameClientConnection : : PushControllerState ( uint8_t port , ControlDeviceState state )
2016-02-06 04:14:27 +00:00
{
LockHandler lock = _writeLock . AcquireSafe ( ) ;
_inputData [ port ] . push_back ( state ) ;
_inputSize [ port ] + + ;
if ( _inputData [ port ] . size ( ) > = _minimumQueueSize ) {
_waitForInput [ port ] . Signal ( ) ;
}
}
void GameClientConnection : : DisableControllers ( )
{
//Used to prevent deadlocks when client is trying to fill its buffer while the host changes the current game/settings/etc. (i.e situations where we need to call Console::Pause())
ClearInputData ( ) ;
_enableControllers = false ;
2017-11-20 04:08:23 +00:00
for ( int i = 0 ; i < BaseControlDevice : : PortCount ; i + + ) {
2016-02-06 04:14:27 +00:00
_waitForInput [ i ] . Signal ( ) ;
}
}
2017-11-20 04:08:23 +00:00
bool GameClientConnection : : SetInput ( BaseControlDevice * device )
2016-02-06 04:14:27 +00:00
{
if ( _enableControllers ) {
2017-11-20 04:08:23 +00:00
uint8_t port = device - > GetPort ( ) ;
2016-02-06 04:14:27 +00:00
while ( _inputSize [ port ] = = 0 ) {
_waitForInput [ port ] . Wait ( ) ;
if ( port = = 0 & & _minimumQueueSize < 10 ) {
//Increase buffer size - reduces freezes at the cost of additional lag
_minimumQueueSize + + ;
}
if ( _shutdown | | ! _enableControllers ) {
2017-11-20 04:08:23 +00:00
return true ;
2016-02-06 04:14:27 +00:00
}
}
LockHandler lock = _writeLock . AcquireSafe ( ) ;
2017-11-20 04:08:23 +00:00
ControlDeviceState state = _inputData [ port ] . front ( ) ;
2016-02-06 04:14:27 +00:00
_inputData [ port ] . pop_front ( ) ;
_inputSize [ port ] - - ;
if ( _inputData [ port ] . size ( ) > _minimumQueueSize ) {
//Too much data, catch up
2017-05-19 22:27:39 +00:00
EmulationSettings : : SetFlags ( EmulationFlags : : ForceMaxSpeed ) ;
2016-02-06 04:14:27 +00:00
} else {
2017-05-19 22:27:39 +00:00
EmulationSettings : : ClearFlags ( EmulationFlags : : ForceMaxSpeed ) ;
2016-02-06 04:14:27 +00:00
EmulationSettings : : SetEmulationSpeed ( 100 ) ;
}
2017-11-20 04:08:23 +00:00
device - > SetRawState ( state ) ;
2016-02-06 04:14:27 +00:00
}
2017-11-20 04:08:23 +00:00
return true ;
2016-02-06 04:14:27 +00:00
}
2017-11-20 04:08:23 +00:00
void GameClientConnection : : InitControlDevice ( )
{
if ( _controllerPort = = BaseControlDevice : : ExpDevicePort ) {
_newControlDevice = ControlManager : : CreateExpansionDevice ( EmulationSettings : : GetExpansionDevice ( ) ) ;
} else {
//Pretend we are using port 0 (to use player 1's keybindings during netplay)
_newControlDevice = ControlManager : : CreateControllerDevice ( EmulationSettings : : GetControllerType ( _controllerPort ) , 0 ) ;
}
}
2016-02-11 00:48:15 +00:00
void GameClientConnection : : ProcessNotification ( ConsoleNotificationType type , void * parameter )
{
if ( type = = ConsoleNotificationType : : ConfigChanged ) {
2017-11-20 04:08:23 +00:00
InitControlDevice ( ) ;
2016-02-11 00:48:15 +00:00
}
}
2014-07-09 23:05:07 +00:00
void GameClientConnection : : SendInput ( )
{
2015-08-24 00:24:24 +00:00
if ( _gameLoaded ) {
2016-02-11 00:48:15 +00:00
if ( _newControlDevice ) {
_controlDevice = _newControlDevice ;
_newControlDevice . reset ( ) ;
}
2017-11-20 04:08:23 +00:00
ControlDeviceState inputState ;
2016-02-14 17:58:35 +00:00
if ( _controlDevice ) {
2017-11-20 04:08:23 +00:00
_controlDevice - > SetStateFromInput ( ) ;
inputState = _controlDevice - > GetRawState ( ) ;
2016-02-06 04:14:27 +00:00
}
2016-02-14 17:58:35 +00:00
2015-08-24 00:24:24 +00:00
if ( _lastInputSent ! = inputState ) {
2015-08-29 01:01:18 +00:00
InputDataMessage message ( inputState ) ;
SendNetMessage ( message ) ;
2015-08-24 00:24:24 +00:00
_lastInputSent = inputState ;
}
2014-07-09 23:05:07 +00:00
}
2016-02-06 20:33:45 +00:00
}
void GameClientConnection : : SelectController ( uint8_t port )
{
SendControllerSelection ( port ) ;
}
uint8_t GameClientConnection : : GetAvailableControllers ( )
{
2017-11-20 04:08:23 +00:00
uint8_t availablePorts = ( 1 < < BaseControlDevice : : PortCount ) - 1 ;
2016-02-06 20:33:45 +00:00
for ( PlayerInfo & playerInfo : _playerList ) {
2017-11-20 04:08:23 +00:00
if ( playerInfo . ControllerPort < BaseControlDevice : : PortCount ) {
2016-02-06 20:33:45 +00:00
availablePorts & = ~ ( 1 < < playerInfo . ControllerPort ) ;
}
}
return availablePorts ;
}
uint8_t GameClientConnection : : GetControllerPort ( )
{
return _controllerPort ;
2014-07-09 23:05:07 +00:00
}