From 633173ba4d380c93588bd1ea9fa596f21c238a81 Mon Sep 17 00:00:00 2001 From: Sergio Martin Date: Thu, 8 Feb 2024 07:44:08 +0100 Subject: [PATCH] Differential compression requires passing relative positions for differential and reference data --- source/nesInstanceBase.hpp | 4 +- source/quickNES/nesInstance.hpp | 6 +- source/quickerNES/core/core.hpp | 165 ++++++++++++++++-------------- source/quickerNES/core/emu.hpp | 26 +++-- source/quickerNES/nesInstance.hpp | 8 +- source/tester.cpp | 22 +++- 6 files changed, 136 insertions(+), 95 deletions(-) diff --git a/source/nesInstanceBase.hpp b/source/nesInstanceBase.hpp index cedc093..d46e4b8 100644 --- a/source/nesInstanceBase.hpp +++ b/source/nesInstanceBase.hpp @@ -98,8 +98,8 @@ class NESInstanceBase virtual void deserializeState(const uint8_t *state) = 0; virtual size_t getStateSize() const = 0; - virtual size_t serializeDifferentialState(uint8_t *differentialData, const uint8_t* referenceData, const size_t maxSize, const bool useZlib) const = 0; - virtual void deserializeDifferentialState(const uint8_t *differentialData, const uint8_t* referenceData, const bool useZlib) = 0; + virtual void serializeDifferentialState(uint8_t *differentialData, size_t* differentialDataPos, const uint8_t* referenceData, size_t* referenceDataPos, const size_t maxSize, const bool useZlib) const = 0; + virtual void deserializeDifferentialState(const uint8_t *differentialData, size_t* differentialDataPos, const uint8_t* referenceData, size_t* referenceDataPos, const bool useZlib) = 0; virtual size_t getDifferentialStateSize() const = 0; virtual void doSoftReset() = 0; diff --git a/source/quickNES/nesInstance.hpp b/source/quickNES/nesInstance.hpp index 7edf5ec..391ffec 100644 --- a/source/quickNES/nesInstance.hpp +++ b/source/quickNES/nesInstance.hpp @@ -50,10 +50,10 @@ class NESInstance final : public NESInstanceBase return w.size(); } - size_t serializeDifferentialState(uint8_t *differentialData, const uint8_t* referenceData, const size_t maxSize, const bool useZlib) const override - { serializeState(differentialData); return 0; } + void serializeDifferentialState(uint8_t *differentialData, size_t* differentialDataPos, const uint8_t* referenceData, size_t* referenceDataPos, const size_t maxSize, const bool useZlib) const override + { serializeState(differentialData); } - void deserializeDifferentialState(const uint8_t *differentialData, const uint8_t* referenceData, const bool useZlib) override + void deserializeDifferentialState(const uint8_t *differentialData, size_t* differentialDataPos, const uint8_t* referenceData, size_t* referenceDataPos, const bool useZlib) override { deserializeState(differentialData); } size_t getDifferentialStateSize() const override diff --git a/source/quickerNES/core/core.hpp b/source/quickerNES/core/core.hpp index 1912c3f..becfa5a 100644 --- a/source/quickerNES/core/core.hpp +++ b/source/quickerNES/core/core.hpp @@ -160,7 +160,7 @@ class Core : private Cpu // Moving pointer positions *outputDataPos += inputDataSize; - *referenceDataPos += inputDataSize; + if (referenceDataPos != nullptr) *referenceDataPos += inputDataSize; } static inline void deserializeContiguousData(uint8_t* __restrict__ outputData, const size_t outputDataSize, const uint8_t* __restrict__ inputData, size_t* inputDataPos, size_t* referenceDataPos) @@ -170,22 +170,31 @@ class Core : private Cpu // Moving pointer positions *inputDataPos += outputDataSize; - *referenceDataPos += outputDataSize; + if (referenceDataPos != nullptr) *referenceDataPos += outputDataSize; } - static inline void serializeBlockHead(uint8_t* __restrict__ outputData, size_t* outputDataPos, size_t* referenceDataPos, const char* blockTag, const uint32_t blockSize) + static inline void serializeBlockHead( + uint8_t* __restrict__ outputData, + size_t* outputDataPos, + const char* blockTag, + const uint32_t blockSize, + size_t* referenceDataPos = nullptr) { if (outputData != nullptr) memcpy(&outputData[*outputDataPos], blockTag, 4); - *outputDataPos += 4; *referenceDataPos += 4; + *outputDataPos += 4; + if (referenceDataPos != nullptr) *referenceDataPos += 4; if (outputData != nullptr) memcpy(&outputData[*outputDataPos], &blockSize, 4); - *outputDataPos += 4; *referenceDataPos += 4; + *outputDataPos += 4; + if (referenceDataPos != nullptr) *referenceDataPos += 4; } - static inline void deserializeBlockHead(size_t* inputDataPos, size_t* referenceDataPos) + static inline void deserializeBlockHead( + size_t* inputDataPos, + size_t* referenceDataPos = nullptr) { *inputDataPos += 8; - *referenceDataPos += 8; + if (referenceDataPos != nullptr) *referenceDataPos += 8; } static inline void serializeDifferentialData( @@ -294,18 +303,19 @@ class Core : private Cpu } - size_t serializeState( + inline void serializeState( uint8_t* __restrict__ outputData, - const bool useDifferentialCompression = false, + size_t* outputDataPos = nullptr, const uint8_t* __restrict__ referenceData = nullptr, + size_t* referenceDataPos = nullptr, const size_t outputMaxSize = 0, const bool useZlib = false) const { - size_t outputDataPos = 0; - size_t referenceDataPos = 0; + size_t tmpIOutputDataPos = 0; + if (outputDataPos == nullptr) outputDataPos = &tmpIOutputDataPos; // NESS Block - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "NESS", 0xFFFFFFFF); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "NESS", 0xFFFFFFFF, referenceDataPos); // TIME Block if (TIMEBlockEnabled == true) @@ -316,8 +326,8 @@ class Core : private Cpu const auto inputDataSize = sizeof(nes_state_t); const auto inputData = (uint8_t *)&state; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "TIME", inputDataSize); - serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "TIME", inputDataSize, referenceDataPos); + serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); } // CPUR Block @@ -335,8 +345,8 @@ class Core : private Cpu const auto inputDataSize = sizeof(cpu_state_t); const auto inputData = (uint8_t *)&s; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "CPUR", inputDataSize); - serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "CPUR", inputDataSize, referenceDataPos); + serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); } if (PPURBlockEnabled == true) @@ -344,8 +354,8 @@ class Core : private Cpu const auto inputDataSize = sizeof(ppu_state_t); const auto inputData = (const uint8_t *)&ppu; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "PPUR", inputDataSize); - serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "PPUR", inputDataSize, referenceDataPos); + serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); } // APUR Block @@ -357,8 +367,8 @@ class Core : private Cpu const auto inputDataSize = sizeof(Apu::apu_state_t); const auto inputData = (uint8_t *)&apuState; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "APUR", inputDataSize); - serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "APUR", inputDataSize, referenceDataPos); + serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); } // CTRL Block @@ -367,8 +377,8 @@ class Core : private Cpu const auto inputDataSize = sizeof(joypad_state_t); const auto inputData = (uint8_t *)&joypad; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "CTRL", inputDataSize); - serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "CTRL", inputDataSize, referenceDataPos); + serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); } // MAPR Block @@ -377,8 +387,8 @@ class Core : private Cpu const auto inputDataSize = mapper->state_size; const auto inputData = (uint8_t *)mapper->state; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "MAPR", inputDataSize); - serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "MAPR", inputDataSize, referenceDataPos); + serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); } // LRAM Block @@ -387,9 +397,9 @@ class Core : private Cpu const auto inputDataSize = low_ram_size; const auto inputData = (uint8_t *)low_mem; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "LRAM", inputDataSize); - if (useDifferentialCompression == false) serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) serializeDifferentialData(inputData, inputDataSize, outputData, &outputDataPos, referenceData, &referenceDataPos, outputMaxSize, useZlib); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "LRAM", inputDataSize, referenceDataPos); + if (referenceDataPos == nullptr) serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, referenceData, referenceDataPos, outputMaxSize, useZlib); } // SPRT Block @@ -398,9 +408,9 @@ class Core : private Cpu const auto inputDataSize = Ppu::spr_ram_size; const auto inputData = (uint8_t *)ppu.spr_ram; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "SPRT", inputDataSize); - if (useDifferentialCompression == false) serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) serializeDifferentialData(inputData, inputDataSize, outputData, &outputDataPos, referenceData, &referenceDataPos, outputMaxSize, useZlib); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "SPRT", inputDataSize, referenceDataPos); + if (referenceDataPos == nullptr) serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, referenceData, referenceDataPos, outputMaxSize, useZlib); } // NTAB Block @@ -412,9 +422,9 @@ class Core : private Cpu const auto inputDataSize = nametable_size; const auto inputData = (uint8_t *)ppu.impl->nt_ram; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "NTAB", inputDataSize); - if (useDifferentialCompression == false) serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) serializeDifferentialData(inputData, inputDataSize, outputData, &outputDataPos, referenceData, &referenceDataPos, outputMaxSize, useZlib); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "NTAB", inputDataSize, referenceDataPos); + if (referenceDataPos == nullptr) serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, referenceData, referenceDataPos, outputMaxSize, useZlib); } // CHRR Block @@ -425,9 +435,9 @@ class Core : private Cpu const auto inputDataSize = ppu.chr_size; const auto inputData = (uint8_t *)ppu.impl->chr_ram; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "CHRR", inputDataSize); - if (useDifferentialCompression == false) serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) serializeDifferentialData(inputData, inputDataSize, outputData, &outputDataPos, referenceData, &referenceDataPos, outputMaxSize, useZlib); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "CHRR", inputDataSize, referenceDataPos); + if (referenceDataPos == nullptr) serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, referenceData, referenceDataPos, outputMaxSize, useZlib); } } @@ -439,29 +449,32 @@ class Core : private Cpu const auto inputDataSize = impl->sram_size; const auto inputData = (uint8_t *)impl->sram; - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "SRAM", inputDataSize); - if (useDifferentialCompression == false) serializeContiguousData(inputData, inputDataSize, outputData, &outputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) serializeDifferentialData(inputData, inputDataSize, outputData, &outputDataPos, referenceData, &referenceDataPos, outputMaxSize, useZlib); + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "SRAM", inputDataSize, referenceDataPos); + if (referenceDataPos == nullptr) serializeContiguousData(inputData, inputDataSize, outputData, outputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) serializeDifferentialData(inputData, inputDataSize, outputData, outputDataPos, referenceData, referenceDataPos, outputMaxSize, useZlib); } } // gend Block - if (HEADBlockEnabled == true) serializeBlockHead(outputData, &outputDataPos, &referenceDataPos, "gend", 0); - - return outputDataPos; // Bytes written + if (HEADBlockEnabled == true) serializeBlockHead(outputData, outputDataPos, "gend", 0, referenceDataPos); } - size_t deserializeState(const uint8_t* __restrict__ inputData, const bool useDifferentialCompression = false, const uint8_t* __restrict__ referenceData = nullptr, const bool useZlib = false) + inline void deserializeState( + const uint8_t* __restrict__ inputData, + size_t* inputDataPos = nullptr, + const uint8_t* __restrict__ referenceData = nullptr, + size_t* referenceDataPos = nullptr, + const bool useZlib = false) { disable_rendering(); error_count = 0; ppu.burst_phase = 0; // avoids shimmer when seeking to same time over and over - size_t inputDataPos = 0; - size_t referenceDataPos = 0; - + size_t tmpInputDataPos = 0; + if (inputDataPos == nullptr) inputDataPos = &tmpInputDataPos; + // NESS Block - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); // TIME Block if (TIMEBlockEnabled == true) @@ -471,8 +484,8 @@ class Core : private Cpu const auto outputData = (uint8_t*) &nesState; const auto inputDataSize = sizeof(nes_state_t); - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); - deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); nes = nesState; nes.timestamp /= 5; @@ -486,8 +499,8 @@ class Core : private Cpu const auto outputData = (uint8_t*) &s; const auto inputDataSize = sizeof(cpu_state_t); - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); - deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); r.pc = s.pc; r.sp = s.s; @@ -503,8 +516,8 @@ class Core : private Cpu const auto outputData = (uint8_t*) &ppu; const auto inputDataSize = sizeof(ppu_state_t); - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); - deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); } // APUR Block @@ -515,8 +528,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); - deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); impl->apu.load_state(apuState); impl->apu.end_frame(-(int)nes.timestamp / ppu_overclock); @@ -528,8 +541,8 @@ class Core : private Cpu const auto outputData = (uint8_t*) &joypad; const auto inputDataSize = sizeof(joypad_state_t); - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); - deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); } // MAPR Block @@ -540,8 +553,8 @@ class Core : private Cpu const auto outputData = (uint8_t*) mapper->state; const auto inputDataSize = mapper->state_size; - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); - deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); mapper->apply_mapping(); } @@ -552,9 +565,9 @@ class Core : private Cpu const auto outputData = (uint8_t*) low_mem; const auto inputDataSize = low_ram_size; - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); - if (useDifferentialCompression == false) deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) deserializeDifferentialData(outputData, inputDataSize, inputData, &inputDataPos, referenceData, &referenceDataPos, useZlib); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + if (referenceDataPos == nullptr) deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, referenceData, referenceDataPos, useZlib); } // SPRT Block @@ -563,9 +576,9 @@ 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 (useDifferentialCompression == false) deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) deserializeDifferentialData(outputData, inputDataSize, inputData, &inputDataPos, referenceData, &referenceDataPos, useZlib); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + if (referenceDataPos == nullptr) deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, referenceData, referenceDataPos, useZlib); } // NTAB Block @@ -577,9 +590,9 @@ 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 (useDifferentialCompression == false) deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) deserializeDifferentialData(outputData, inputDataSize, inputData, &inputDataPos, referenceData, &referenceDataPos, useZlib); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + if (referenceDataPos == nullptr) deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, referenceData, referenceDataPos, useZlib); } // CHRR Block @@ -590,9 +603,9 @@ 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 (useDifferentialCompression == false) deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) deserializeDifferentialData(outputData, inputDataSize, inputData, &inputDataPos, referenceData, &referenceDataPos, useZlib); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + if (referenceDataPos == nullptr) deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, referenceData, referenceDataPos, useZlib); ppu.all_tiles_modified(); } @@ -606,18 +619,16 @@ class Core : private Cpu const auto outputData = (uint8_t*) impl->sram; const auto inputDataSize = impl->sram_size; - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); - if (useDifferentialCompression == false) deserializeContiguousData(outputData, inputDataSize, inputData, &inputDataPos, &referenceDataPos); - if (useDifferentialCompression == true) deserializeDifferentialData(outputData, inputDataSize, inputData, &inputDataPos, referenceData, &referenceDataPos, useZlib); + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); + if (referenceDataPos == nullptr) deserializeContiguousData(outputData, inputDataSize, inputData, inputDataPos, referenceDataPos); + if (referenceDataPos != nullptr) deserializeDifferentialData(outputData, inputDataSize, inputData, inputDataPos, referenceData, referenceDataPos, useZlib); } } if (sram_present) enable_sram(true); // gend Block - if (HEADBlockEnabled == true) deserializeBlockHead(&inputDataPos, &referenceDataPos); - - return inputDataPos; // Bytes read + if (HEADBlockEnabled == true) deserializeBlockHead(inputDataPos, referenceDataPos); } void enableStateBlock(const std::string& block) diff --git a/source/quickerNES/core/emu.hpp b/source/quickerNES/core/emu.hpp index 02cb0f6..8a12231 100644 --- a/source/quickerNES/core/emu.hpp +++ b/source/quickerNES/core/emu.hpp @@ -45,13 +45,27 @@ class Emu const uint8_t *getHostPixels() const { return emu.ppu.host_pixels; } // Save emulator state variants - size_t serializeState(uint8_t *buffer) const { return emu.serializeState(buffer, false); } - size_t deserializeState(const uint8_t *buffer) { return emu.deserializeState(buffer, false); } - size_t getStateSize() const { return emu.serializeState(nullptr, false); } + void serializeState(uint8_t *buffer) const { emu.serializeState(buffer); } + void deserializeState(const uint8_t *buffer) { emu.deserializeState(buffer); } + size_t getStateSize() const { size_t outputDataPos = 0; emu.serializeState(nullptr, &outputDataPos); return outputDataPos; } - size_t serializeDifferentialState(uint8_t* __restrict__ outputData, const uint8_t* __restrict__ referenceData, const size_t outputMaxSize, const bool useZlib) const { return emu.serializeState(outputData, true, referenceData, outputMaxSize, useZlib); } - size_t deserializeDifferentialState(const uint8_t* __restrict__ inputStateData, const uint8_t* __restrict__ referenceData, const bool useZlib) { return emu.deserializeState(inputStateData, true, referenceData, useZlib); } - size_t getDifferentialStateSize() const { return emu.serializeState(nullptr, true, nullptr, 0, false); } + void serializeDifferentialState(uint8_t* __restrict__ outputData, size_t* outputDataPos, const uint8_t* __restrict__ referenceData, size_t* referenceDataPos, const size_t outputMaxSize, const bool useZlib) const + { + emu.serializeState(outputData, outputDataPos, referenceData, referenceDataPos, outputMaxSize, useZlib); + } + + void deserializeDifferentialState(const uint8_t* __restrict__ inputData, size_t* inputDataPos, const uint8_t* __restrict__ referenceData, size_t* referenceDataPos, const bool useZlib) + { + emu.deserializeState(inputData, inputDataPos, referenceData, referenceDataPos, useZlib); + } + + size_t getDifferentialStateSize() const + { + size_t outputDataPos = 0; + size_t referenceDataPos = 0; + emu.serializeState(nullptr, &outputDataPos, nullptr, &referenceDataPos, 0, false); + return outputDataPos; + } 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 80143d6..2b4e887 100644 --- a/source/quickerNES/nesInstance.hpp +++ b/source/quickerNES/nesInstance.hpp @@ -28,11 +28,11 @@ class NESInstance final : public NESInstanceBase void deserializeState(const uint8_t *state) override { _nes.deserializeState(state); } size_t getStateSize() const override { return _nes.getStateSize(); } - size_t serializeDifferentialState(uint8_t *differentialData, const uint8_t* referenceData, const size_t maxSize, const bool useZlib) const override - { return _nes.serializeDifferentialState(differentialData, referenceData, maxSize, useZlib); } + void serializeDifferentialState(uint8_t *differentialData, size_t* differentialDataPos, const uint8_t* referenceData, size_t* referenceDataPos, const size_t maxSize, const bool useZlib) const override + { _nes.serializeDifferentialState(differentialData, differentialDataPos, referenceData, referenceDataPos, maxSize, useZlib); } - void deserializeDifferentialState(const uint8_t *differentialData, const uint8_t* referenceData, const bool useZlib) override - { _nes.deserializeDifferentialState(differentialData, referenceData, useZlib); } + void deserializeDifferentialState(const uint8_t *differentialData, size_t* differentialDataPos, const uint8_t* referenceData, size_t* referenceDataPos, const bool useZlib) override + { _nes.deserializeDifferentialState(differentialData, differentialDataPos, referenceData, referenceDataPos, useZlib); } size_t getDifferentialStateSize() const override { return _nes.getDifferentialStateSize(); } diff --git a/source/tester.cpp b/source/tester.cpp index 25bb0e4..4d59222 100644 --- a/source/tester.cpp +++ b/source/tester.cpp @@ -195,7 +195,10 @@ int main(int argc, char *argv[]) if (differentialCompressionEnabled == true) { differentialStateData = (uint8_t *)malloc(fullDifferentialStateSize); - differentialStateMaxSizeDetected = e.serializeDifferentialState(differentialStateData, currentState, fullDifferentialStateSize, differentialCompressionUseZlib); + size_t differentialDataPos = 0; + size_t referenceDataPos = 0; + e.serializeDifferentialState(differentialStateData, &differentialDataPos, currentState, &referenceDataPos, fullDifferentialStateSize, differentialCompressionUseZlib); + differentialStateMaxSizeDetected = differentialDataPos; } // Check whether to perform each action @@ -211,7 +214,13 @@ int main(int argc, char *argv[]) if (doDeserialize == true) { - if (differentialCompressionEnabled == true) e.deserializeDifferentialState(differentialStateData, currentState, differentialCompressionUseZlib); + if (differentialCompressionEnabled == true) + { + size_t differentialDataPos = 0; + size_t referenceDataPos = 0; + e.deserializeDifferentialState(differentialStateData, &differentialDataPos, currentState, &referenceDataPos, differentialCompressionUseZlib); + } + if (differentialCompressionEnabled == false) e.deserializeState(currentState); } @@ -219,7 +228,14 @@ int main(int argc, char *argv[]) if (doSerialize == true) { - if (differentialCompressionEnabled == true) differentialStateMaxSizeDetected = std::max(differentialStateMaxSizeDetected, e.serializeDifferentialState(differentialStateData, currentState, fullDifferentialStateSize, differentialCompressionUseZlib)); + if (differentialCompressionEnabled == true) + { + size_t differentialDataPos = 0; + size_t referenceDataPos = 0; + e.serializeDifferentialState(differentialStateData, &differentialDataPos, currentState, &referenceDataPos, fullDifferentialStateSize, differentialCompressionUseZlib); + differentialStateMaxSizeDetected = std::max(differentialStateMaxSizeDetected, differentialDataPos); + } + if (differentialCompressionEnabled == false) e.serializeState(currentState); } }