mirror of
https://github.com/libretro/Mesen.git
synced 2024-11-27 11:00:50 +00:00
167 lines
5.4 KiB
C++
167 lines
5.4 KiB
C++
#include "stdafx.h"
|
|
#include "VsControlManager.h"
|
|
|
|
VsControlManager *VsControlManager::_instance = nullptr;
|
|
|
|
VsControlManager::VsControlManager(shared_ptr<BaseControlDevice> systemActionManager, shared_ptr<BaseControlDevice> mapperControlDevice) : ControlManager(systemActionManager, mapperControlDevice)
|
|
{
|
|
_instance = this;
|
|
}
|
|
|
|
VsControlManager::~VsControlManager()
|
|
{
|
|
if(_instance == this) {
|
|
_instance = nullptr;
|
|
}
|
|
}
|
|
|
|
ControllerType VsControlManager::GetControllerType(uint8_t port)
|
|
{
|
|
ControllerType type = ControlManager::GetControllerType(port);
|
|
if(type == ControllerType::Zapper) {
|
|
type = ControllerType::VsZapper;
|
|
}
|
|
return type;
|
|
}
|
|
|
|
void VsControlManager::Reset(bool softReset)
|
|
{
|
|
_protectionCounter = 0;
|
|
}
|
|
|
|
VsControlManager* VsControlManager::GetInstance()
|
|
{
|
|
return _instance;
|
|
}
|
|
|
|
void VsControlManager::StreamState(bool saving)
|
|
{
|
|
ControlManager::StreamState(saving);
|
|
|
|
VsInputType unusedInputType = VsInputType::Default;
|
|
Stream(_prgChrSelectBit, _protectionCounter, _refreshState, unusedInputType);
|
|
}
|
|
|
|
void VsControlManager::GetMemoryRanges(MemoryRanges &ranges)
|
|
{
|
|
ControlManager::GetMemoryRanges(ranges);
|
|
ranges.AddHandler(MemoryOperation::Read, 0x4020, 0x5FFF);
|
|
ranges.AddHandler(MemoryOperation::Write, 0x4020, 0x5FFF);
|
|
}
|
|
|
|
uint8_t VsControlManager::GetPrgChrSelectBit()
|
|
{
|
|
return _prgChrSelectBit;
|
|
}
|
|
|
|
void VsControlManager::RemapControllerButtons()
|
|
{
|
|
shared_ptr<StandardController> controllers[2];
|
|
controllers[0] = std::dynamic_pointer_cast<StandardController>(GetControlDevice(0));
|
|
controllers[1] = std::dynamic_pointer_cast<StandardController>(GetControlDevice(1));
|
|
|
|
if(!controllers[0] || !controllers[1]) {
|
|
return;
|
|
}
|
|
|
|
VsInputType inputType = EmulationSettings::GetVsInputType();
|
|
if(inputType == VsInputType::TypeA) {
|
|
BaseControlDevice::SwapButtons(controllers[0], StandardController::Buttons::Select, controllers[0], StandardController::Buttons::Start);
|
|
BaseControlDevice::SwapButtons(controllers[1], StandardController::Buttons::Select, controllers[1], StandardController::Buttons::Start);
|
|
} else if(inputType == VsInputType::TypeB) {
|
|
std::swap(controllers[0], controllers[1]);
|
|
BaseControlDevice::SwapButtons(controllers[1], StandardController::Buttons::Select, controllers[0], StandardController::Buttons::Start);
|
|
BaseControlDevice::SwapButtons(controllers[0], StandardController::Buttons::Select, controllers[1], StandardController::Buttons::Start);
|
|
} else if(inputType == VsInputType::TypeC) {
|
|
std::swap(controllers[0], controllers[1]);
|
|
|
|
if(controllers[0]->IsPressed(StandardController::Buttons::Start)) {
|
|
controllers[1]->SetBit(StandardController::Buttons::Select);
|
|
} else {
|
|
controllers[1]->ClearBit(StandardController::Buttons::Select);
|
|
}
|
|
|
|
controllers[0]->ClearBit(StandardController::Buttons::Start);
|
|
controllers[0]->ClearBit(StandardController::Buttons::Select);
|
|
} else if(inputType == VsInputType::TypeD) {
|
|
std::swap(controllers[0], controllers[1]);
|
|
BaseControlDevice::SwapButtons(controllers[1], StandardController::Buttons::Select, controllers[0], StandardController::Buttons::Start);
|
|
BaseControlDevice::SwapButtons(controllers[0], StandardController::Buttons::Select, controllers[1], StandardController::Buttons::Start);
|
|
controllers[0]->InvertBit(StandardController::Buttons::Select);
|
|
controllers[1]->InvertBit(StandardController::Buttons::Select);
|
|
} else if(inputType == VsInputType::TypeE) {
|
|
BaseControlDevice::SwapButtons(controllers[0], StandardController::Buttons::B, controllers[1], StandardController::Buttons::A);
|
|
BaseControlDevice::SwapButtons(controllers[0], StandardController::Buttons::Select, controllers[0], StandardController::Buttons::Start);
|
|
BaseControlDevice::SwapButtons(controllers[1], StandardController::Buttons::Select, controllers[1], StandardController::Buttons::Start);
|
|
}
|
|
}
|
|
|
|
uint8_t VsControlManager::ReadRAM(uint16_t addr)
|
|
{
|
|
uint8_t value = 0;
|
|
|
|
uint32_t crc = Console::GetHashInfo().PrgCrc32Hash;
|
|
|
|
switch(addr) {
|
|
case 0x4016: {
|
|
uint32_t dipSwitches = EmulationSettings::GetDipSwitches();
|
|
value = ControlManager::ReadRAM(addr);
|
|
value |= ((dipSwitches & 0x01) ? 0x08 : 0x00);
|
|
value |= ((dipSwitches & 0x02) ? 0x10 : 0x00);
|
|
break;
|
|
}
|
|
|
|
case 0x4017: {
|
|
value = ControlManager::ReadRAM(addr) & 0x01;
|
|
|
|
uint32_t dipSwitches = EmulationSettings::GetDipSwitches();
|
|
value |= ((dipSwitches & 0x04) ? 0x04 : 0x00);
|
|
value |= ((dipSwitches & 0x08) ? 0x08 : 0x00);
|
|
value |= ((dipSwitches & 0x10) ? 0x10 : 0x00);
|
|
value |= ((dipSwitches & 0x20) ? 0x20 : 0x00);
|
|
value |= ((dipSwitches & 0x40) ? 0x40 : 0x00);
|
|
value |= ((dipSwitches & 0x80) ? 0x80 : 0x00);
|
|
break;
|
|
}
|
|
|
|
case 0x5E00:
|
|
_protectionCounter = 0;
|
|
break;
|
|
|
|
case 0x5E01:
|
|
if(crc == 0xEB2DBA63 || crc == 0x98CFE016) {
|
|
//TKO Boxing
|
|
value = _protectionData[0][_protectionCounter++ & 0x1F];
|
|
} else if(crc == 0x135ADF7C) {
|
|
//RBI Baseball
|
|
value = _protectionData[1][_protectionCounter++ & 0x1F];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if((crc == 0xF9D3B0A3 || crc == 0x66BB838F || crc == 0x9924980A) && addr >= 0x5400 && addr <= 0x57FF) {
|
|
//Super devious
|
|
return _protectionData[2][_protectionCounter++ & 0x1F];
|
|
}
|
|
break;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
void VsControlManager::WriteRAM(uint16_t addr, uint8_t value)
|
|
{
|
|
ControlManager::WriteRAM(addr, value);
|
|
|
|
bool previousState = _refreshState;
|
|
_refreshState = (value & 0x01) == 0x01;
|
|
|
|
if(previousState && !_refreshState) {
|
|
RemapControllerButtons();
|
|
}
|
|
|
|
if(addr == 0x4016) {
|
|
_prgChrSelectBit = (value >> 2) & 0x01;
|
|
}
|
|
}
|