diff --git a/externals/boost b/externals/boost index 1acb9699a..d2a5baa1a 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 1acb9699ac8e91654331504cf3524b26463eeee4 +Subproject commit d2a5baa1ad701671a7ef547ef71cb0f0c80ce2cf diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index af07ac215..5abf93dbc 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -84,6 +84,7 @@ add_library(common STATIC misc.cpp param_package.cpp param_package.h + pod.h quaternion.h ring_buffer.h scm_rev.cpp diff --git a/src/common/pod.h b/src/common/pod.h new file mode 100644 index 000000000..e7224644a --- /dev/null +++ b/src/common/pod.h @@ -0,0 +1,20 @@ +#include "boost/serialization/split_member.hpp" + +#define SERIALIZE_AS_POD \ + private: \ + friend class boost::serialization::access; \ + template \ + void save(Archive & ar, const unsigned int file_version) const { \ + ar.save_binary(this, sizeof(*this)); \ + } \ + template \ + void load(Archive & ar, const unsigned int file_version) { \ + ar.load_binary(this, sizeof(*this)); \ + } \ + template \ + void serialize( \ + Archive &ar, \ + const unsigned int file_version \ + ){ \ + boost::serialization::split_member(ar, *this, file_version); \ + } diff --git a/src/core/core.h b/src/core/core.h index 5b7965453..333e4a76c 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -15,6 +15,7 @@ #include "core/memory.h" #include "core/perf_stats.h" #include "core/telemetry_session.h" +class boost::serialization::access; class ARM_Interface; @@ -338,6 +339,14 @@ private: std::atomic reset_requested; std::atomic shutdown_requested; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & GPU::g_regs; + ar & LCD::g_regs; + } }; inline ARM_Interface& CPU() { diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 1543d7bd8..4168ce36c 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -10,6 +10,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/pod.h" // All the constants in this file come from http://3dbrew.org/wiki/Error_codes @@ -225,6 +226,8 @@ union ResultCode { constexpr bool IsError() const { return is_error.ExtractValue(raw) == 1; } + + SERIALIZE_AS_POD }; constexpr bool operator==(const ResultCode& a, const ResultCode& b) { diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 606ab9504..980b48cd7 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -10,6 +10,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/pod.h" namespace Memory { class MemorySystem; @@ -296,6 +297,8 @@ private: static inline u32 DecodeAddressRegister(u32 register_value) { return register_value * 8; } + + SERIALIZE_AS_POD }; static_assert(std::is_standard_layout::value, "Structure does not use standard layout"); diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h index 5e37121f7..ecc9ecea4 100644 --- a/src/core/hw/lcd.h +++ b/src/core/hw/lcd.h @@ -9,6 +9,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/pod.h" #define LCD_REG_INDEX(field_name) (offsetof(LCD::Regs, field_name) / sizeof(u32)) @@ -50,6 +51,8 @@ struct Regs { u32* content = reinterpret_cast(this); return content[index]; } + + SERIALIZE_AS_POD }; static_assert(std::is_standard_layout::value, "Structure does not use standard layout"); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index e5fb83f5a..9ee279129 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,7 +4,8 @@ #include #include -#include "boost/serialization/split_member.hpp" +#include "boost/serialization/array.hpp" +#include "boost/serialization/nvp.hpp" #include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" @@ -54,6 +55,16 @@ private: std::array vram{}; std::array linear_heap{}; std::array new_linear_heap{}; + + static_assert(sizeof(bool) == 1); // TODO: Maybe this isn't true? + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & vram; + ar & linear_heap; + ar & new_linear_heap; + } }; class MemorySystem::Impl { @@ -71,31 +82,29 @@ public: AudioCore::DspInterface* dsp = nullptr; private: + + template + void add_blob(Archive & ar, std::unique_ptr & var, const char *name, std::size_t size) + { + ar & boost::serialization::make_nvp( + name, + *static_cast(static_cast(var.get())) + ); + } + friend class boost::serialization::access; template - void save(Archive & ar, const unsigned int file_version) const + void serialize(Archive & ar, const unsigned int file_version) { // TODO: Skip n3ds ram when not used? - ar.save_binary(fcram.get(), Memory::FCRAM_N3DS_SIZE); - ar.save_binary(vram.get(), Memory::VRAM_SIZE); - ar.save_binary(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); - // ar & cache_marker; + add_blob(ar, fcram, "fcram", Memory::FCRAM_N3DS_SIZE); + add_blob(ar, vram, "vram", Memory::VRAM_SIZE); + add_blob(ar, n3ds_extra_ram, "n3ds_extra_ram", Memory::N3DS_EXTRA_RAM_SIZE); + ar & cache_marker; + // TODO: How the hell to do page tables.. // ar & page_table_list; // ar & current_page_table; } - - template - void load(Archive & ar, const unsigned int file_version) - { - ar.load_binary(fcram.get(), Memory::FCRAM_N3DS_SIZE); - ar.load_binary(vram.get(), Memory::VRAM_SIZE); - ar.load_binary(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); - // ar & cache_marker; - // ar & page_table_list; - // ar & current_page_table; - } - - BOOST_SERIALIZATION_SPLIT_MEMBER() }; SERIALIZE_IMPL(MemorySystem::Impl)