diff --git a/extern/jaffarCommon b/extern/jaffarCommon index f15d231..900e829 160000 --- a/extern/jaffarCommon +++ b/extern/jaffarCommon @@ -1 +1 @@ -Subproject commit f15d231ead67f064ff6dc3b1aad07b20da088dab +Subproject commit 900e829a650eff802db4423b89023fa4d1b545b9 diff --git a/source/nesInstanceBase.hpp b/source/nesInstanceBase.hpp index 9368576..4fab6c9 100644 --- a/source/nesInstanceBase.hpp +++ b/source/nesInstanceBase.hpp @@ -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; diff --git a/source/playbackInstance.hpp b/source/playbackInstance.hpp index fc9fe36..fded5a5 100644 --- a/source/playbackInstance.hpp +++ b/source/playbackInstance.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #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)); } diff --git a/source/player.cpp b/source/player.cpp index 666ee00..6f714df 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -1,5 +1,7 @@ #include #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; diff --git a/source/quickNES/nesInstance.hpp b/source/quickNES/nesInstance.hpp index 0cd559a..aa73f72 100644 --- a/source/quickNES/nesInstance.hpp +++ b/source/quickNES/nesInstance.hpp @@ -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); } diff --git a/source/quickerNES/core/core.hpp b/source/quickerNES/core/core.hpp index a8b9160..5138b99 100644 --- a/source/quickerNES/core/core.hpp +++ b/source/quickerNES/core/core.hpp @@ -22,7 +22,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ppu/ppu.hpp" #include #include -#include +#include +#include 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) diff --git a/source/quickerNES/core/emu.hpp b/source/quickerNES/core/emu.hpp index 6dd59b7..892234e 100644 --- a/source/quickerNES/core/emu.hpp +++ b/source/quickerNES/core/emu.hpp @@ -4,7 +4,6 @@ // Emu 0.7.0 -#include #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::max()); } - void deserializeState(const uint8_t *buffer) { emu.deserializeState(buffer, nullptr, std::numeric_limits::max()); } - size_t getStateSize() const { size_t outputDataPos = 0; emu.serializeState(nullptr, &outputDataPos, std::numeric_limits::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::max(); - uint32_t referenceDataMaxSize = std::numeric_limits::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); }; diff --git a/source/quickerNES/nesInstance.hpp b/source/quickerNES/nesInstance.hpp index d36f18f..85b6332 100644 --- a/source/quickerNES/nesInstance.hpp +++ b/source/quickerNES/nesInstance.hpp @@ -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 diff --git a/source/tester.cpp b/source/tester.cpp index 53938d1..e0faf19 100644 --- a/source/tester.cpp +++ b/source/tester.cpp @@ -1,5 +1,9 @@ #include #include +#include +#include +#include +#include #include #include #include @@ -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(); diff --git a/tests/microMachines.race20.test b/tests/microMachines.race20.test index bfce733..cfa3e2f 100644 --- a/tests/microMachines.race20.test +++ b/tests/microMachines.race20.test @@ -8,7 +8,7 @@ "Controller 2 Type": "None", "Differential Compression": { - "Enabled": true, + "Enabled": true, "Max Differences": 3100, "Use Zlib": true }