Differentiating full & lite state classes
This commit is contained in:
parent
0883f5f4da
commit
5a99f2749a
|
@ -64,38 +64,14 @@ class EmuInstance
|
|||
std::string moveString = "|..|........|";
|
||||
#endif
|
||||
|
||||
if (move & 0b00010000)
|
||||
moveString += 'U';
|
||||
else
|
||||
moveString += '.';
|
||||
if (move & 0b00100000)
|
||||
moveString += 'D';
|
||||
else
|
||||
moveString += '.';
|
||||
if (move & 0b01000000)
|
||||
moveString += 'L';
|
||||
else
|
||||
moveString += '.';
|
||||
if (move & 0b10000000)
|
||||
moveString += 'R';
|
||||
else
|
||||
moveString += '.';
|
||||
if (move & 0b00001000)
|
||||
moveString += 'S';
|
||||
else
|
||||
moveString += '.';
|
||||
if (move & 0b00000100)
|
||||
moveString += 's';
|
||||
else
|
||||
moveString += '.';
|
||||
if (move & 0b00000010)
|
||||
moveString += 'B';
|
||||
else
|
||||
moveString += '.';
|
||||
if (move & 0b00000001)
|
||||
moveString += 'A';
|
||||
else
|
||||
moveString += '.';
|
||||
if (move & 0b00010000) moveString += 'U'; else moveString += '.';
|
||||
if (move & 0b00100000) moveString += 'D'; else moveString += '.';
|
||||
if (move & 0b01000000) moveString += 'L'; else moveString += '.';
|
||||
if (move & 0b10000000) moveString += 'R'; else moveString += '.';
|
||||
if (move & 0b00001000) moveString += 'S'; else moveString += '.';
|
||||
if (move & 0b00000100) moveString += 's'; else moveString += '.';
|
||||
if (move & 0b00000010) moveString += 'B'; else moveString += '.';
|
||||
if (move & 0b00000001) moveString += 'A'; else moveString += '.';
|
||||
|
||||
moveString += "|";
|
||||
return moveString;
|
||||
|
@ -108,8 +84,6 @@ class EmuInstance
|
|||
advanceStateImpl(moveStringToCode(move), 0);
|
||||
}
|
||||
|
||||
inline size_t getStateSize() const { return _stateSize; }
|
||||
inline size_t getLiteStateSize() const { return _liteStateSize; }
|
||||
inline std::string getRomSHA1() const { return _romSHA1String; }
|
||||
|
||||
inline hash_t getStateHash() const
|
||||
|
@ -134,14 +108,14 @@ class EmuInstance
|
|||
std::string stateData;
|
||||
bool status = loadStringFromFile(stateData, stateFilePath);
|
||||
if (status == false) EXIT_WITH_ERROR("Could not find/read state file: %s\n", stateFilePath.c_str());
|
||||
deserializeState((uint8_t *)stateData.data());
|
||||
deserializeFullState((uint8_t *)stateData.data());
|
||||
}
|
||||
|
||||
inline void saveStateFile(const std::string &stateFilePath) const
|
||||
{
|
||||
std::string stateData;
|
||||
stateData.resize(_stateSize);
|
||||
serializeState((uint8_t *)stateData.data());
|
||||
stateData.resize(_fullStateSize);
|
||||
serializeFullState((uint8_t *)stateData.data());
|
||||
saveStringToFile(stateData, stateFilePath.c_str());
|
||||
}
|
||||
|
||||
|
@ -159,10 +133,10 @@ class EmuInstance
|
|||
if (status == false) EXIT_WITH_ERROR("Could not process ROM file: %s\n", romFilePath.c_str());
|
||||
|
||||
// Detecting full state size
|
||||
_stateSize = getStateSizeImpl();
|
||||
_fullStateSize = getFullStateSize();
|
||||
|
||||
// Detecting lite state size
|
||||
_liteStateSize = getLiteStateSizeImpl();
|
||||
_liteStateSize = getLiteStateSize();
|
||||
}
|
||||
|
||||
// Virtual functions
|
||||
|
@ -174,10 +148,12 @@ class EmuInstance
|
|||
virtual uint8_t *getHighMem() const = 0;
|
||||
virtual const uint8_t *getChrMem() const = 0;
|
||||
virtual size_t getChrMemSize() const = 0;
|
||||
virtual void serializeState(uint8_t *state) const = 0;
|
||||
virtual void deserializeState(const uint8_t *state) = 0;
|
||||
virtual size_t getStateSizeImpl() const = 0;
|
||||
virtual size_t getLiteStateSizeImpl() const { return getStateSizeImpl(); };
|
||||
virtual void serializeFullState(uint8_t *state) const = 0;
|
||||
virtual void deserializeFullState(const uint8_t *state) = 0;
|
||||
virtual void serializeLiteState(uint8_t *state) const = 0;
|
||||
virtual void deserializeLiteState(const uint8_t *state) = 0;
|
||||
virtual size_t getFullStateSize() const = 0;
|
||||
virtual size_t getLiteStateSize() const = 0;
|
||||
virtual void doSoftReset() = 0;
|
||||
virtual void doHardReset() = 0;
|
||||
virtual std::string getCoreName() const = 0;
|
||||
|
@ -190,7 +166,7 @@ class EmuInstance
|
|||
size_t _liteStateSize;
|
||||
|
||||
// Storage for the full state size
|
||||
size_t _stateSize;
|
||||
size_t _fullStateSize;
|
||||
|
||||
// Flag to determine whether to enable/disable rendering
|
||||
bool _doRendering = true;
|
||||
|
|
|
@ -29,13 +29,16 @@ struct stepData_t
|
|||
|
||||
class PlaybackInstance
|
||||
{
|
||||
static const uint16_t image_width = 256;
|
||||
static const uint16_t image_height = 240;
|
||||
|
||||
public:
|
||||
void addStep(const std::string &input)
|
||||
{
|
||||
stepData_t step;
|
||||
step.input = input;
|
||||
step.stateData = (uint8_t *)malloc(_emu->getStateSize());
|
||||
_emu->serializeState(step.stateData);
|
||||
step.stateData = (uint8_t *)malloc(_emu->getFullStateSize());
|
||||
_emu->serializeFullState(step.stateData);
|
||||
step.hash = _emu->getStateHash();
|
||||
|
||||
// Adding the step into the sequence
|
||||
|
@ -50,8 +53,8 @@ class PlaybackInstance
|
|||
|
||||
// Loading Emulator instance HQN
|
||||
_hqnState.setEmulatorPointer(_emu->getInternalEmulatorPointer());
|
||||
static uint8_t video_buffer[emulator_t::image_width * emulator_t::image_height];
|
||||
_hqnState.m_emu->set_pixels(video_buffer, emulator_t::image_width + 8);
|
||||
static uint8_t video_buffer[image_width * image_height];
|
||||
_hqnState.m_emu->set_pixels(video_buffer, image_width + 8);
|
||||
|
||||
// Building sequence information
|
||||
for (const auto &input : sequence)
|
||||
|
@ -166,7 +169,7 @@ class PlaybackInstance
|
|||
if (stepId > 0)
|
||||
{
|
||||
const auto stateData = getStateData(stepId - 1);
|
||||
_emu->deserializeState(stateData);
|
||||
_emu->deserializeFullState(stateData);
|
||||
_emu->advanceState(getStateInput(stepId - 1));
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ int main(int argc, char *argv[])
|
|||
auto p = PlaybackInstance(&e, sequence);
|
||||
|
||||
// Getting state size
|
||||
auto stateSize = e.getStateSize();
|
||||
auto stateSize = e.getFullStateSize();
|
||||
|
||||
// Flag to continue running playback
|
||||
bool continueRunning = true;
|
||||
|
|
|
@ -45,20 +45,34 @@ class QuickNESInstance : public EmuInstance
|
|||
const uint8_t *getChrMem() const override { return _nes->chr_mem(); };
|
||||
size_t getChrMemSize() const override { return _nes->chr_size(); };
|
||||
|
||||
void serializeState(uint8_t *state) const override
|
||||
void serializeLiteState(uint8_t *state) const override { serializeFullState(state); }
|
||||
void deserializeLiteState(const uint8_t *state) override { deserializeFullState(state); }
|
||||
inline size_t getLiteStateSize() const override { return getFullStateSize(); }
|
||||
|
||||
void serializeFullState(uint8_t *state) const override
|
||||
{
|
||||
Mem_Writer w(state, _stateSize, 0);
|
||||
Mem_Writer w(state, _fullStateSize, 0);
|
||||
Auto_File_Writer a(w);
|
||||
_nes->save_state(a);
|
||||
}
|
||||
|
||||
void deserializeState(const uint8_t *state) override
|
||||
void deserializeFullState(const uint8_t *state) override
|
||||
{
|
||||
Mem_File_Reader r(state, _stateSize);
|
||||
Mem_File_Reader r(state, _fullStateSize);
|
||||
Auto_File_Reader a(r);
|
||||
_nes->load_state(a);
|
||||
}
|
||||
|
||||
inline size_t getFullStateSize() const override
|
||||
{
|
||||
uint8_t *data = (uint8_t *)malloc(_DUMMY_SIZE);
|
||||
Mem_Writer w(data, _DUMMY_SIZE);
|
||||
Auto_File_Writer a(w);
|
||||
_nes->save_state(a);
|
||||
free(data);
|
||||
return w.size();
|
||||
}
|
||||
|
||||
void advanceStateImpl(const inputType controller1, const inputType controller2) override
|
||||
{
|
||||
if (_doRendering == true) _nes->emulate_frame(controller1, controller2);
|
||||
|
@ -72,15 +86,6 @@ class QuickNESInstance : public EmuInstance
|
|||
void *getInternalEmulatorPointer() const override { return _nes; }
|
||||
|
||||
private:
|
||||
inline size_t getStateSizeImpl() const override
|
||||
{
|
||||
uint8_t *data = (uint8_t *)malloc(_DUMMY_SIZE);
|
||||
Mem_Writer w(data, _DUMMY_SIZE);
|
||||
Auto_File_Writer a(w);
|
||||
_nes->save_state(a);
|
||||
free(data);
|
||||
return w.size();
|
||||
}
|
||||
|
||||
// Video buffer
|
||||
uint8_t *video_buffer;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
// Blip_Buffer 0.4.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Blip_Buffer.hpp"
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "blipBuffer.hpp"
|
||||
|
||||
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
|
@ -3,8 +3,8 @@
|
|||
// NES non-linear audio buffer
|
||||
// Emu 0.7.0
|
||||
|
||||
#include "Multi_Buffer.hpp"
|
||||
#include <cstdint>
|
||||
#include "multiBuffer.hpp"
|
||||
|
||||
namespace quickerNES
|
||||
{
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
// Multi-channel effects buffer with panning, echo and reverb
|
||||
// Game_Music_Emu 0.3.0
|
||||
|
||||
#include "Multi_Buffer.hpp"
|
||||
#include <stdint.h>
|
||||
#include "multiBuffer.hpp"
|
||||
|
||||
namespace quickerNES
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Emu 0.7.0
|
||||
|
||||
#include <cstdint>
|
||||
#include "apu/Blip_Buffer.hpp"
|
||||
#include "apu/blipBuffer.hpp"
|
||||
|
||||
namespace quickerNES
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
// Blip_Buffer 0.4.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Multi_Buffer.hpp"
|
||||
#include <cstdint>
|
||||
#include "multiBuffer.hpp"
|
||||
|
||||
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
|
@ -4,7 +4,7 @@
|
|||
// Multi-channel sound buffer interface, and basic mono and stereo buffers
|
||||
// Blip_Buffer 0.4.0
|
||||
|
||||
#include "Blip_Buffer.hpp"
|
||||
#include "blipBuffer.hpp"
|
||||
|
||||
namespace quickerNES
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
// Snd_Emu 0.1.7. http://www.slack.net/~ant/
|
||||
|
||||
#include "apu/namco/apu.hpp"
|
||||
#include "apu/Blip_Buffer.hpp"
|
||||
#include "apu/blipBuffer.hpp"
|
||||
|
||||
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Private oscillators used by Apu
|
||||
// Snd_Emu 0.1.7
|
||||
|
||||
#include "Blip_Buffer.hpp"
|
||||
#include "blipBuffer.hpp"
|
||||
|
||||
namespace quickerNES
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// Snd_Emu 0.1.7
|
||||
|
||||
#include <cstdint>
|
||||
#include "apu/Blip_Buffer.hpp"
|
||||
#include "apu/blipBuffer.hpp"
|
||||
#include "apu/apu.hpp"
|
||||
|
||||
namespace quickerNES
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// Snd_Emu 0.1.7. Copyright (C) 2003-2005 Shay Green. GNU LGPL license.
|
||||
|
||||
#include <cstdint>
|
||||
#include "apu/Blip_Buffer.hpp"
|
||||
#include "apu/blipBuffer.hpp"
|
||||
#include "apu/vrc7/emu2413_state.hpp"
|
||||
|
||||
namespace quickerNES
|
||||
|
|
|
@ -129,93 +129,7 @@ class Core : private Cpu
|
|||
reset(true, true);
|
||||
}
|
||||
|
||||
size_t getLiteStateSize() const
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
size += sizeof(nes_state_t);
|
||||
size += sizeof(registers_t);
|
||||
size += sizeof(ppu_state_t);
|
||||
size += sizeof(Apu::apu_state_t);
|
||||
size += sizeof(joypad_state_t);
|
||||
size += mapper->state_size;
|
||||
size += low_ram_size;
|
||||
size += Ppu::spr_ram_size;
|
||||
size_t nametable_size = 0x800;
|
||||
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
||||
size += nametable_size;
|
||||
if (ppu.chr_is_writable) size += ppu.chr_size;
|
||||
if (sram_present) size += impl->sram_size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t getStateSize() const
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
size += sizeof(char[4]); // NESS Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
|
||||
size += sizeof(char[4]); // TIME Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += sizeof(nes_state_t);
|
||||
|
||||
size += sizeof(char[4]); // CPUR Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += sizeof(registers_t);
|
||||
|
||||
size += sizeof(char[4]); // PPUR Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += sizeof(ppu_state_t);
|
||||
|
||||
size += sizeof(char[4]); // APUR Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += sizeof(Apu::apu_state_t);
|
||||
|
||||
size += sizeof(char[4]); // CTRL Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += sizeof(joypad_state_t);
|
||||
|
||||
size += sizeof(char[4]); // MAPR Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += mapper->state_size;
|
||||
|
||||
size += sizeof(char[4]); // LRAM Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += low_ram_size;
|
||||
|
||||
size += sizeof(char[4]); // SPRT Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += Ppu::spr_ram_size;
|
||||
|
||||
size += sizeof(char[4]); // NTAB Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size_t nametable_size = 0x800;
|
||||
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
||||
size += nametable_size;
|
||||
|
||||
if (ppu.chr_is_writable)
|
||||
{
|
||||
size += sizeof(char[4]); // CHRR Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += ppu.chr_size;
|
||||
}
|
||||
|
||||
if (sram_present)
|
||||
{
|
||||
size += sizeof(char[4]); // SRAM Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
size += impl->sram_size;
|
||||
}
|
||||
|
||||
size += sizeof(char[4]); // gend Block
|
||||
size += sizeof(uint32_t); // Block Size
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t serializeState(uint8_t *buffer) const
|
||||
size_t serializeFullState(uint8_t *buffer) const
|
||||
{
|
||||
size_t pos = 0;
|
||||
std::string headerCode;
|
||||
|
@ -225,9 +139,9 @@ class Core : private Cpu
|
|||
|
||||
headerCode = "NESS"; // NESS Block
|
||||
blockSize = 0xFFFFFFFF;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
|
||||
headerCode = "TIME"; // TIME Block
|
||||
|
@ -235,11 +149,11 @@ class Core : private Cpu
|
|||
state.timestamp *= 5;
|
||||
blockSize = sizeof(nes_state_t);
|
||||
dataSource = (void *)&state;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
headerCode = "CPUR"; // CPUR Block
|
||||
|
@ -253,72 +167,72 @@ class Core : private Cpu
|
|||
s.p = r.status;
|
||||
blockSize = sizeof(cpu_state_t);
|
||||
dataSource = (void *)&s;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
headerCode = "PPUR"; // PPUR Block
|
||||
blockSize = sizeof(ppu_state_t);
|
||||
dataSource = (void *)&ppu;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
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);
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &apuState, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &apuState, blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
headerCode = "CTRL"; // CTRL Block
|
||||
blockSize = sizeof(joypad_state_t);
|
||||
dataSource = (void *)&joypad;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
headerCode = "MAPR"; // MAPR Block
|
||||
blockSize = mapper->state_size;
|
||||
dataSource = (void *)mapper->state;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
headerCode = "LRAM"; // LRAM Block
|
||||
blockSize = low_ram_size;
|
||||
dataSource = (void *)low_mem;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
headerCode = "SPRT"; // SPRT Block
|
||||
blockSize = Ppu::spr_ram_size;
|
||||
dataSource = (void *)ppu.spr_ram;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
headerCode = "NTAB"; // NTAB Block
|
||||
|
@ -326,11 +240,11 @@ class Core : private Cpu
|
|||
if (ppu.nt_banks[3] >= &ppu.impl->nt_ram[0xC00]) nametable_size = 0x1000;
|
||||
blockSize = nametable_size;
|
||||
dataSource = (void *)ppu.impl->nt_ram;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
if (ppu.chr_is_writable)
|
||||
|
@ -338,11 +252,11 @@ class Core : private Cpu
|
|||
headerCode = "CHRR"; // CHRR Block
|
||||
blockSize = ppu.chr_size;
|
||||
dataSource = (void *)ppu.impl->chr_ram;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
}
|
||||
|
||||
|
@ -351,25 +265,301 @@ class Core : private Cpu
|
|||
headerCode = "SRAM"; // SRAM Block
|
||||
blockSize = impl->sram_size;
|
||||
dataSource = (void *)impl->sram;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], dataSource, blockSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], dataSource, blockSize);
|
||||
pos += blockSize;
|
||||
}
|
||||
|
||||
headerCode = "gend"; // gend Block
|
||||
blockSize = 0;
|
||||
memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
pos += headerSize;
|
||||
memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], &blockSize, headerSize);
|
||||
pos += headerSize;
|
||||
|
||||
return pos; // Bytes written
|
||||
}
|
||||
|
||||
size_t deserializeState(const uint8_t *buffer)
|
||||
size_t deserializeFullState(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;
|
||||
const uint32_t headerSize = sizeof(char) * 4;
|
||||
uint32_t blockSize = 0;
|
||||
|
||||
// NESS Block
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
|
||||
// TIME Block
|
||||
nes_state_t nesState;
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
blockSize = sizeof(nes_state_t);
|
||||
memcpy(&nesState, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
nes = nesState;
|
||||
nes.timestamp /= 5;
|
||||
|
||||
// CPUR Block
|
||||
cpu_state_t s;
|
||||
blockSize = sizeof(cpu_state_t);
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy((void *)&s, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
r.pc = s.pc;
|
||||
r.sp = s.s;
|
||||
r.a = s.a;
|
||||
r.x = s.x;
|
||||
r.y = s.y;
|
||||
r.status = s.p;
|
||||
|
||||
// PPUR Block
|
||||
blockSize = sizeof(ppu_state_t);
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy((void *)&ppu, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
// APUR Block
|
||||
Apu::apu_state_t apuState;
|
||||
blockSize = sizeof(Apu::apu_state_t);
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy(&apuState, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
impl->apu.load_state(apuState);
|
||||
impl->apu.end_frame(-(int)nes.timestamp / ppu_overclock);
|
||||
|
||||
// CTRL Block
|
||||
blockSize = sizeof(joypad_state_t);
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy((void *)&joypad, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
// MAPR Block
|
||||
mapper->default_reset_state();
|
||||
blockSize = mapper->state_size;
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy((void *)mapper->state, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
mapper->apply_mapping();
|
||||
|
||||
// LRAM Block
|
||||
blockSize = low_ram_size;
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy((void *)low_mem, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
// SPRT Block
|
||||
blockSize = Ppu::spr_ram_size;
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy((void *)ppu.spr_ram, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
|
||||
// NTAB Block
|
||||
size_t nametable_size = 0x800;
|
||||
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
|
||||
blockSize = ppu.chr_size;
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy((void *)ppu.impl->chr_ram, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
}
|
||||
|
||||
if (sram_present)
|
||||
{
|
||||
// SRAM Block
|
||||
blockSize = impl->sram_size;
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
memcpy((void *)impl->sram, &buffer[pos], blockSize);
|
||||
pos += blockSize;
|
||||
enable_sram(true);
|
||||
}
|
||||
|
||||
// headerCode = "gend"; // gend Block
|
||||
pos += headerSize;
|
||||
pos += headerSize;
|
||||
|
||||
return pos; // Bytes read
|
||||
}
|
||||
|
||||
size_t serializeLiteState(uint8_t *buffer) const
|
||||
{
|
||||
size_t pos = 0;
|
||||
std::string headerCode;
|
||||
const uint32_t headerSize = sizeof(char) * 4;
|
||||
uint32_t blockSize = 0;
|
||||
void *dataSource;
|
||||
|
||||
headerCode = "NESS"; // NESS Block
|
||||
blockSize = 0xFFFFFFFF;
|
||||
if (buffer != nullptr) memcpy(&buffer[pos], headerCode.data(), headerSize);
|
||||
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
|
||||
blockSize = ppu.chr_size;
|
||||
dataSource = (void *)ppu.impl->chr_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 (sram_present)
|
||||
{
|
||||
headerCode = "SRAM"; // SRAM Block
|
||||
blockSize = impl->sram_size;
|
||||
dataSource = (void *)impl->sram;
|
||||
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 = "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
|
||||
}
|
||||
|
||||
size_t deserializeLiteState(const uint8_t *buffer)
|
||||
{
|
||||
disable_rendering();
|
||||
error_count = 0;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cart.hpp"
|
||||
#include "core.hpp"
|
||||
#include "apu/Multi_Buffer.hpp"
|
||||
#include "apu/multiBuffer.hpp"
|
||||
|
||||
namespace quickerNES
|
||||
{
|
||||
|
@ -44,8 +44,15 @@ class Emu
|
|||
|
||||
const uint8_t *getHostPixels() const { return emu.ppu.host_pixels; }
|
||||
|
||||
size_t getLiteStateSize() const { return emu.getLiteStateSize(); }
|
||||
size_t getStateSize() const { return emu.getStateSize(); }
|
||||
// Save emulator state variants
|
||||
size_t serializeFullState(uint8_t *buffer) const { return emu.serializeFullState(buffer); }
|
||||
size_t serializeLiteState(uint8_t *buffer) const { return emu.serializeLiteState(buffer); }
|
||||
|
||||
size_t deserializeFullState(const uint8_t *buffer) { return emu.deserializeFullState(buffer); }
|
||||
size_t deserializeLiteState(const uint8_t *buffer) { return emu.deserializeLiteState(buffer); }
|
||||
|
||||
size_t getLiteStateSize() const { return emu.serializeLiteState(nullptr); }
|
||||
size_t getFullStateSize() const { return emu.serializeFullState(nullptr); }
|
||||
|
||||
// Basic emulation
|
||||
|
||||
|
@ -141,10 +148,6 @@ class Emu
|
|||
|
||||
// File save/load
|
||||
|
||||
// Save emulator state
|
||||
size_t serializeState(uint8_t *buffer) const { return emu.serializeState(buffer); }
|
||||
size_t deserializeState(const uint8_t *buffer) { return emu.deserializeState(buffer); }
|
||||
|
||||
// True if current cartridge claims it uses battery-backed memory
|
||||
bool has_battery_ram() const { return cart()->has_battery_ram(); }
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ quickerNESAPUSrc = [
|
|||
'apu/apu.cpp',
|
||||
'apu/oscs.cpp',
|
||||
'apu/buffer.cpp',
|
||||
'apu/Blip_Buffer.cpp',
|
||||
'apu/blipBuffer.cpp',
|
||||
'apu/NESEffectsBuffer.cpp',
|
||||
'apu/effectsBuffer.cpp',
|
||||
'apu/Multi_Buffer.cpp',
|
||||
'apu/multiBuffer.cpp',
|
||||
'apu/namco/apu.cpp',
|
||||
'apu/vrc6/apu.cpp',
|
||||
'apu/vrc7/emu2413.cpp',
|
||||
|
|
|
@ -36,15 +36,14 @@ class QuickerNESInstance : public EmuInstance
|
|||
const uint8_t *getChrMem() const override { return _nes->chr_mem(); };
|
||||
size_t getChrMemSize() const override { return _nes->chr_size(); };
|
||||
|
||||
void serializeState(uint8_t *state) const override
|
||||
{
|
||||
_nes->serializeState(state);
|
||||
}
|
||||
void serializeFullState(uint8_t *state) const override { _nes->serializeFullState(state); }
|
||||
void deserializeFullState(const uint8_t *state) override { _nes->deserializeFullState(state); }
|
||||
|
||||
void deserializeState(const uint8_t *state) override
|
||||
{
|
||||
_nes->deserializeState(state);
|
||||
}
|
||||
void serializeLiteState(uint8_t *state) const override { _nes->serializeLiteState(state); }
|
||||
void deserializeLiteState(const uint8_t *state) override { _nes->deserializeLiteState(state); }
|
||||
|
||||
size_t getFullStateSize() const override { return _nes->getFullStateSize(); }
|
||||
size_t getLiteStateSize() const override { return _nes->getLiteStateSize(); }
|
||||
|
||||
void advanceStateImpl(const inputType controller1, const inputType controller2) override
|
||||
{
|
||||
|
@ -58,17 +57,6 @@ class QuickerNESInstance : public EmuInstance
|
|||
|
||||
void *getInternalEmulatorPointer() const override { return _nes; }
|
||||
|
||||
private:
|
||||
inline size_t getStateSizeImpl() const override
|
||||
{
|
||||
return _nes->getStateSize();
|
||||
}
|
||||
|
||||
inline size_t getLiteStateSizeImpl() const override
|
||||
{
|
||||
return _nes->getLiteStateSize();
|
||||
}
|
||||
|
||||
// Video buffer
|
||||
uint8_t *video_buffer;
|
||||
|
||||
|
|
|
@ -76,14 +76,14 @@ int main(int argc, char *argv[])
|
|||
if (scriptJson["Expected ROM SHA1"].is_string() == false) EXIT_WITH_ERROR("Script file 'Expected ROM SHA1' entry is not a string\n");
|
||||
std::string expectedROMSHA1 = scriptJson["Expected ROM SHA1"].get<std::string>();
|
||||
|
||||
// Creating emulator instance
|
||||
#ifdef _USE_QUICKNES
|
||||
// Creating emulator instance
|
||||
#ifdef _USE_QUICKNES
|
||||
auto e = QuickNESInstance();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _USE_QUICKERNES
|
||||
#ifdef _USE_QUICKERNES
|
||||
auto e = quickerNES::QuickerNESInstance();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Loading ROM File
|
||||
e.loadROMFile(romFilePath);
|
||||
|
@ -98,7 +98,7 @@ int main(int argc, char *argv[])
|
|||
auto initialHash = e.getStateHash();
|
||||
|
||||
// Getting full state size
|
||||
const auto stateSize = e.getStateSize();
|
||||
const auto fullStateSize = e.getFullStateSize();
|
||||
|
||||
// Getting lite state size
|
||||
const auto liteStateSize = e.getLiteStateSize();
|
||||
|
@ -132,15 +132,15 @@ int main(int argc, char *argv[])
|
|||
printf("[] Sequence File: '%s'\n", sequenceFilePath.c_str());
|
||||
printf("[] Sequence Length: %lu\n", sequenceLength);
|
||||
printf("[] Initial State Hash: 0x%lX%lX\n", initialHash.first, initialHash.second);
|
||||
printf("[] Full State Size: %lu bytes\n", stateSize);
|
||||
printf("[] Full State Size: %lu bytes\n", fullStateSize);
|
||||
printf("[] Lite State Size: %lu bytes\n", liteStateSize);
|
||||
printf("[] ********** Running Test **********\n");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
// Serializing initial state
|
||||
uint8_t *currentState = (uint8_t *)malloc(stateSize);
|
||||
e.serializeState(currentState);
|
||||
uint8_t *currentState = (uint8_t *)malloc(liteStateSize);
|
||||
e.serializeLiteState(currentState);
|
||||
|
||||
// Check whether to perform each action
|
||||
bool doPreAdvance = cycleType == "Full";
|
||||
|
@ -152,9 +152,9 @@ int main(int argc, char *argv[])
|
|||
for (const std::string &input : sequence)
|
||||
{
|
||||
if (doPreAdvance == true) e.advanceState(input);
|
||||
if (doDeserialize == true) e.deserializeState(currentState);
|
||||
if (doDeserialize == true) e.deserializeLiteState(currentState);
|
||||
e.advanceState(input);
|
||||
if (doSerialize == true) e.serializeState(currentState);
|
||||
if (doSerialize == true) e.serializeLiteState(currentState);
|
||||
}
|
||||
auto tf = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
|
Loading…
Reference in New Issue