Simplifying light state logic, adding header block, adapting tests
This commit is contained in:
parent
4040672b0b
commit
a2c541b5a0
|
@ -85,14 +85,14 @@ class EmuInstanceBase
|
||||||
std::string stateData;
|
std::string stateData;
|
||||||
bool status = loadStringFromFile(stateData, stateFilePath);
|
bool status = loadStringFromFile(stateData, stateFilePath);
|
||||||
if (status == false) EXIT_WITH_ERROR("Could not find/read state file: %s\n", stateFilePath.c_str());
|
if (status == false) EXIT_WITH_ERROR("Could not find/read state file: %s\n", stateFilePath.c_str());
|
||||||
deserializeFullState((uint8_t *)stateData.data());
|
deserializeState((uint8_t *)stateData.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void saveStateFile(const std::string &stateFilePath) const
|
inline void saveStateFile(const std::string &stateFilePath) const
|
||||||
{
|
{
|
||||||
std::string stateData;
|
std::string stateData;
|
||||||
stateData.resize(_fullStateSize);
|
stateData.resize(_stateSize);
|
||||||
serializeFullState((uint8_t *)stateData.data());
|
serializeState((uint8_t *)stateData.data());
|
||||||
saveStringToFile(stateData, stateFilePath.c_str());
|
saveStringToFile(stateData, stateFilePath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,29 +110,37 @@ class EmuInstanceBase
|
||||||
if (status == false) EXIT_WITH_ERROR("Could not process ROM file: %s\n", romFilePath.c_str());
|
if (status == false) EXIT_WITH_ERROR("Could not process ROM file: %s\n", romFilePath.c_str());
|
||||||
|
|
||||||
// Detecting full state size
|
// Detecting full state size
|
||||||
_fullStateSize = getFullStateSize();
|
_stateSize = getStateSize();
|
||||||
|
}
|
||||||
|
|
||||||
// Detecting lite state size
|
void enableStateBlock(const std::string& block)
|
||||||
_liteStateSize = getLiteStateSize();
|
{
|
||||||
|
// Calling implementation
|
||||||
|
enableStateBlockImpl(block);
|
||||||
|
|
||||||
|
// Recalculating State size
|
||||||
|
_stateSize = getStateSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableStateBlock(const std::string& block)
|
||||||
|
{
|
||||||
|
// Calling implementation
|
||||||
|
disableStateBlockImpl(block);
|
||||||
|
|
||||||
|
// Recalculating State Size
|
||||||
|
_stateSize = getStateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Virtual functions
|
// Virtual functions
|
||||||
|
|
||||||
virtual bool loadROMFileImpl(const std::string &romFilePath) = 0;
|
|
||||||
virtual void advanceStateImpl(const Controller::port_t controller1, const Controller::port_t controller2) = 0;
|
|
||||||
virtual uint8_t *getLowMem() const = 0;
|
virtual uint8_t *getLowMem() const = 0;
|
||||||
virtual uint8_t *getNametableMem() const = 0;
|
virtual uint8_t *getNametableMem() const = 0;
|
||||||
virtual uint8_t *getHighMem() const = 0;
|
virtual uint8_t *getHighMem() const = 0;
|
||||||
virtual const uint8_t *getChrMem() const = 0;
|
virtual const uint8_t *getChrMem() const = 0;
|
||||||
virtual size_t getChrMemSize() const = 0;
|
virtual size_t getChrMemSize() const = 0;
|
||||||
virtual void serializeFullState(uint8_t *state) const = 0;
|
virtual void serializeState(uint8_t *state) const = 0;
|
||||||
virtual void deserializeFullState(const uint8_t *state) = 0;
|
virtual void deserializeState(const uint8_t *state) = 0;
|
||||||
virtual void serializeLiteState(uint8_t *state) const = 0;
|
virtual size_t getStateSize() const = 0;
|
||||||
virtual void deserializeLiteState(const uint8_t *state) = 0;
|
|
||||||
virtual size_t getFullStateSize() const = 0;
|
|
||||||
virtual size_t getLiteStateSize() const = 0;
|
|
||||||
virtual void enableLiteStateBlock(const std::string& block) = 0;
|
|
||||||
virtual void disableLiteStateBlock(const std::string& block) = 0;
|
|
||||||
|
|
||||||
virtual void doSoftReset() = 0;
|
virtual void doSoftReset() = 0;
|
||||||
virtual void doHardReset() = 0;
|
virtual void doHardReset() = 0;
|
||||||
|
@ -141,11 +149,13 @@ class EmuInstanceBase
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Storage for the light state size
|
virtual void enableStateBlockImpl(const std::string& block) = 0;
|
||||||
size_t _liteStateSize;
|
virtual void disableStateBlockImpl(const std::string& block) = 0;
|
||||||
|
virtual bool loadROMFileImpl(const std::string &romFilePath) = 0;
|
||||||
|
virtual void advanceStateImpl(const Controller::port_t controller1, const Controller::port_t controller2) = 0;
|
||||||
|
|
||||||
// Storage for the full state size
|
// Storage for the light state size
|
||||||
size_t _fullStateSize;
|
size_t _stateSize;
|
||||||
|
|
||||||
// Flag to determine whether to enable/disable rendering
|
// Flag to determine whether to enable/disable rendering
|
||||||
bool _doRendering = true;
|
bool _doRendering = true;
|
||||||
|
|
|
@ -28,8 +28,8 @@ class PlaybackInstance
|
||||||
{
|
{
|
||||||
stepData_t step;
|
stepData_t step;
|
||||||
step.input = input;
|
step.input = input;
|
||||||
step.stateData = (uint8_t *)malloc(_emu->getFullStateSize());
|
step.stateData = (uint8_t *)malloc(_emu->getStateSize());
|
||||||
_emu->serializeFullState(step.stateData);
|
_emu->serializeState(step.stateData);
|
||||||
step.hash = _emu->getStateHash();
|
step.hash = _emu->getStateHash();
|
||||||
|
|
||||||
// Adding the step into the sequence
|
// Adding the step into the sequence
|
||||||
|
@ -160,7 +160,7 @@ class PlaybackInstance
|
||||||
if (stepId > 0)
|
if (stepId > 0)
|
||||||
{
|
{
|
||||||
const auto stateData = getStateData(stepId - 1);
|
const auto stateData = getStateData(stepId - 1);
|
||||||
_emu->deserializeFullState(stateData);
|
_emu->deserializeState(stateData);
|
||||||
_emu->advanceState(getStateInput(stepId - 1));
|
_emu->advanceState(getStateInput(stepId - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ int main(int argc, char *argv[])
|
||||||
auto p = PlaybackInstance(&e, sequence);
|
auto p = PlaybackInstance(&e, sequence);
|
||||||
|
|
||||||
// Getting state size
|
// Getting state size
|
||||||
auto stateSize = e.getFullStateSize();
|
auto stateSize = e.getStateSize();
|
||||||
|
|
||||||
// Flag to continue running playback
|
// Flag to continue running playback
|
||||||
bool continueRunning = true;
|
bool continueRunning = true;
|
||||||
|
|
|
@ -47,28 +47,24 @@ class EmuInstance : public EmuInstanceBase
|
||||||
const uint8_t *getChrMem() const override { return _nes->chr_mem(); };
|
const uint8_t *getChrMem() const override { return _nes->chr_mem(); };
|
||||||
size_t getChrMemSize() const override { return _nes->chr_size(); };
|
size_t getChrMemSize() const override { return _nes->chr_size(); };
|
||||||
|
|
||||||
void serializeLiteState(uint8_t *state) const override { serializeFullState(state); }
|
void enableStateBlockImpl(const std::string& block) override {};
|
||||||
void deserializeLiteState(const uint8_t *state) override { deserializeFullState(state); }
|
void disableStateBlockImpl(const std::string& block) override {};
|
||||||
inline size_t getLiteStateSize() const override { return getFullStateSize(); }
|
|
||||||
|
|
||||||
void enableLiteStateBlock(const std::string& block) override {};
|
void serializeState(uint8_t *state) const override
|
||||||
void disableLiteStateBlock(const std::string& block) override {};
|
|
||||||
|
|
||||||
void serializeFullState(uint8_t *state) const override
|
|
||||||
{
|
{
|
||||||
Mem_Writer w(state, _fullStateSize, 0);
|
Mem_Writer w(state, _stateSize, 0);
|
||||||
Auto_File_Writer a(w);
|
Auto_File_Writer a(w);
|
||||||
_nes->save_state(a);
|
_nes->save_state(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deserializeFullState(const uint8_t *state) override
|
void deserializeState(const uint8_t *state) override
|
||||||
{
|
{
|
||||||
Mem_File_Reader r(state, _fullStateSize);
|
Mem_File_Reader r(state, _stateSize);
|
||||||
Auto_File_Reader a(r);
|
Auto_File_Reader a(r);
|
||||||
_nes->load_state(a);
|
_nes->load_state(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t getFullStateSize() const override
|
inline size_t getStateSize() const override
|
||||||
{
|
{
|
||||||
uint8_t *data = (uint8_t *)malloc(_DUMMY_SIZE);
|
uint8_t *data = (uint8_t *)malloc(_DUMMY_SIZE);
|
||||||
Mem_Writer w(data, _DUMMY_SIZE);
|
Mem_Writer w(data, _DUMMY_SIZE);
|
||||||
|
|
|
@ -93,6 +93,7 @@ class Core : private Cpu
|
||||||
bool NTABBlockEnabled = true;
|
bool NTABBlockEnabled = true;
|
||||||
bool CHRRBlockEnabled = true;
|
bool CHRRBlockEnabled = true;
|
||||||
bool SRAMBlockEnabled = true;
|
bool SRAMBlockEnabled = true;
|
||||||
|
bool HEADBlockEnabled = true;
|
||||||
|
|
||||||
Core() : ppu(this)
|
Core() : ppu(this)
|
||||||
{
|
{
|
||||||
|
@ -150,7 +151,7 @@ class Core : private Cpu
|
||||||
reset(true, true);
|
reset(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t serializeFullState(uint8_t *buffer) const
|
size_t serializeState(uint8_t *buffer) const
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
std::string headerCode;
|
std::string headerCode;
|
||||||
|
@ -158,153 +159,247 @@ class Core : private Cpu
|
||||||
uint32_t blockSize = 0;
|
uint32_t blockSize = 0;
|
||||||
void *dataSource;
|
void *dataSource;
|
||||||
|
|
||||||
headerCode = "NESS"; // NESS Block
|
|
||||||
blockSize = 0xFFFFFFFF;
|
blockSize = 0xFFFFFFFF;
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
if (HEADBlockEnabled == true)
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
|
|
||||||
headerCode = "TIME"; // TIME Block
|
|
||||||
nes_state_t state = nes;
|
|
||||||
state.timestamp *= 5;
|
|
||||||
blockSize = sizeof(nes_state_t);
|
|
||||||
dataSource = (void *)&state;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
headerCode = "CPUR"; // CPUR Block
|
|
||||||
cpu_state_t s;
|
|
||||||
memset(&s, 0, sizeof s);
|
|
||||||
s.pc = r.pc;
|
|
||||||
s.s = r.sp;
|
|
||||||
s.a = r.a;
|
|
||||||
s.x = r.x;
|
|
||||||
s.y = r.y;
|
|
||||||
s.p = r.status;
|
|
||||||
blockSize = sizeof(cpu_state_t);
|
|
||||||
dataSource = (void *)&s;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
headerCode = "PPUR"; // PPUR Block
|
|
||||||
blockSize = sizeof(ppu_state_t);
|
|
||||||
dataSource = (void *)&ppu;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
headerCode = "APUR"; // APUR Block
|
|
||||||
Apu::apu_state_t apuState;
|
|
||||||
impl->apu.save_state(&apuState);
|
|
||||||
blockSize = sizeof(Apu::apu_state_t);
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &apuState, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
headerCode = "CTRL"; // CTRL Block
|
|
||||||
blockSize = sizeof(joypad_state_t);
|
|
||||||
dataSource = (void *)&joypad;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
headerCode = "MAPR"; // MAPR Block
|
|
||||||
blockSize = mapper->state_size;
|
|
||||||
dataSource = (void *)mapper->state;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
headerCode = "LRAM"; // LRAM Block
|
|
||||||
blockSize = low_ram_size;
|
|
||||||
dataSource = (void *)low_mem;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
headerCode = "SPRT"; // SPRT Block
|
|
||||||
blockSize = Ppu::spr_ram_size;
|
|
||||||
dataSource = (void *)ppu.spr_ram;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
headerCode = "NTAB"; // NTAB Block
|
|
||||||
size_t nametable_size = 0x800;
|
|
||||||
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
|
||||||
blockSize = nametable_size;
|
|
||||||
dataSource = (void *)ppu.impl->nt_ram;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
if (ppu.chr_is_writable)
|
|
||||||
{
|
{
|
||||||
headerCode = "CHRR"; // CHRR Block
|
headerCode = "NESS"; // NESS Block
|
||||||
blockSize = ppu.chr_size;
|
|
||||||
dataSource = (void *)ppu.impl->chr_ram;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
pos += headerSize;
|
pos += headerSize;
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
pos += headerSize;
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TIMEBlockEnabled == true)
|
||||||
|
{
|
||||||
|
nes_state_t state = nes;
|
||||||
|
state.timestamp *= 5;
|
||||||
|
blockSize = sizeof(nes_state_t);
|
||||||
|
dataSource = (void *)&state;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "TIME"; // TIME Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
pos += blockSize;
|
pos += blockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sram_present)
|
if (CPURBlockEnabled == true)
|
||||||
{
|
{
|
||||||
headerCode = "SRAM"; // SRAM Block
|
cpu_state_t s;
|
||||||
blockSize = impl->sram_size;
|
memset(&s, 0, sizeof s);
|
||||||
dataSource = (void *)impl->sram;
|
s.pc = r.pc;
|
||||||
|
s.s = r.sp;
|
||||||
|
s.a = r.a;
|
||||||
|
s.x = r.x;
|
||||||
|
s.y = r.y;
|
||||||
|
s.p = r.status;
|
||||||
|
blockSize = sizeof(cpu_state_t);
|
||||||
|
dataSource = (void *)&s;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "CPUR"; // CPUR Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PPURBlockEnabled == true)
|
||||||
|
{
|
||||||
|
blockSize = sizeof(ppu_state_t);
|
||||||
|
dataSource = (void *)&ppu;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "PPUR"; // PPUR Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (APURBlockEnabled == true)
|
||||||
|
{
|
||||||
|
Apu::apu_state_t apuState;
|
||||||
|
impl->apu.save_state(&apuState);
|
||||||
|
blockSize = sizeof(Apu::apu_state_t);
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "APUR"; // APUR Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &apuState, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CTRLBlockEnabled == true)
|
||||||
|
{
|
||||||
|
blockSize = sizeof(joypad_state_t);
|
||||||
|
dataSource = (void *)&joypad;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "CTRL"; // CTRL Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MAPRBlockEnabled == true)
|
||||||
|
{
|
||||||
|
blockSize = mapper->state_size;
|
||||||
|
dataSource = (void *)mapper->state;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "MAPR"; // MAPR Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LRAMBlockEnabled == true)
|
||||||
|
{
|
||||||
|
blockSize = low_ram_size;
|
||||||
|
dataSource = (void *)low_mem;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "LRAM"; // LRAM Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SPRTBlockEnabled == true)
|
||||||
|
{
|
||||||
|
blockSize = Ppu::spr_ram_size;
|
||||||
|
dataSource = (void *)ppu.spr_ram;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "SPRT"; // SPRT Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NTABBlockEnabled == true)
|
||||||
|
{
|
||||||
|
size_t nametable_size = 0x800;
|
||||||
|
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
||||||
|
blockSize = nametable_size;
|
||||||
|
dataSource = (void *)ppu.impl->nt_ram;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "NTAB"; // NTAB Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CHRRBlockEnabled == true)
|
||||||
|
{
|
||||||
|
if (ppu.chr_is_writable)
|
||||||
|
{
|
||||||
|
blockSize = ppu.chr_size;
|
||||||
|
dataSource = (void *)ppu.impl->chr_ram;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "CHRR"; // CHRR Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SRAMBlockEnabled == true)
|
||||||
|
{
|
||||||
|
if (sram_present)
|
||||||
|
{
|
||||||
|
blockSize = impl->sram_size;
|
||||||
|
dataSource = (void *)impl->sram;
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "SRAM"; // SRAM Block
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
|
pos += headerSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HEADBlockEnabled == true)
|
||||||
|
{
|
||||||
|
headerCode = "gend"; // gend Block
|
||||||
|
blockSize = 0;
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||||
pos += headerSize;
|
pos += headerSize;
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||||
pos += headerSize;
|
pos += headerSize;
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
headerCode = "gend"; // gend Block
|
|
||||||
blockSize = 0;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
|
||||||
pos += headerSize;
|
|
||||||
|
|
||||||
return pos; // Bytes written
|
return pos; // Bytes written
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t deserializeFullState(const uint8_t *buffer)
|
size_t deserializeState(const uint8_t *buffer)
|
||||||
{
|
{
|
||||||
disable_rendering();
|
disable_rendering();
|
||||||
error_count = 0;
|
error_count = 0;
|
||||||
|
@ -315,119 +410,140 @@ class Core : private Cpu
|
||||||
uint32_t blockSize = 0;
|
uint32_t blockSize = 0;
|
||||||
|
|
||||||
// NESS Block
|
// NESS Block
|
||||||
pos += headerSize;
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += headerSize;
|
|
||||||
|
|
||||||
// TIME Block
|
// TIME Block
|
||||||
nes_state_t nesState;
|
if (TIMEBlockEnabled == true)
|
||||||
pos += headerSize;
|
{
|
||||||
pos += headerSize;
|
nes_state_t nesState;
|
||||||
blockSize = sizeof(nes_state_t);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
memcpy(&nesState, &buffer[pos], blockSize);
|
blockSize = sizeof(nes_state_t);
|
||||||
pos += blockSize;
|
memcpy(&nesState, &buffer[pos], blockSize);
|
||||||
nes = nesState;
|
pos += blockSize;
|
||||||
nes.timestamp /= 5;
|
nes = nesState;
|
||||||
|
nes.timestamp /= 5;
|
||||||
|
}
|
||||||
|
|
||||||
// CPUR Block
|
// CPUR Block
|
||||||
cpu_state_t s;
|
if (CPURBlockEnabled == true)
|
||||||
blockSize = sizeof(cpu_state_t);
|
{
|
||||||
pos += headerSize;
|
cpu_state_t s;
|
||||||
pos += headerSize;
|
blockSize = sizeof(cpu_state_t);
|
||||||
memcpy((void *)&s, &buffer[pos], blockSize);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += blockSize;
|
memcpy((void *)&s, &buffer[pos], blockSize);
|
||||||
r.pc = s.pc;
|
pos += blockSize;
|
||||||
r.sp = s.s;
|
r.pc = s.pc;
|
||||||
r.a = s.a;
|
r.sp = s.s;
|
||||||
r.x = s.x;
|
r.a = s.a;
|
||||||
r.y = s.y;
|
r.x = s.x;
|
||||||
r.status = s.p;
|
r.y = s.y;
|
||||||
|
r.status = s.p;
|
||||||
|
}
|
||||||
|
|
||||||
// PPUR Block
|
// PPUR Block
|
||||||
blockSize = sizeof(ppu_state_t);
|
if (PPURBlockEnabled == true)
|
||||||
pos += headerSize;
|
{
|
||||||
pos += headerSize;
|
blockSize = sizeof(ppu_state_t);
|
||||||
memcpy((void *)&ppu, &buffer[pos], blockSize);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += blockSize;
|
memcpy((void *)&ppu, &buffer[pos], blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
// APUR Block
|
// APUR Block
|
||||||
Apu::apu_state_t apuState;
|
if (APURBlockEnabled == true)
|
||||||
blockSize = sizeof(Apu::apu_state_t);
|
{
|
||||||
pos += headerSize;
|
Apu::apu_state_t apuState;
|
||||||
pos += headerSize;
|
blockSize = sizeof(Apu::apu_state_t);
|
||||||
memcpy(&apuState, &buffer[pos], blockSize);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += blockSize;
|
memcpy(&apuState, &buffer[pos], blockSize);
|
||||||
impl->apu.load_state(apuState);
|
pos += blockSize;
|
||||||
impl->apu.end_frame(-(int)nes.timestamp / ppu_overclock);
|
impl->apu.load_state(apuState);
|
||||||
|
impl->apu.end_frame(-(int)nes.timestamp / ppu_overclock);
|
||||||
|
}
|
||||||
|
|
||||||
// CTRL Block
|
// CTRL Block
|
||||||
blockSize = sizeof(joypad_state_t);
|
if (CTRLBlockEnabled == true)
|
||||||
pos += headerSize;
|
{
|
||||||
pos += headerSize;
|
blockSize = sizeof(joypad_state_t);
|
||||||
memcpy((void *)&joypad, &buffer[pos], blockSize);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += blockSize;
|
memcpy((void *)&joypad, &buffer[pos], blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
// MAPR Block
|
// MAPR Block
|
||||||
mapper->default_reset_state();
|
if (MAPRBlockEnabled == true)
|
||||||
blockSize = mapper->state_size;
|
{
|
||||||
pos += headerSize;
|
mapper->default_reset_state();
|
||||||
pos += headerSize;
|
blockSize = mapper->state_size;
|
||||||
memcpy((void *)mapper->state, &buffer[pos], blockSize);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += blockSize;
|
memcpy((void *)mapper->state, &buffer[pos], blockSize);
|
||||||
mapper->apply_mapping();
|
pos += blockSize;
|
||||||
|
mapper->apply_mapping();
|
||||||
|
}
|
||||||
|
|
||||||
// LRAM Block
|
// LRAM Block
|
||||||
blockSize = low_ram_size;
|
if (LRAMBlockEnabled == true)
|
||||||
pos += headerSize;
|
{
|
||||||
pos += headerSize;
|
blockSize = low_ram_size;
|
||||||
memcpy((void *)low_mem, &buffer[pos], blockSize);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += blockSize;
|
memcpy((void *)low_mem, &buffer[pos], blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
// SPRT Block
|
// SPRT Block
|
||||||
blockSize = Ppu::spr_ram_size;
|
if (SPRTBlockEnabled == true)
|
||||||
pos += headerSize;
|
{
|
||||||
pos += headerSize;
|
blockSize = Ppu::spr_ram_size;
|
||||||
memcpy((void *)ppu.spr_ram, &buffer[pos], blockSize);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += blockSize;
|
memcpy((void *)ppu.spr_ram, &buffer[pos], blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
// NTAB Block
|
// NTAB Block
|
||||||
size_t nametable_size = 0x800;
|
if (NTABBlockEnabled == true)
|
||||||
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
|
||||||
blockSize = nametable_size;
|
|
||||||
pos += headerSize;
|
|
||||||
pos += headerSize;
|
|
||||||
memcpy((void *)ppu.impl->nt_ram, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
|
|
||||||
if (ppu.chr_is_writable)
|
|
||||||
{
|
{
|
||||||
// CHRR Block
|
size_t nametable_size = 0x800;
|
||||||
blockSize = ppu.chr_size;
|
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
||||||
pos += headerSize;
|
blockSize = nametable_size;
|
||||||
pos += headerSize;
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
memcpy((void *)ppu.impl->chr_ram, &buffer[pos], blockSize);
|
memcpy((void *)ppu.impl->nt_ram, &buffer[pos], blockSize);
|
||||||
pos += blockSize;
|
pos += blockSize;
|
||||||
ppu.all_tiles_modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sram_present)
|
if (CHRRBlockEnabled == true)
|
||||||
{
|
{
|
||||||
// SRAM Block
|
if (ppu.chr_is_writable)
|
||||||
blockSize = impl->sram_size;
|
{
|
||||||
pos += headerSize;
|
// CHRR Block
|
||||||
pos += headerSize;
|
blockSize = ppu.chr_size;
|
||||||
memcpy((void *)impl->sram, &buffer[pos], blockSize);
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += blockSize;
|
memcpy((void *)ppu.impl->chr_ram, &buffer[pos], blockSize);
|
||||||
enable_sram(true);
|
pos += blockSize;
|
||||||
|
ppu.all_tiles_modified();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SRAMBlockEnabled == true)
|
||||||
|
{
|
||||||
|
if (sram_present)
|
||||||
|
{
|
||||||
|
// SRAM Block
|
||||||
|
blockSize = impl->sram_size;
|
||||||
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
|
memcpy((void *)impl->sram, &buffer[pos], blockSize);
|
||||||
|
pos += blockSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sram_present) enable_sram(true);
|
||||||
|
|
||||||
// headerCode = "gend"; // gend Block
|
// headerCode = "gend"; // gend Block
|
||||||
pos += headerSize;
|
if (HEADBlockEnabled == true) pos += 2 * headerSize;
|
||||||
pos += headerSize;
|
|
||||||
|
|
||||||
return pos; // Bytes read
|
return pos; // Bytes read
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableLiteStateBlock(const std::string& block)
|
void enableStateBlock(const std::string& block)
|
||||||
{
|
{
|
||||||
bool recognizedBlock = false;
|
bool recognizedBlock = false;
|
||||||
|
|
||||||
|
@ -442,12 +558,13 @@ void enableLiteStateBlock(const std::string& block)
|
||||||
if (block == "NTAB") { NTABBlockEnabled = true; recognizedBlock = true; }
|
if (block == "NTAB") { NTABBlockEnabled = true; recognizedBlock = true; }
|
||||||
if (block == "CHRR") { CHRRBlockEnabled = true; recognizedBlock = true; }
|
if (block == "CHRR") { CHRRBlockEnabled = true; recognizedBlock = true; }
|
||||||
if (block == "SRAM") { SRAMBlockEnabled = true; recognizedBlock = true; }
|
if (block == "SRAM") { SRAMBlockEnabled = true; recognizedBlock = true; }
|
||||||
|
if (block == "HEAD") { HEADBlockEnabled = true; recognizedBlock = true; }
|
||||||
|
|
||||||
if (recognizedBlock == false) { fprintf(stderr, "Unrecognized block type: %s\n", block.c_str()); exit(-1);}
|
if (recognizedBlock == false) { fprintf(stderr, "Unrecognized block type: %s\n", block.c_str()); exit(-1);}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void disableLiteStateBlock(const std::string& block)
|
void disableStateBlock(const std::string& block)
|
||||||
{
|
{
|
||||||
bool recognizedBlock = false;
|
bool recognizedBlock = false;
|
||||||
|
|
||||||
|
@ -462,241 +579,12 @@ void disableLiteStateBlock(const std::string& block)
|
||||||
if (block == "NTAB") { NTABBlockEnabled = false; recognizedBlock = true; }
|
if (block == "NTAB") { NTABBlockEnabled = false; recognizedBlock = true; }
|
||||||
if (block == "CHRR") { CHRRBlockEnabled = false; recognizedBlock = true; }
|
if (block == "CHRR") { CHRRBlockEnabled = false; recognizedBlock = true; }
|
||||||
if (block == "SRAM") { SRAMBlockEnabled = false; recognizedBlock = true; }
|
if (block == "SRAM") { SRAMBlockEnabled = false; recognizedBlock = true; }
|
||||||
|
if (block == "HEAD") { HEADBlockEnabled = false; recognizedBlock = true; }
|
||||||
|
|
||||||
if (recognizedBlock == false) { fprintf(stderr, "Unrecognized block type: %s\n", block.c_str()); exit(-1);}
|
if (recognizedBlock == false) { fprintf(stderr, "Unrecognized block type: %s\n", block.c_str()); exit(-1);}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
size_t serializeLiteState(uint8_t *buffer) const
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
uint32_t blockSize = 0;
|
|
||||||
void *dataSource;
|
|
||||||
|
|
||||||
if (TIMEBlockEnabled == true)
|
|
||||||
{
|
|
||||||
nes_state_lite_t state;
|
|
||||||
state.timestamp = nes.timestamp;
|
|
||||||
state.frame_count = (uint8_t)nes.frame_count;
|
|
||||||
state.timestamp *= 5;
|
|
||||||
blockSize = sizeof(nes_state_lite_t);
|
|
||||||
dataSource = (void *)&state;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CPURBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = sizeof(cpu::registers_t);
|
|
||||||
dataSource = (void *)&r;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PPURBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = sizeof(ppu_state_t);
|
|
||||||
dataSource = (void *)&ppu;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (APURBlockEnabled == true)
|
|
||||||
{
|
|
||||||
Apu::apu_state_t apuState;
|
|
||||||
impl->apu.save_state(&apuState);
|
|
||||||
blockSize = sizeof(Apu::apu_state_t);
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], &apuState, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CTRLBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = sizeof(joypad_state_t);
|
|
||||||
dataSource = (void *)&joypad;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MAPRBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = mapper->state_size;
|
|
||||||
dataSource = (void *)mapper->state;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LRAMBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = low_ram_size;
|
|
||||||
dataSource = (void *)low_mem;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SPRTBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = Ppu::spr_ram_size;
|
|
||||||
dataSource = (void *)ppu.spr_ram;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NTABBlockEnabled == true)
|
|
||||||
{
|
|
||||||
size_t nametable_size = 0x800;
|
|
||||||
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
|
||||||
blockSize = nametable_size;
|
|
||||||
dataSource = (void *)ppu.impl->nt_ram;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CHRRBlockEnabled == true)
|
|
||||||
{
|
|
||||||
if (ppu.chr_is_writable)
|
|
||||||
{
|
|
||||||
blockSize = ppu.chr_size;
|
|
||||||
dataSource = (void *)ppu.impl->chr_ram;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SRAMBlockEnabled == true)
|
|
||||||
{
|
|
||||||
if (sram_present)
|
|
||||||
{
|
|
||||||
blockSize = impl->sram_size;
|
|
||||||
dataSource = (void *)impl->sram;
|
|
||||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pos; // Bytes written
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t deserializeLiteState(const uint8_t *buffer)
|
|
||||||
{
|
|
||||||
disable_rendering();
|
|
||||||
error_count = 0;
|
|
||||||
ppu.burst_phase = 0; // avoids shimmer when seeking to same time over and over
|
|
||||||
|
|
||||||
size_t pos = 0;
|
|
||||||
uint32_t blockSize = 0;
|
|
||||||
|
|
||||||
// TIME Block
|
|
||||||
if (TIMEBlockEnabled == true)
|
|
||||||
{
|
|
||||||
nes_state_lite_t nesState;
|
|
||||||
blockSize = sizeof(nes_state_lite_t);
|
|
||||||
memcpy(&nesState, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
nes.frame_count = nesState.frame_count;
|
|
||||||
nes.timestamp = nesState.timestamp;
|
|
||||||
nes.timestamp /= 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CPUR Block
|
|
||||||
if (CPURBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = sizeof(cpu::registers_t);
|
|
||||||
memcpy((void *)&r, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PPUR Block
|
|
||||||
if (PPURBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = sizeof(ppu_state_t);
|
|
||||||
memcpy((void *)&ppu, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// APUR Block
|
|
||||||
if (APURBlockEnabled == true)
|
|
||||||
{
|
|
||||||
Apu::apu_state_t apuState;
|
|
||||||
blockSize = sizeof(Apu::apu_state_t);
|
|
||||||
memcpy(&apuState, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
impl->apu.load_state(apuState);
|
|
||||||
impl->apu.end_frame(-(int)nes.timestamp / ppu_overclock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CTRL Block
|
|
||||||
if (CTRLBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = sizeof(joypad_state_t);
|
|
||||||
memcpy((void *)&joypad, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MAPR Block
|
|
||||||
if (MAPRBlockEnabled == true)
|
|
||||||
{
|
|
||||||
mapper->default_reset_state();
|
|
||||||
blockSize = mapper->state_size;
|
|
||||||
memcpy((void *)mapper->state, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
mapper->apply_mapping();
|
|
||||||
}
|
|
||||||
|
|
||||||
// LRAM Block
|
|
||||||
if (LRAMBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = low_ram_size;
|
|
||||||
memcpy((void *)low_mem, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SPRT Block
|
|
||||||
if (SPRTBlockEnabled == true)
|
|
||||||
{
|
|
||||||
blockSize = Ppu::spr_ram_size;
|
|
||||||
memcpy((void *)ppu.spr_ram, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NTAB Block
|
|
||||||
if (NTABBlockEnabled == true)
|
|
||||||
{
|
|
||||||
size_t nametable_size = 0x800;
|
|
||||||
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
|
||||||
blockSize = nametable_size;
|
|
||||||
memcpy((void *)ppu.impl->nt_ram, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CHRRBlockEnabled == true)
|
|
||||||
{
|
|
||||||
if (ppu.chr_is_writable)
|
|
||||||
{
|
|
||||||
// CHRR Block
|
|
||||||
blockSize = ppu.chr_size;
|
|
||||||
memcpy((void *)ppu.impl->chr_ram, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
ppu.all_tiles_modified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SRAMBlockEnabled == true)
|
|
||||||
{
|
|
||||||
if (sram_present)
|
|
||||||
{
|
|
||||||
// SRAM Block
|
|
||||||
blockSize = impl->sram_size;
|
|
||||||
memcpy((void *)impl->sram, &buffer[pos], blockSize);
|
|
||||||
pos += blockSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sram_present) enable_sram(true);
|
|
||||||
|
|
||||||
return pos; // Bytes read
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset(bool full_reset, bool erase_battery_ram)
|
void reset(bool full_reset, bool erase_battery_ram)
|
||||||
{
|
{
|
||||||
if (full_reset)
|
if (full_reset)
|
||||||
|
|
|
@ -45,17 +45,11 @@ class Emu
|
||||||
const uint8_t *getHostPixels() const { return emu.ppu.host_pixels; }
|
const uint8_t *getHostPixels() const { return emu.ppu.host_pixels; }
|
||||||
|
|
||||||
// Save emulator state variants
|
// Save emulator state variants
|
||||||
size_t serializeFullState(uint8_t *buffer) const { return emu.serializeFullState(buffer); }
|
size_t serializeState(uint8_t *buffer) const { return emu.serializeState(buffer); }
|
||||||
size_t serializeLiteState(uint8_t *buffer) const { return emu.serializeLiteState(buffer); }
|
size_t deserializeState(const uint8_t *buffer) { return emu.deserializeState(buffer); }
|
||||||
|
size_t getStateSize() const { return emu.serializeState(nullptr); }
|
||||||
size_t deserializeFullState(const uint8_t *buffer) { return emu.deserializeFullState(buffer); }
|
void enableStateBlock(const std::string& block) { emu.enableStateBlock(block); };
|
||||||
size_t deserializeLiteState(const uint8_t *buffer) { return emu.deserializeLiteState(buffer); }
|
void disableStateBlock(const std::string& block) { emu.disableStateBlock(block); };
|
||||||
|
|
||||||
size_t getLiteStateSize() const { return emu.serializeLiteState(nullptr); }
|
|
||||||
size_t getFullStateSize() const { return emu.serializeFullState(nullptr); }
|
|
||||||
|
|
||||||
void enableLiteStateBlock(const std::string& block) { emu.enableLiteStateBlock(block); };
|
|
||||||
void disableLiteStateBlock(const std::string& block) { emu.disableLiteStateBlock(block); };
|
|
||||||
|
|
||||||
// Basic emulation
|
// Basic emulation
|
||||||
|
|
||||||
|
|
|
@ -35,17 +35,11 @@ class EmuInstance : public EmuInstanceBase
|
||||||
const uint8_t *getChrMem() const override { return _nes->chr_mem(); };
|
const uint8_t *getChrMem() const override { return _nes->chr_mem(); };
|
||||||
size_t getChrMemSize() const override { return _nes->chr_size(); };
|
size_t getChrMemSize() const override { return _nes->chr_size(); };
|
||||||
|
|
||||||
void serializeFullState(uint8_t *state) const override { _nes->serializeFullState(state); }
|
void serializeState(uint8_t *state) const override { _nes->serializeState(state); }
|
||||||
void deserializeFullState(const uint8_t *state) override { _nes->deserializeFullState(state); }
|
void deserializeState(const uint8_t *state) override { _nes->deserializeState(state); }
|
||||||
|
size_t getStateSize() const override { return _nes->getStateSize(); }
|
||||||
void serializeLiteState(uint8_t *state) const override { _nes->serializeLiteState(state); }
|
void enableStateBlockImpl(const std::string& block) override { _nes->enableStateBlock(block); };
|
||||||
void deserializeLiteState(const uint8_t *state) override { _nes->deserializeLiteState(state); }
|
void disableStateBlockImpl(const std::string& block) override { _nes->disableStateBlock(block); };
|
||||||
|
|
||||||
size_t getFullStateSize() const override { return _nes->getFullStateSize(); }
|
|
||||||
size_t getLiteStateSize() const override { return _nes->getLiteStateSize(); }
|
|
||||||
|
|
||||||
void enableLiteStateBlock(const std::string& block) override { _nes->enableLiteStateBlock(block); };
|
|
||||||
void disableLiteStateBlock(const std::string& block) override { _nes->disableLiteStateBlock(block); };
|
|
||||||
|
|
||||||
void advanceStateImpl(const Controller::port_t controller1, const Controller::port_t controller2) override
|
void advanceStateImpl(const Controller::port_t controller1, const Controller::port_t controller2) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -100,20 +100,20 @@ int main(int argc, char *argv[])
|
||||||
e.setController1Type(controller1Type);
|
e.setController1Type(controller1Type);
|
||||||
e.setController2Type(controller2Type);
|
e.setController2Type(controller2Type);
|
||||||
|
|
||||||
// Disabling requested blocks from light state serialization
|
|
||||||
for (const auto& block : stateDisabledBlocks) e.disableLiteStateBlock(block);
|
|
||||||
|
|
||||||
// Loading ROM File
|
// Loading ROM File
|
||||||
e.loadROMFile(romFilePath);
|
e.loadROMFile(romFilePath);
|
||||||
|
|
||||||
// If an initial state is provided, load it now
|
// If an initial state is provided, load it now
|
||||||
if (initialStateFilePath != "") e.loadStateFile(initialStateFilePath);
|
if (initialStateFilePath != "") e.loadStateFile(initialStateFilePath);
|
||||||
|
|
||||||
|
// Disabling requested blocks from state serialization
|
||||||
|
for (const auto& block : stateDisabledBlocks) e.disableStateBlock(block);
|
||||||
|
|
||||||
// Disable rendering
|
// Disable rendering
|
||||||
e.disableRendering();
|
e.disableRendering();
|
||||||
|
|
||||||
// Getting lite state size
|
// Getting state size
|
||||||
const auto liteStateSize = e.getLiteStateSize();
|
const auto stateSize = e.getStateSize();
|
||||||
|
|
||||||
// Getting actual ROM SHA1
|
// Getting actual ROM SHA1
|
||||||
auto romSHA1 = e.getRomSHA1();
|
auto romSHA1 = e.getRomSHA1();
|
||||||
|
@ -144,14 +144,14 @@ int main(int argc, char *argv[])
|
||||||
//printf("[] ROM SHA1: '%s'\n", romSHA1.c_str());
|
//printf("[] ROM SHA1: '%s'\n", romSHA1.c_str());
|
||||||
printf("[] Sequence File: '%s'\n", sequenceFilePath.c_str());
|
printf("[] Sequence File: '%s'\n", sequenceFilePath.c_str());
|
||||||
printf("[] Sequence Length: %lu\n", sequenceLength);
|
printf("[] Sequence Length: %lu\n", sequenceLength);
|
||||||
printf("[] State Size: %lu bytes - Disabled Blocks: [ %s ]\n", e.getLiteStateSize(), stateDisabledBlocksOutput.c_str());
|
printf("[] State Size: %lu bytes - Disabled Blocks: [ %s ]\n", e.getStateSize(), stateDisabledBlocksOutput.c_str());
|
||||||
printf("[] ********** Running Test **********\n");
|
printf("[] ********** Running Test **********\n");
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// Serializing initial state
|
// Serializing initial state
|
||||||
uint8_t *currentState = (uint8_t *)malloc(liteStateSize);
|
uint8_t *currentState = (uint8_t *)malloc(stateSize);
|
||||||
e.serializeLiteState(currentState);
|
e.serializeState(currentState);
|
||||||
|
|
||||||
// Check whether to perform each action
|
// Check whether to perform each action
|
||||||
bool doPreAdvance = cycleType == "Full";
|
bool doPreAdvance = cycleType == "Full";
|
||||||
|
@ -163,9 +163,9 @@ int main(int argc, char *argv[])
|
||||||
for (const std::string &input : sequence)
|
for (const std::string &input : sequence)
|
||||||
{
|
{
|
||||||
if (doPreAdvance == true) e.advanceState(input);
|
if (doPreAdvance == true) e.advanceState(input);
|
||||||
if (doDeserialize == true) e.deserializeLiteState(currentState);
|
if (doDeserialize == true) e.deserializeState(currentState);
|
||||||
e.advanceState(input);
|
e.advanceState(input);
|
||||||
if (doSerialize == true) e.serializeLiteState(currentState);
|
if (doSerialize == true) e.serializeState(currentState);
|
||||||
}
|
}
|
||||||
auto tf = std::chrono::high_resolution_clock::now();
|
auto tf = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "B2B30C4F30DD853C215C17B0C67CFE63D61A3062",
|
"Expected ROM SHA1": "B2B30C4F30DD853C215C17B0C67CFE63D61A3062",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "arkanoid.warpless.sol",
|
"Sequence File": "arkanoid.warpless.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "MAPR", "CTRL", "APUR" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "MAPR", "CTRL", "APUR" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "B2B30C4F30DD853C215C17B0C67CFE63D61A3062",
|
"Expected ROM SHA1": "B2B30C4F30DD853C215C17B0C67CFE63D61A3062",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "arkanoid.warps.sol",
|
"Sequence File": "arkanoid.warps.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "MAPR", "CTRL", "APUR" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "MAPR", "CTRL", "APUR" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "A31B8BD5B370A9103343C866F3C2B2998E889341",
|
"Expected ROM SHA1": "A31B8BD5B370A9103343C866F3C2B2998E889341",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "castlevania1.anyPercent.sol",
|
"Sequence File": "castlevania1.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "A31B8BD5B370A9103343C866F3C2B2998E889341",
|
"Expected ROM SHA1": "A31B8BD5B370A9103343C866F3C2B2998E889341",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "castlevania1.pacifist.sol",
|
"Sequence File": "castlevania1.pacifist.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "DA54C223D79FA59EB95437854B677CF69B5CAC8A",
|
"Expected ROM SHA1": "DA54C223D79FA59EB95437854B677CF69B5CAC8A",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "galaga.anyPercent.sol",
|
"Sequence File": "galaga.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "97B79E432F62403FB9F877090850C41112A9A168",
|
"Expected ROM SHA1": "97B79E432F62403FB9F877090850C41112A9A168",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "ironSword.anyPercent.sol",
|
"Sequence File": "ironSword.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "ECF39EC5A33E6A6F832F03E8FFC61C5D53F4F90B",
|
"Expected ROM SHA1": "ECF39EC5A33E6A6F832F03E8FFC61C5D53F4F90B",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "metroid.playaround.sol",
|
"Sequence File": "metroid.playaround.sol",
|
||||||
"Disable State Blocks": [ "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "BBE5CF2DFA0B5422776A530D6F1B617238A8569F",
|
"Expected ROM SHA1": "BBE5CF2DFA0B5422776A530D6F1B617238A8569F",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "nigelMansell.anyPercent.sol",
|
"Sequence File": "nigelMansell.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "CA513F841D75EFEB33BB8099FB02BEEB39F6BB9C",
|
"Expected ROM SHA1": "CA513F841D75EFEB33BB8099FB02BEEB39F6BB9C",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "ninjaGaiden.anyPercent.sol",
|
"Sequence File": "ninjaGaiden.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "CA513F841D75EFEB33BB8099FB02BEEB39F6BB9C",
|
"Expected ROM SHA1": "CA513F841D75EFEB33BB8099FB02BEEB39F6BB9C",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "ninjaGaiden.pacifist.sol",
|
"Sequence File": "ninjaGaiden.pacifist.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "B1796660E4A4CEFC72181D4BF4F97999BC048A77",
|
"Expected ROM SHA1": "B1796660E4A4CEFC72181D4BF4F97999BC048A77",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "ninjaGaiden2.anyPercent.sol",
|
"Sequence File": "ninjaGaiden2.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "B1796660E4A4CEFC72181D4BF4F97999BC048A77",
|
"Expected ROM SHA1": "B1796660E4A4CEFC72181D4BF4F97999BC048A77",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "ninjaGaiden2.pacifist.sol",
|
"Sequence File": "ninjaGaiden2.pacifist.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "B6B07EE76492ED475F39167C89B342353F999231",
|
"Expected ROM SHA1": "B6B07EE76492ED475F39167C89B342353F999231",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "novaTheSquirrel.anyPercent.sol",
|
"Sequence File": "novaTheSquirrel.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "6B58F149F34FA829135619C58700CAAA95B9CDE3",
|
"Expected ROM SHA1": "6B58F149F34FA829135619C58700CAAA95B9CDE3",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "princeOfPersia.anyPercent.sol",
|
"Sequence File": "princeOfPersia.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "8C68582BDAA32FBC8C7CD858991D4E00D3B1569C",
|
"Expected ROM SHA1": "8C68582BDAA32FBC8C7CD858991D4E00D3B1569C",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "rcProAmII.race1.sol",
|
"Sequence File": "rcProAmII.race1.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "NTAB", "SPRT", "CTRL", "APUR" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "NTAB", "SPRT", "CTRL", "APUR" ],
|
||||||
"Controller 1 Type": "FourScore1",
|
"Controller 1 Type": "FourScore1",
|
||||||
"Controller 2 Type": "FourScore2"
|
"Controller 2 Type": "FourScore2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "F871D9B3DAFDDCDAD5F2ACD71044292E5169064E",
|
"Expected ROM SHA1": "F871D9B3DAFDDCDAD5F2ACD71044292E5169064E",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "saintSeiyaKanketsuHen.anyPercent.sol",
|
"Sequence File": "saintSeiyaKanketsuHen.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "3F3B499CF50386084E053BCA096AE8E52330CFAE",
|
"Expected ROM SHA1": "3F3B499CF50386084E053BCA096AE8E52330CFAE",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "saintSeiyaKanketsuHen.anyPercent.sol",
|
"Sequence File": "saintSeiyaKanketsuHen.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "C2F12D915A4D0B1FFDF8A64AE1092CE6A2D08770",
|
"Expected ROM SHA1": "C2F12D915A4D0B1FFDF8A64AE1092CE6A2D08770",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "saiyuukiWorld.anyPercent.sol",
|
"Sequence File": "saiyuukiWorld.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "C2F12D915A4D0B1FFDF8A64AE1092CE6A2D08770",
|
"Expected ROM SHA1": "C2F12D915A4D0B1FFDF8A64AE1092CE6A2D08770",
|
||||||
"Initial State File": "saiyuukiWorld.lastHalf.state",
|
"Initial State File": "saiyuukiWorld.lastHalf.state",
|
||||||
"Sequence File": "saiyuukiWorld.lastHalf.sol",
|
"Sequence File": "saiyuukiWorld.lastHalf.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"Expected ROM SHA1": "872B91A2F7A2F635061EF43F79E7F7E9F59F5C50",
|
"Expected ROM SHA1": "872B91A2F7A2F635061EF43F79E7F7E9F59F5C50",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "solarJetman.anyPercent.sol",
|
"Sequence File": "solarJetman.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "6EC09B9B51320A536A786D3D4719432B714C5779",
|
"Expected ROM SHA1": "6EC09B9B51320A536A786D3D4719432B714C5779",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "sprilo.anyPercent.sol",
|
"Sequence File": "sprilo.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "EA343F4E445A9050D4B4FBAC2C77D0693B1D0922",
|
"Expected ROM SHA1": "EA343F4E445A9050D4B4FBAC2C77D0693B1D0922",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "superMarioBros.warpless.sol",
|
"Sequence File": "superMarioBros.warpless.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "EA343F4E445A9050D4B4FBAC2C77D0693B1D0922",
|
"Expected ROM SHA1": "EA343F4E445A9050D4B4FBAC2C77D0693B1D0922",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "superMarioBros.warps.sol",
|
"Sequence File": "superMarioBros.warps.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "A03E7E526E79DF222E048AE22214BCA2BC49C449",
|
"Expected ROM SHA1": "A03E7E526E79DF222E048AE22214BCA2BC49C449",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "superMarioBros3.warps.sol",
|
"Sequence File": "superMarioBros3.warps.sol",
|
||||||
"Disable State Blocks": [ "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "57919B685B55EE3ED3AD98FB1D25626B98BE7D39",
|
"Expected ROM SHA1": "57919B685B55EE3ED3AD98FB1D25626B98BE7D39",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "superOffroad.anyPercent.sol",
|
"Sequence File": "superOffroad.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "Joypad"
|
"Controller 2 Type": "Joypad"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"Expected ROM SHA1": "80D99C035E6A5AB9718E413EC25CBE094F085962",
|
"Expected ROM SHA1": "80D99C035E6A5AB9718E413EC25CBE094F085962",
|
||||||
"Initial State File": "",
|
"Initial State File": "",
|
||||||
"Sequence File": "tennis.anyPercent.sol",
|
"Sequence File": "tennis.anyPercent.sol",
|
||||||
"Disable State Blocks": [ "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
"Disable State Blocks": [ "HEAD", "SRAM", "CHRR", "NTAB", "SPRT", "CTRL" ],
|
||||||
"Controller 1 Type": "Joypad",
|
"Controller 1 Type": "Joypad",
|
||||||
"Controller 2 Type": "None"
|
"Controller 2 Type": "None"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue