Using encapsulated serializators now

This commit is contained in:
Sergio Martin 2024-02-09 20:43:42 +01:00
parent 877d7a4052
commit 944046a78a
10 changed files with 143 additions and 240 deletions

2
extern/jaffarCommon vendored

@ -1 +1 @@
Subproject commit f15d231ead67f064ff6dc3b1aad07b20da088dab
Subproject commit 900e829a650eff802db4423b89023fa4d1b545b9

View File

@ -1,5 +1,7 @@
#pragma once
#include "jaffarCommon/include/serializers/contiguous.hpp"
#include "jaffarCommon/include/serializers/differential.hpp"
#include "jaffarCommon/include/logger.hpp"
#include "controller.hpp"
@ -65,7 +67,7 @@ class NESInstanceBase
auto status = loadROMImpl(romData, romSize);
// Detecting full state size
_stateSize = getStateSize();
_stateSize = getFullStateSize();
// Returning status
return status;
@ -77,7 +79,7 @@ class NESInstanceBase
enableStateBlockImpl(block);
// Recalculating State size
_stateSize = getStateSize();
_stateSize = getFullStateSize();
}
void disableStateBlock(const std::string& block)
@ -86,37 +88,19 @@ class NESInstanceBase
disableStateBlockImpl(block);
// Recalculating State Size
_stateSize = getStateSize();
_stateSize = getFullStateSize();
}
virtual size_t getFullStateSize() const = 0;
virtual size_t getDifferentialStateSize() const = 0;
// Virtual functions
virtual uint8_t *getLowMem() const = 0;
virtual size_t getLowMemSize() const = 0;
virtual void serializeState(uint8_t *state) const = 0;
virtual void deserializeState(const uint8_t *state) = 0;
virtual size_t getStateSize() const = 0;
virtual void serializeDifferentialState(
uint8_t *outputData,
size_t* outputDataPos,
const size_t outputDataMaxSize,
const uint8_t* referenceData,
size_t* referenceDataPos,
const size_t referenceDataMaxSize,
const bool useZlib) const = 0;
virtual void deserializeDifferentialState(
const uint8_t *inputData,
size_t* inputDataPos,
const size_t inputDataMaxSize,
const uint8_t* referenceData,
size_t* referenceDataPos,
const size_t referenceDataMaxSize,
const bool useZlib) = 0;
virtual size_t getDifferentialStateSize() const = 0;
virtual void serializeState(jaffarCommon::serializer::Base& serializer) const = 0;
virtual void deserializeState(jaffarCommon::deserializer::Base& deserializer) = 0;
virtual void doSoftReset() = 0;
virtual void doHardReset() = 0;

View File

@ -6,6 +6,8 @@
#include <SDL_image.h>
#include <hqn/hqn.h>
#include <hqn/hqn_gui_controller.h>
#include <jaffarCommon/include/serializers/contiguous.hpp>
#include <jaffarCommon/include/deserializers/contiguous.hpp>
#include <jaffarCommon/include/hash.hpp>
#include "nesInstance.hpp"
@ -28,8 +30,10 @@ class PlaybackInstance
{
stepData_t step;
step.input = input;
step.stateData = (uint8_t *)malloc(_emu->getStateSize());
_emu->serializeState(step.stateData);
step.stateData = (uint8_t *)malloc(_emu->getFullStateSize());
jaffarCommon::serializer::Contiguous serializer(step.stateData);
_emu->serializeState(serializer);
step.hash = jaffarCommon::calculateMetroHash(_emu->getLowMem(), _emu->getLowMemSize());
// Adding the step into the sequence
@ -166,7 +170,8 @@ class PlaybackInstance
if (stepId > 0)
{
const auto stateData = getStateData(stepId - 1);
_emu->deserializeState(stateData);
jaffarCommon::deserializer::Contiguous deserializer(stateData);
_emu->deserializeState(deserializer);
_emu->advanceState(getStateInput(stepId - 1));
}

View File

@ -1,5 +1,7 @@
#include <cstdlib>
#include "jaffarCommon/extern/argparse/argparse.hpp"
#include "jaffarCommon/include/serializers/contiguous.hpp"
#include "jaffarCommon/include/deserializers/contiguous.hpp"
#include "jaffarCommon/include/file.hpp"
#include "jaffarCommon/include/logger.hpp"
#include "jaffarCommon/include/string.hpp"
@ -109,14 +111,15 @@ int main(int argc, char *argv[])
{
std::string stateFileData;
if (jaffarCommon::loadStringFromFile(stateFileData, stateFilePath) == false) EXIT_WITH_ERROR("Could not initial state file: %s\n", stateFilePath.c_str());
e.deserializeState((uint8_t*)stateFileData.data());
jaffarCommon::deserializer::Contiguous deserializer(stateFileData.data());
e.deserializeState(deserializer);
}
// Creating playback instance
auto p = PlaybackInstance(&e, sequence);
// Getting state size
auto stateSize = e.getStateSize();
auto stateSize = e.getFullStateSize();
// Flag to continue running playback
bool continueRunning = true;

View File

@ -1,5 +1,7 @@
#pragma once
#include "jaffarCommon/include/serializers/base.hpp"
#include "jaffarCommon/include/deserializers/base.hpp"
#include "core/nes_emu/Nes_Emu.h"
#include "core/nes_emu/Nes_State.h"
#include "../nesInstanceBase.hpp"
@ -26,21 +28,21 @@ class NESInstance final : public NESInstanceBase
uint8_t *getLowMem() const override { return _nes.low_mem(); };
size_t getLowMemSize() const override { return 0x800; };
void serializeState(uint8_t *state) const override
void serializeState(jaffarCommon::serializer::Base& serializer) const override
{
Mem_Writer w(state, _stateSize, 0);
Mem_Writer w(serializer.getOutputDataBuffer(), _stateSize, 0);
Auto_File_Writer a(w);
_nes.save_state(a);
}
void deserializeState(const uint8_t *state) override
void deserializeState(jaffarCommon::deserializer::Base& deserializer) override
{
Mem_File_Reader r(state, _stateSize);
Mem_File_Reader r(deserializer.getInputDataBuffer(), _stateSize);
Auto_File_Reader a(r);
_nes.load_state(a);
}
inline size_t getStateSize() const override
inline size_t getFullStateSize() const override
{
uint8_t *data = (uint8_t *)malloc(_DUMMY_SIZE);
Mem_Writer w(data, _DUMMY_SIZE);
@ -50,28 +52,7 @@ class NESInstance final : public NESInstanceBase
return w.size();
}
void serializeDifferentialState(
uint8_t *outputData,
size_t* outputDataPos,
const size_t outputDataMaxSize,
const uint8_t* referenceData,
size_t* referenceDataPos,
const size_t maxSize,
const bool useZlib) const override
{ serializeState(outputData); }
void deserializeDifferentialState(
const uint8_t *inputData,
size_t* inputDataPos,
const size_t inputDataMaxSize,
const uint8_t* referenceData,
size_t* referenceDataPos,
const size_t referenceDataMaxSize,
const bool useZlib) override
{ deserializeState(inputData); }
size_t getDifferentialStateSize() const override
{ return getStateSize(); }
inline size_t getDifferentialStateSize() const override { return getFullStateSize(); }
std::string getCoreName() const override { return "QuickNES"; }
void doSoftReset() override { _nes.reset(false); }

View File

@ -22,7 +22,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "ppu/ppu.hpp"
#include <cstdio>
#include <string>
#include <jaffarCommon/include/diff.hpp>
#include <jaffarCommon/include/serializers/base.hpp>
#include <jaffarCommon/include/deserializers/base.hpp>
namespace quickerNES
{
@ -156,39 +157,24 @@ class Core : private Cpu
static inline void serializeBlockHead(
const char* blockTag,
const uint32_t blockSize,
uint8_t* __restrict__ outputData,
size_t* outputDataPos,
const size_t outputDataMaxSize,
size_t* referenceDataPos,
const size_t referenceDataMaxSize)
jaffarCommon::serializer::Base& serializer)
{
jaffarCommon::serializeContiguousData(blockTag, 4, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
jaffarCommon::serializeContiguousData(&blockSize, 4, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
serializer.pushContiguous(blockTag, 4);
serializer.pushContiguous(&blockSize, 4);
}
static inline void deserializeBlockHead(
size_t* inputDataPos,
size_t* referenceDataPos = nullptr)
static inline void deserializeBlockHead(jaffarCommon::deserializer::Base& deserializer)
{
*inputDataPos += 8;
if (referenceDataPos != nullptr) *referenceDataPos += 8;
uint32_t nullValue = 0;
deserializer.popContiguous(&nullValue, 4);
deserializer.popContiguous(&nullValue, 4);
}
inline void serializeState(
uint8_t* __restrict__ outputData,
size_t* outputDataPos,
const size_t outputDataMaxSize,
const uint8_t* __restrict__ referenceData = nullptr,
size_t* referenceDataPos = nullptr,
const size_t referenceDataMaxSize = 0,
const bool useZlib = false) const
inline void serializeState(jaffarCommon::serializer::Base& serializer) const
{
size_t tmpIOutputDataPos = 0;
if (outputDataPos == nullptr) outputDataPos = &tmpIOutputDataPos;
// NESS Block
if (HEADBlockEnabled == true) serializeBlockHead("NESS", 0xFFFFFFFF, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) serializeBlockHead("NESS", 0xFFFFFFFF, serializer);
// TIME Block
if (TIMEBlockEnabled == true)
@ -199,8 +185,8 @@ class Core : private Cpu
const auto inputDataSize = sizeof(nes_state_t);
const auto inputData = (uint8_t *)&state;
if (HEADBlockEnabled == true) serializeBlockHead("TIME", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) serializeBlockHead("TIME", inputDataSize, serializer);
serializer.pushContiguous(inputData, inputDataSize);
}
// CPUR Block
@ -218,8 +204,8 @@ class Core : private Cpu
const auto inputDataSize = sizeof(cpu_state_t);
const auto inputData = (uint8_t *)&s;
if (HEADBlockEnabled == true) serializeBlockHead("CPUR", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) serializeBlockHead("CPUR", inputDataSize, serializer);
serializer.pushContiguous(inputData, inputDataSize);
}
if (PPURBlockEnabled == true)
@ -227,8 +213,8 @@ class Core : private Cpu
const auto inputDataSize = sizeof(ppu_state_t);
const auto inputData = (const uint8_t *)&ppu;
if (HEADBlockEnabled == true) serializeBlockHead("PPUR", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) serializeBlockHead("PPUR", inputDataSize, serializer);
serializer.pushContiguous(inputData, inputDataSize);
}
// APUR Block
@ -240,8 +226,8 @@ class Core : private Cpu
const auto inputDataSize = sizeof(Apu::apu_state_t);
const auto inputData = (uint8_t *)&apuState;
if (HEADBlockEnabled == true) serializeBlockHead("APUR", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) serializeBlockHead("APUR", inputDataSize, serializer);
serializer.pushContiguous(inputData, inputDataSize);
}
// CTRL Block
@ -250,8 +236,8 @@ class Core : private Cpu
const auto inputDataSize = sizeof(joypad_state_t);
const auto inputData = (uint8_t *)&joypad;
if (HEADBlockEnabled == true) serializeBlockHead("CTRL", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) serializeBlockHead("CTRL", inputDataSize, serializer);
serializer.pushContiguous(inputData, inputDataSize);
}
// MAPR Block
@ -260,8 +246,8 @@ class Core : private Cpu
const auto inputDataSize = mapper->state_size;
const auto inputData = (uint8_t *)mapper->state;
if (HEADBlockEnabled == true) serializeBlockHead("MAPR", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) serializeBlockHead("MAPR", inputDataSize, serializer);
serializer.pushContiguous(inputData, inputDataSize);
}
// LRAM Block
@ -270,9 +256,8 @@ class Core : private Cpu
const auto inputDataSize = low_ram_size;
const auto inputData = (uint8_t *)low_mem;
if (HEADBlockEnabled == true) serializeBlockHead("LRAM", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos == nullptr) jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize,useZlib);
if (HEADBlockEnabled == true) serializeBlockHead("LRAM", inputDataSize, serializer);
serializer.push(inputData, inputDataSize);
}
// SPRT Block
@ -281,9 +266,8 @@ class Core : private Cpu
const auto inputDataSize = Ppu::spr_ram_size;
const auto inputData = (uint8_t *)ppu.spr_ram;
if (HEADBlockEnabled == true) serializeBlockHead("SPRT", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos == nullptr) jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize,useZlib);
if (HEADBlockEnabled == true) serializeBlockHead("SPRT", inputDataSize, serializer);
serializer.push(inputData, inputDataSize);
}
// NTAB Block
@ -295,9 +279,8 @@ class Core : private Cpu
const auto inputDataSize = nametable_size;
const auto inputData = (uint8_t *)ppu.impl->nt_ram;
if (HEADBlockEnabled == true) serializeBlockHead("NTAB", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos == nullptr) jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize,useZlib);
if (HEADBlockEnabled == true) serializeBlockHead("NTAB", inputDataSize, serializer);
serializer.push(inputData, inputDataSize);
}
// CHRR Block
@ -308,9 +291,8 @@ class Core : private Cpu
const auto inputDataSize = ppu.chr_size;
const auto inputData = (uint8_t *)ppu.impl->chr_ram;
if (HEADBlockEnabled == true) serializeBlockHead("CHRR", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos == nullptr) jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize,useZlib);
if (HEADBlockEnabled == true) serializeBlockHead("CHRR", inputDataSize, serializer);
serializer.push(inputData, inputDataSize);
}
}
@ -322,34 +304,23 @@ class Core : private Cpu
const auto inputDataSize = impl->sram_size;
const auto inputData = (uint8_t *)impl->sram;
if (HEADBlockEnabled == true) serializeBlockHead("SRAM", inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos == nullptr) jaffarCommon::serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, outputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize,useZlib);
if (HEADBlockEnabled == true) serializeBlockHead("SRAM", inputDataSize, serializer);
serializer.push(inputData, inputDataSize);
}
}
// gend Block
if (HEADBlockEnabled == true) serializeBlockHead("gend", 0, outputData, outputDataPos, outputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) serializeBlockHead("gend", 0, serializer);
}
inline void deserializeState(
const uint8_t* __restrict__ inputData,
size_t* inputDataPos,
const size_t inputDataMaxSize,
const uint8_t* __restrict__ referenceData = nullptr,
size_t* referenceDataPos = nullptr,
const size_t referenceDataMaxSize = 0,
const bool useZlib = false)
inline void deserializeState(jaffarCommon::deserializer::Base& deserializer)
{
disable_rendering();
error_count = 0;
ppu.burst_phase = 0; // avoids shimmer when seeking to same time over and over
size_t tmpInputDataPos = 0;
if (inputDataPos == nullptr) inputDataPos = &tmpInputDataPos;
// NESS Block
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
// TIME Block
if (TIMEBlockEnabled == true)
@ -359,8 +330,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) &nesState;
const auto inputDataSize = sizeof(nes_state_t);
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.popContiguous(outputData, inputDataSize);
nes = nesState;
nes.timestamp /= 5;
@ -374,8 +345,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) &s;
const auto inputDataSize = sizeof(cpu_state_t);
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.popContiguous(outputData, inputDataSize);
r.pc = s.pc;
r.sp = s.s;
@ -391,8 +362,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) &ppu;
const auto inputDataSize = sizeof(ppu_state_t);
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.popContiguous(outputData, inputDataSize);
}
// APUR Block
@ -403,8 +374,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) &apuState;
const auto inputDataSize = sizeof(Apu::apu_state_t);
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.popContiguous(outputData, inputDataSize);
impl->apu.load_state(apuState);
impl->apu.end_frame(-(int)nes.timestamp / ppu_overclock);
@ -416,8 +387,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) &joypad;
const auto inputDataSize = sizeof(joypad_state_t);
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.popContiguous(outputData, inputDataSize);
}
// MAPR Block
@ -428,8 +399,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) mapper->state;
const auto inputDataSize = mapper->state_size;
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.popContiguous(outputData, inputDataSize);
mapper->apply_mapping();
}
@ -440,9 +411,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) low_mem;
const auto inputDataSize = low_ram_size;
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
if (referenceDataPos == nullptr) jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.pop(outputData, inputDataSize);
}
// SPRT Block
@ -451,9 +421,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) ppu.spr_ram;
const auto inputDataSize = Ppu::spr_ram_size;
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
if (referenceDataPos == nullptr) jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.pop(outputData, inputDataSize);
}
// NTAB Block
@ -465,9 +434,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) ppu.impl->nt_ram;
const auto inputDataSize = nametable_size;
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
if (referenceDataPos == nullptr) jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.pop(outputData, inputDataSize);
}
// CHRR Block
@ -478,9 +446,8 @@ class Core : private Cpu
const auto outputData = (uint8_t*) ppu.impl->chr_ram;
const auto inputDataSize = ppu.chr_size;
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
if (referenceDataPos == nullptr) jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.pop(outputData, inputDataSize);
ppu.all_tiles_modified();
}
@ -494,16 +461,15 @@ class Core : private Cpu
const auto outputData = (uint8_t*) impl->sram;
const auto inputDataSize = impl->sram_size;
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
if (referenceDataPos == nullptr) jaffarCommon::deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceDataPos, referenceDataMaxSize);
if (referenceDataPos != nullptr) jaffarCommon::deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, inputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
deserializer.pop(outputData, inputDataSize);
}
}
if (sram_present) enable_sram(true);
// gend Block
if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos);
if (HEADBlockEnabled == true) deserializeBlockHead(deserializer);
}
void enableStateBlock(const std::string& block)

View File

@ -4,7 +4,6 @@
// Emu 0.7.0
#include <limits>
#include "cart.hpp"
#include "core.hpp"
#include "apu/multiBuffer.hpp"
@ -46,47 +45,8 @@ class Emu
const uint8_t *getHostPixels() const { return emu.ppu.host_pixels; }
// Save emulator state variants
void serializeState(uint8_t *buffer) const { emu.serializeState(buffer, nullptr, std::numeric_limits<uint32_t>::max()); }
void deserializeState(const uint8_t *buffer) { emu.deserializeState(buffer, nullptr, std::numeric_limits<uint32_t>::max()); }
size_t getStateSize() const { size_t outputDataPos = 0; emu.serializeState(nullptr, &outputDataPos, std::numeric_limits<uint32_t>::max()); return outputDataPos; }
void serializeDifferentialState(
uint8_t* __restrict__ outputData,
size_t* outputDataPos,
const size_t outputDataMaxSize,
const uint8_t* __restrict__ referenceData,
size_t* referenceDataPos,
const size_t referenceDataMaxSize,
const bool useZlib) const
{
emu.serializeState(outputData, outputDataPos, outputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib);
}
void deserializeDifferentialState(
const uint8_t* __restrict__ inputData,
size_t* inputDataPos,
const size_t inputDataMaxSize,
const uint8_t* __restrict__ referenceData,
size_t* referenceDataPos,
const size_t referenceDataMaxSize,
const bool useZlib)
{
emu.deserializeState(inputData, inputDataPos, inputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib);
}
size_t getDifferentialStateSize() const
{
uint8_t* outputDataPtr = nullptr;
size_t outputDataPos = 0;
uint8_t* referenceDataPtr = nullptr;
size_t referenceDataPos = 0;
uint32_t outputDataMaxSize = std::numeric_limits<uint32_t>::max();
uint32_t referenceDataMaxSize = std::numeric_limits<uint32_t>::max();
emu.serializeState(outputDataPtr, &outputDataPos, outputDataMaxSize, referenceDataPtr, &referenceDataPos, referenceDataMaxSize, false);
return outputDataPos;
}
void serializeState(jaffarCommon::serializer::Base& serializer) const { emu.serializeState(serializer); }
void deserializeState(jaffarCommon::deserializer::Base& deserializer) { emu.deserializeState(deserializer); }
void enableStateBlock(const std::string& block) { emu.enableStateBlock(block); };
void disableStateBlock(const std::string& block) { emu.disableStateBlock(block); };

View File

@ -24,33 +24,8 @@ class NESInstance final : public NESInstanceBase
uint8_t *getCHRMem() const { return _nes.chr_mem(); };
size_t getCHRMemSize() const { return _nes.chr_size(); };
void serializeState(uint8_t *state) const override { _nes.serializeState(state); }
void deserializeState(const uint8_t *state) override { _nes.deserializeState(state); }
size_t getStateSize() const override { return _nes.getStateSize(); }
void serializeDifferentialState(
uint8_t *outputData,
size_t* outputDataPos,
const size_t outputDataMaxSize,
const uint8_t* referenceData,
size_t* referenceDataPos,
const size_t referenceDataMaxSize,
const bool useZlib) const override
{ _nes.serializeDifferentialState(outputData, outputDataPos, outputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib); }
void deserializeDifferentialState(
const uint8_t *inputData,
size_t* inputDataPos,
const size_t inputDataMaxSize,
const uint8_t* referenceData,
size_t* referenceDataPos,
const size_t referenceDataMaxSize,
const bool useZlib
) override
{ _nes.deserializeDifferentialState(inputData, inputDataPos, inputDataMaxSize, referenceData, referenceDataPos, referenceDataMaxSize, useZlib); }
size_t getDifferentialStateSize() const override
{ return _nes.getDifferentialStateSize(); }
void serializeState(jaffarCommon::serializer::Base& serializer) const override { _nes.serializeState(serializer); }
void deserializeState(jaffarCommon::deserializer::Base& deserializer) override { _nes.deserializeState(deserializer); }
std::string getCoreName() const override { return "QuickerNES"; }
@ -59,6 +34,20 @@ class NESInstance final : public NESInstanceBase
void *getInternalEmulatorPointer() override { return &_nes; }
inline size_t getFullStateSize() const override
{
jaffarCommon::serializer::Contiguous serializer;
serializeState(serializer);
return serializer.getOutputSize();
}
inline size_t getDifferentialStateSize() const override
{
jaffarCommon::serializer::Differential serializer;
serializeState(serializer);
return serializer.getOutputSize();
}
protected:
bool loadROMImpl(const uint8_t* romData, const size_t romSize) override

View File

@ -1,5 +1,9 @@
#include <jaffarCommon/extern/argparse/argparse.hpp>
#include <jaffarCommon/include/json.hpp>
#include <jaffarCommon/include/serializers/contiguous.hpp>
#include <jaffarCommon/include/serializers/differential.hpp>
#include <jaffarCommon/include/deserializers/contiguous.hpp>
#include <jaffarCommon/include/deserializers/differential.hpp>
#include <jaffarCommon/include/hash.hpp>
#include <jaffarCommon/include/string.hpp>
#include <jaffarCommon/include/file.hpp>
@ -131,7 +135,8 @@ int main(int argc, char *argv[])
{
std::string stateFileData;
if (jaffarCommon::loadStringFromFile(stateFileData, initialStateFilePath) == false) EXIT_WITH_ERROR("Could not initial state file: %s\n", initialStateFilePath.c_str());
e.deserializeState((uint8_t*)stateFileData.data());
jaffarCommon::deserializer::Contiguous d(stateFileData.data());
e.deserializeState(d);
}
// Disabling requested blocks from state serialization
@ -140,8 +145,8 @@ int main(int argc, char *argv[])
// Disable rendering
e.disableRendering();
// Getting state size
const auto stateSize = e.getStateSize();
// Getting full state size
const auto stateSize = e.getFullStateSize();
// Getting differential state size
const auto fixedDiferentialStateSize = e.getDifferentialStateSize();
@ -187,19 +192,23 @@ int main(int argc, char *argv[])
fflush(stdout);
// Serializing initial state
uint8_t *currentState = (uint8_t *)malloc(stateSize);
e.serializeState(currentState);
auto currentState = (uint8_t *)malloc(stateSize);
{
jaffarCommon::serializer::Contiguous cs(currentState);
e.serializeState(cs);
}
// Serializing differential state data (in case it's used)
uint8_t *differentialStateData = nullptr;
size_t differentialStateMaxSizeDetected = 0;
// Allocating memory for differential data and performing the first serialization
if (differentialCompressionEnabled == true)
{
differentialStateData = (uint8_t *)malloc(fullDifferentialStateSize);
size_t differentialDataPos = 0;
size_t referenceDataPos = 0;
e.serializeDifferentialState(differentialStateData, &differentialDataPos, fullDifferentialStateSize, currentState, &referenceDataPos, stateSize, differentialCompressionUseZlib);
differentialStateMaxSizeDetected = differentialDataPos;
auto s = jaffarCommon::serializer::Differential(differentialStateData, fullDifferentialStateSize, currentState, stateSize, differentialCompressionUseZlib);
e.serializeState(s);
differentialStateMaxSizeDetected = s.getOutputSize();
}
// Check whether to perform each action
@ -217,12 +226,15 @@ int main(int argc, char *argv[])
{
if (differentialCompressionEnabled == true)
{
size_t differentialDataPos = 0;
size_t referenceDataPos = 0;
e.deserializeDifferentialState(differentialStateData, &differentialDataPos, fullDifferentialStateSize, currentState, &referenceDataPos, stateSize, differentialCompressionUseZlib);
jaffarCommon::deserializer::Differential d(differentialStateData, fullDifferentialStateSize, currentState, stateSize, differentialCompressionUseZlib);
e.deserializeState(d);
}
if (differentialCompressionEnabled == false) e.deserializeState(currentState);
if (differentialCompressionEnabled == false)
{
jaffarCommon::deserializer::Contiguous d(currentState, stateSize);
e.deserializeState(d);
}
}
e.advanceState(input);
@ -231,13 +243,16 @@ int main(int argc, char *argv[])
{
if (differentialCompressionEnabled == true)
{
size_t differentialDataPos = 0;
size_t referenceDataPos = 0;
e.serializeDifferentialState(differentialStateData, &differentialDataPos, fullDifferentialStateSize, currentState, &referenceDataPos, stateSize, differentialCompressionUseZlib);
differentialStateMaxSizeDetected = std::max(differentialStateMaxSizeDetected, differentialDataPos);
auto s = jaffarCommon::serializer::Differential(differentialStateData, fullDifferentialStateSize, currentState, stateSize, differentialCompressionUseZlib);
e.serializeState(s);
differentialStateMaxSizeDetected = std::max(differentialStateMaxSizeDetected, s.getOutputSize());
}
if (differentialCompressionEnabled == false) e.serializeState(currentState);
if (differentialCompressionEnabled == false)
{
auto s = jaffarCommon::serializer::Contiguous(currentState, stateSize);
e.serializeState(s);
}
}
}
auto tf = std::chrono::high_resolution_clock::now();

View File

@ -8,7 +8,7 @@
"Controller 2 Type": "None",
"Differential Compression":
{
"Enabled": true,
"Enabled": true,
"Max Differences": 3100,
"Use Zlib": true
}