2014-06-21 15:43:41 -04:00
# include "stdafx.h"
# include "ControlManager.h"
2015-07-10 21:07:24 -04:00
unique_ptr < IKeyManager > ControlManager : : _keyManager = nullptr ;
2014-06-21 15:43:41 -04:00
IControlDevice * ControlManager : : ControlDevices [ ] = { nullptr , nullptr , nullptr , nullptr } ;
2014-07-06 19:54:47 -04:00
IControlDevice * ControlManager : : OriginalControlDevices [ ] = { nullptr , nullptr , nullptr , nullptr } ;
IGameBroadcaster * ControlManager : : GameBroadcaster = nullptr ;
2014-07-06 21:11:52 -04:00
SimpleLock ControlManager : : ControllerLock [ 4 ] ;
2014-06-21 15:43:41 -04:00
ControlManager : : ControlManager ( )
{
}
2015-07-10 21:07:24 -04:00
void ControlManager : : RegisterKeyManager ( IKeyManager * keyManager )
{
_keyManager . reset ( keyManager ) ;
}
bool ControlManager : : IsKeyPressed ( uint32_t keyCode )
{
if ( _keyManager ! = nullptr ) {
return _keyManager - > IsKeyPressed ( keyCode ) ;
}
return false ;
}
uint32_t ControlManager : : GetPressedKey ( )
{
if ( _keyManager ! = nullptr ) {
return _keyManager - > GetPressedKey ( ) ;
}
return 0 ;
}
2015-07-11 08:27:22 -04:00
string ControlManager : : GetKeyName ( uint32_t keyCode )
2015-07-10 21:07:24 -04:00
{
if ( _keyManager ! = nullptr ) {
return _keyManager - > GetKeyName ( keyCode ) ;
}
return 0 ;
}
2015-07-11 08:27:22 -04:00
uint32_t ControlManager : : GetKeyCode ( string keyName )
2015-07-10 21:07:24 -04:00
{
if ( _keyManager ! = nullptr ) {
return _keyManager - > GetKeyCode ( keyName ) ;
}
return 0 ;
}
2014-07-06 19:54:47 -04:00
void ControlManager : : RegisterBroadcaster ( IGameBroadcaster * gameBroadcaster )
{
ControlManager : : GameBroadcaster = gameBroadcaster ;
}
void ControlManager : : UnregisterBroadcaster ( IGameBroadcaster * gameBroadcaster )
{
if ( ControlManager : : GameBroadcaster = = gameBroadcaster ) {
ControlManager : : GameBroadcaster = nullptr ;
}
}
void ControlManager : : BackupControlDevices ( )
{
for ( int i = 0 ; i < 4 ; i + + ) {
OriginalControlDevices [ i ] = ControlDevices [ i ] ;
}
}
void ControlManager : : RestoreControlDevices ( )
{
for ( int i = 0 ; i < 4 ; i + + ) {
2014-07-06 21:11:52 -04:00
ControlManager : : ControllerLock [ i ] . Acquire ( ) ;
2014-07-06 19:54:47 -04:00
ControlDevices [ i ] = OriginalControlDevices [ i ] ;
2014-07-06 21:11:52 -04:00
ControlManager : : ControllerLock [ i ] . Release ( ) ;
}
2014-07-06 19:54:47 -04:00
}
IControlDevice * ControlManager : : GetControlDevice ( uint8_t port )
{
return ControlManager : : ControlDevices [ port ] ;
}
2014-06-21 15:43:41 -04:00
void ControlManager : : RegisterControlDevice ( IControlDevice * controlDevice , uint8_t port )
{
2014-07-06 21:11:52 -04:00
ControlManager : : ControllerLock [ port ] . Acquire ( ) ;
2014-06-21 15:43:41 -04:00
ControlManager : : ControlDevices [ port ] = controlDevice ;
2014-07-06 21:11:52 -04:00
ControlManager : : ControllerLock [ port ] . Release ( ) ;
2014-06-21 15:43:41 -04:00
}
2014-07-06 19:54:47 -04:00
void ControlManager : : UnregisterControlDevice ( IControlDevice * controlDevice )
{
for ( int i = 0 ; i < 4 ; i + + ) {
if ( ControlManager : : ControlDevices [ i ] = = controlDevice ) {
2014-07-06 21:11:52 -04:00
ControlManager : : ControllerLock [ i ] . Acquire ( ) ;
2014-07-06 19:54:47 -04:00
ControlManager : : ControlDevices [ i ] = nullptr ;
2014-07-06 21:11:52 -04:00
ControlManager : : ControllerLock [ i ] . Release ( ) ;
2014-07-06 19:54:47 -04:00
break ;
}
}
2014-07-06 21:11:52 -04:00
2014-07-06 19:54:47 -04:00
}
2014-06-21 15:43:41 -04:00
void ControlManager : : RefreshAllPorts ( )
{
RefreshStateBuffer ( 0 ) ;
RefreshStateBuffer ( 1 ) ;
}
2015-07-10 21:07:24 -04:00
uint8_t ControlManager : : GetControllerState ( uint8_t controllerID )
2014-06-21 15:43:41 -04:00
{
2015-07-10 21:07:24 -04:00
ControlManager : : ControllerLock [ controllerID ] . Acquire ( ) ;
IControlDevice * controlDevice = ControlManager : : ControlDevices [ controllerID ] ;
2014-06-21 15:43:41 -04:00
2014-07-01 12:44:01 -04:00
uint8_t state ;
if ( Movie : : Playing ( ) ) {
2015-07-10 21:07:24 -04:00
state = Movie : : Instance - > GetState ( controllerID ) ;
2014-06-21 15:43:41 -04:00
} else {
2014-07-01 12:44:01 -04:00
if ( controlDevice ) {
2015-12-29 20:54:55 -05:00
if ( _keyManager ) {
_keyManager - > RefreshState ( ) ;
}
2014-07-06 19:54:47 -04:00
state = controlDevice - > GetButtonState ( ) . ToByte ( ) ;
2014-07-01 12:44:01 -04:00
} else {
state = 0x00 ;
}
2014-06-21 15:43:41 -04:00
}
2015-07-10 21:07:24 -04:00
ControlManager : : ControllerLock [ controllerID ] . Release ( ) ;
2014-07-01 12:44:01 -04:00
//Used when recording movies
2015-07-10 21:07:24 -04:00
Movie : : Instance - > RecordState ( controllerID , state ) ;
2014-07-06 19:54:47 -04:00
if ( ControlManager : : GameBroadcaster ) {
2015-07-10 21:07:24 -04:00
//Used when acting as a game server
ControlManager : : GameBroadcaster - > BroadcastInput ( state , controllerID ) ;
2014-07-06 19:54:47 -04:00
}
2014-07-01 12:44:01 -04:00
2015-07-10 21:07:24 -04:00
return state ;
}
bool ControlManager : : HasFourScoreAdapter ( )
{
2015-12-29 20:54:55 -05:00
//When a movie is playing, always assume 4 controllers are plugged in (TODO: Change this so movies know how many controllers were plugged when recording)
return ControlManager : : ControlDevices [ 2 ] ! = nullptr | | ControlManager : : ControlDevices [ 3 ] ! = nullptr | | Movie : : Playing ( ) ;
2015-07-10 21:07:24 -04:00
}
void ControlManager : : RefreshStateBuffer ( uint8_t port )
{
if ( port > = 2 ) {
2015-07-11 08:27:22 -04:00
throw std : : runtime_error ( " Invalid port " ) ;
2015-07-10 21:07:24 -04:00
}
//First 8 bits : Gamepad 1/2
uint32_t state = GetControllerState ( port ) ;
if ( HasFourScoreAdapter ( ) ) {
//Next 8 bits = Gamepad 3/4
state | = GetControllerState ( port + 2 ) < < 8 ;
//Last 8 bits = signature
//Signature for port 0 = 0x10, reversed bit order => 0x08
//Signature for port 1 = 0x20, reversed bit order => 0x04
state | = ( port = = 0 ? 0x08 : 0x04 ) < < 16 ;
} else {
//"All subsequent reads will return D=1 on an authentic controller but may return D=0 on third party controllers."
state | = 0xFFFF00 ;
}
2014-07-01 12:44:01 -04:00
_stateBuffer [ port ] = state ;
2014-06-21 15:43:41 -04:00
}
uint8_t ControlManager : : GetPortValue ( uint8_t port )
{
2015-07-10 21:07:24 -04:00
if ( port > = 2 ) {
2015-07-11 08:27:22 -04:00
throw std : : runtime_error ( " Invalid port " ) ;
2014-06-21 15:43:41 -04:00
}
if ( _refreshState ) {
RefreshStateBuffer ( port ) ;
}
uint8_t returnValue = _stateBuffer [ port ] & 0x01 ;
_stateBuffer [ port ] > > = 1 ;
//"All subsequent reads will return D=1 on an authentic controller but may return D=0 on third party controllers."
2015-07-10 21:07:24 -04:00
_stateBuffer [ port ] | = 0x800000 ;
2014-06-21 15:43:41 -04:00
//"In the NES and Famicom, the top three (or five) bits are not driven, and so retain the bits of the previous byte on the bus.
//Usually this is the most significant byte of the address of the controller port - 0x40.
//Paperboy relies on this behavior and requires that reads from the controller ports return exactly $40 or $41 as appropriate."
return 0x40 | returnValue ;
}
uint8_t ControlManager : : ReadRAM ( uint16_t addr )
{
switch ( addr ) {
case 0x4016 :
return GetPortValue ( 0 ) ;
case 0x4017 :
return GetPortValue ( 1 ) ;
}
return 0 ;
}
void ControlManager : : WriteRAM ( uint16_t addr , uint8_t value )
{
switch ( addr ) {
case 0x4016 :
_refreshState = ( value & 0x01 ) = = 0x01 ;
if ( _refreshState ) {
RefreshAllPorts ( ) ;
}
break ;
}
2014-07-06 19:54:47 -04:00
}
void ControlManager : : StreamState ( bool saving )
{
2015-07-10 21:07:24 -04:00
StreamArray < uint32_t > ( _stateBuffer , 2 ) ;
2014-07-06 19:54:47 -04:00
Stream < bool > ( _refreshState ) ;
2014-06-21 15:43:41 -04:00
}