VS: Fixed TKO Boxing/RBI Baseball/Super Devious freezes

This commit is contained in:
Souryo 2016-06-21 22:13:26 -04:00
parent 0e27c7ffab
commit 5096ff414c
7 changed files with 105 additions and 24 deletions

View file

@ -183,6 +183,7 @@ void Console::ResetComponents(bool softReset)
_ppu->Reset();
_apu->Reset(softReset);
_cpu->Reset(softReset);
_controlManager->Reset(softReset);
SoundMixer::StopAudio(true);

View file

@ -198,6 +198,10 @@ void ControlManager::WriteRAM(uint16_t addr, uint8_t value)
}
}
void ControlManager::Reset(bool softReset)
{
}
void ControlManager::StreamState(bool saving)
{
//Restore controllers that were being used at the time the snapshot was made

View file

@ -41,6 +41,8 @@ class ControlManager : public Snapshotable, public IMemoryHandler
ControlManager();
void UpdateControlDevices();
virtual void Reset(bool softReset);
static void RegisterBroadcaster(IGameBroadcaster* gameBroadcaster);
static void UnregisterBroadcaster(IGameBroadcaster* gameBroadcaster);

View file

@ -97,8 +97,13 @@ bool RomLoader::LoadFromMemory(uint8_t* buffer, size_t length, string romName)
fileData = IpsPatcher::PatchBuffer(_ipsFilename, fileData);
}
uint32_t crc = CRC32::GetCRC(buffer, length);
MessageManager::Log("");
MessageManager::Log("Loading rom: " + romName);
stringstream crcHex;
crcHex << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << crc;
MessageManager::Log("File CRC32: 0x" + crcHex.str());
if(memcmp(buffer, "NES\x1a", 4) == 0) {
iNesLoader loader;
_romData = loader.LoadRom(fileData);
@ -110,8 +115,8 @@ bool RomLoader::LoadFromMemory(uint8_t* buffer, size_t length, string romName)
_romData.Error = true;
}
_romData.Crc32 = crc;
_romData.RawData = fileData;
_romData.Crc32 = CRC32::GetCRC(buffer, length);
_romData.RomName = romName;
_romData.Filename = _filename;

View file

@ -2,6 +2,7 @@
#include "stdafx.h"
#include "ControlManager.h"
#include "CPU.h"
#include "Console.h"
#include <assert.h>
class VsControlManager : public ControlManager
@ -13,6 +14,28 @@ private:
bool _serviceButton = false;
bool _coinInserted[2] = { };
int32_t _coinInsertCycle[2] = { };
uint32_t _protectionCounter = 0;
uint32_t _protectionData[3][32] = {
{
0xFF, 0xBF, 0xB7, 0x97, 0x97, 0x17, 0x57, 0x4F,
0x6F, 0x6B, 0xEB, 0xA9, 0xB1, 0x90, 0x94, 0x14,
0x56, 0x4E, 0x6F, 0x6B, 0xEB, 0xA9, 0xB1, 0x90,
0xD4, 0x5C, 0x3E, 0x26, 0x87, 0x83, 0x13, 0x00
},
{
0x00, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00,
0x00, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
},
{
0x05, 0x01, 0x89, 0x37, 0x05, 0x00, 0xD1, 0x3E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
};
private:
void UpdateCoinInsertedFlags()
@ -38,11 +61,22 @@ public:
}
}
void Reset(bool softReset)
{
_protectionCounter = 0;
}
static VsControlManager* GetInstance()
{
return _instance;
}
void StreamState(bool saving)
{
ControlManager::StreamState(saving);
Stream(_prgChrSelectBit, _protectionCounter);
}
void InsertCoin(uint8_t port)
{
assert(port < 2);
@ -78,33 +112,57 @@ public:
UpdateCoinInsertedFlags();
uint8_t value = 0;
uint32_t crc = Console::GetCrc32();
switch(addr) {
case 0x4016: value = GetPortValue(1); break;
case 0x4017: value = GetPortValue(0); break;
}
case 0x4016:
value = GetPortValue(1) & 0x01;
if(_coinInserted[0]) {
value |= 0x20;
}
if(_coinInserted[1]) {
value |= 0x40;
}
if(_serviceButton) {
value |= 0x04;
}
value &= 0x01;
value |= ((_dipSwitches & 0x01) ? 0x08 : 0x00);
value |= ((_dipSwitches & 0x02) ? 0x10 : 0x00);
break;
case 0x4017:
value = GetPortValue(0) & 0x01;
if(addr == 0x4016) {
if(_coinInserted[0]) {
value |= 0x20;
}
if(_coinInserted[1]) {
value |= 0x40;
}
if(_serviceButton) {
value |= 0x04;
}
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;
value |= ((_dipSwitches & 0x01) ? 0x08 : 0x00);
value |= ((_dipSwitches & 0x02) ? 0x10 : 0x00);
} else if(addr == 0x4017) {
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);
case 0x5E00:
_protectionCounter = 0;
break;
case 0x5E01:
if(crc == 0x4A5FEE2B) {
//TKO Boxing
value = _protectionData[0][_protectionCounter++ & 0x1F];
} else if(crc == 0x90584067) {
//RBI Baseball
value = _protectionData[1][_protectionCounter++ & 0x1F];
}
break;
default:
if(crc == 0x5B0433F3 && addr >= 0x5400 && addr <= 0x57FF) {
//Super devious
return _protectionData[2][_protectionCounter++ & 0x1F];
}
break;
}
return value;

View file

@ -24,6 +24,13 @@ protected:
SelectCHRPage(0, 0);
}
void StreamState(bool saving)
{
BaseMapper::StreamState(saving);
Stream(_prgChrSelectBit);
}
uint8_t ReadVRAM(uint16_t addr)
{
if(_prgChrSelectBit != VsControlManager::GetInstance()->GetPrgChrSelectBit()) {

View file

@ -42,6 +42,10 @@ RomData iNesLoader::LoadRom(vector<uint8_t>& romFile)
buffer += header.GetPrgSize();
romData.ChrRom.insert(romData.ChrRom.end(), buffer, buffer + header.GetChrSize());
stringstream crcHex;
crcHex << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << romCrc;
MessageManager::Log("PRG+CHR CRC32: 0x" + crcHex.str());
if(romData.IsNes20Header) {
MessageManager::Log("[iNes] NES 2.0 file: Yes");
}