From 6940c99ed65c64f462efc082d31f238eac13ae25 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 6 Aug 2019 15:59:31 +0100 Subject: [PATCH 001/129] Added boost serialization --- .gitmodules | 2 +- CMakeLists.txt | 9 +++++++++ externals/boost | 2 +- src/common/archives.h | 11 +++++++++++ src/core/CMakeLists.txt | 2 +- src/core/hle/kernel/vm_manager.h | 26 ++++++++++++++++++++++++++ src/core/memory.cpp | 31 +++++++++++++++++++++++++++++++ src/core/memory.h | 9 +++++++++ 8 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 src/common/archives.h diff --git a/.gitmodules b/.gitmodules index b247ccdbe..b0bfcaee8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "boost"] path = externals/boost - url = https://github.com/citra-emu/ext-boost.git + url = https://github.com/hamish-milne/ext-boost.git [submodule "nihstro"] path = externals/nihstro url = https://github.com/neobrain/nihstro.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d55f375..df8081f05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) # System imported libraries # ====================== +add_library(boost_libs INTERFACE) + find_package(Boost 1.66.0 QUIET) if (NOT Boost_FOUND) message(STATUS "Boost 1.66.0 or newer not found, falling back to externals") @@ -131,7 +133,14 @@ if (NOT Boost_FOUND) set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost") set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") set(Boost_NO_SYSTEM_PATHS OFF) + add_definitions( -DBOOST_ALL_NO_LIB ) find_package(Boost QUIET REQUIRED) + + # Boost external libraries + file(GLOB boost_serialization_SRC "externals/boost/libs/serialization/src/*.cpp") + add_library(boost_serialization STATIC ${boost_serialization_SRC}) + target_link_libraries(boost_serialization PUBLIC Boost::boost) + target_link_libraries(boost_libs INTERFACE boost_serialization) endif() # Prefer the -pthread flag on Linux. diff --git a/externals/boost b/externals/boost index 502437b2a..1acb9699a 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 502437b2ae3f1da821aa7d5d5174ec356fa89269 +Subproject commit 1acb9699ac8e91654331504cf3524b26463eeee4 diff --git a/src/common/archives.h b/src/common/archives.h new file mode 100644 index 000000000..76aa71054 --- /dev/null +++ b/src/common/archives.h @@ -0,0 +1,11 @@ +#include "boost/archive/binary_iarchive.hpp" +#include "boost/archive/binary_oarchive.hpp" + +#define SERIALIZE_IMPL(A) template void A::serialize( \ + boost::archive::binary_iarchive & ar, \ + const unsigned int file_version \ +); \ +template void A::serialize( \ + boost::archive::binary_oarchive & ar, \ + const unsigned int file_version \ +); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 064e44f94..ed2642431 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -465,7 +465,7 @@ endif() create_target_directory_groups(core) target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core) -target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives) +target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives boost_libs) if (ENABLE_WEB_SERVICE) target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE) target_link_libraries(core PRIVATE web_service) diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index fbd9bf09b..0d3ae1e44 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -8,6 +8,7 @@ #include #include #include +#include "boost/serialization/split_member.hpp" #include "common/common_types.h" #include "core/hle/result.h" #include "core/memory.h" @@ -193,6 +194,31 @@ public: Memory::PageTable page_table; private: + friend class boost::serialization::access; + template + void save(Archive & ar, const unsigned int file_version) + { + for (int i = 0; i < page_table.pointers.size(); i++) { + ar << memory.GetFCRAMOffset(page_table.pointers[i]); + } + ar & page_table.special_regions; + ar & page_table.attributes; + } + + template + void load(Archive & ar, const unsigned int file_version) + { + for (int i = 0; i < page_table.pointers.size(); i++) { + u32 offset{}; + ar >> offset; + page_table.pointers[i] = memory.GetFCRAMPointer(offset); + } + ar & page_table.special_regions; + ar & page_table.attributes; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + using VMAIter = decltype(vma_map)::iterator; /// Converts a VMAHandle to a mutable VMAIter. diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 096f4c697..e5fb83f5a 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,7 +4,9 @@ #include #include +#include "boost/serialization/split_member.hpp" #include "audio_core/dsp_interface.h" +#include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" @@ -67,8 +69,37 @@ public: std::vector page_table_list; AudioCore::DspInterface* dsp = nullptr; + +private: + friend class boost::serialization::access; + template + void save(Archive & ar, const unsigned int file_version) const + { + // 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; + // 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) + MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; diff --git a/src/core/memory.h b/src/core/memory.h index 6caca5a2b..e5582d16d 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -9,6 +9,7 @@ #include #include #include +#include "boost/serialization/split_member.hpp" #include "common/common_types.h" #include "core/mmio.h" @@ -52,6 +53,14 @@ struct SpecialRegion { VAddr base; u32 size; MMIORegionPointer handler; + + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & base; + ar & size; + ar & handler; + } }; /** From dc04774ece118757007fdf9e14b52585990e2554 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 6 Aug 2019 17:45:06 +0100 Subject: [PATCH 002/129] Added POD serialization --- externals/boost | 2 +- src/common/CMakeLists.txt | 1 + src/common/pod.h | 20 +++++++++++++++++ src/core/core.h | 9 ++++++++ src/core/hle/result.h | 3 +++ src/core/hw/gpu.h | 3 +++ src/core/hw/lcd.h | 3 +++ src/core/memory.cpp | 47 +++++++++++++++++++++++---------------- 8 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 src/common/pod.h 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) From ee2cae20931114fb0b6fc7733e70e48930fa80a9 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 7 Aug 2019 02:53:56 +0100 Subject: [PATCH 003/129] Added core serialization --- src/audio_core/dsp_interface.h | 1 + src/core/core.cpp | 26 ++++++++++++++++++++++++++ src/core/core.h | 12 ++++++------ src/core/memory.cpp | 11 +++++++++-- src/core/memory.h | 6 +++++- 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h index fc3d7cab2..29ec13d61 100644 --- a/src/audio_core/dsp_interface.h +++ b/src/audio_core/dsp_interface.h @@ -6,6 +6,7 @@ #include #include +#include "boost/serialization/array.hpp" #include "audio_core/audio_types.h" #include "audio_core/time_stretch.h" #include "common/common_types.h" diff --git a/src/core/core.cpp b/src/core/core.cpp index ebaee4f87..cee6a3866 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -4,9 +4,12 @@ #include #include +#include "boost/serialization/array.hpp" +#include "boost/serialization/unique_ptr.hpp" #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" +#include "common/archives.h" #include "common/logging/log.h" #include "common/texture.h" #include "core/arm/arm_interface.h" @@ -30,7 +33,9 @@ #include "core/hle/service/fs/archive.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" +#include "core/hw/gpu.h" #include "core/hw/hw.h" +#include "core/hw/lcd.h" #include "core/loader/loader.h" #include "core/movie.h" #include "core/rpc/rpc_server.h" @@ -389,4 +394,25 @@ void System::Reset() { Load(*m_emu_window, m_filepath); } +template +void System::serialize(Archive & ar, const unsigned int file_version) +{ + ar & memory; + ar & GPU::g_regs; + ar & LCD::g_regs; + ar & dsp_core->GetDspMemory(); +} + +void System::Save(std::ostream &stream) const +{ + boost::archive::binary_oarchive oa{stream}; + oa & *this; +} + +void System::Load(std::istream &stream) +{ + boost::archive::binary_iarchive ia{stream}; + ia & *this; +} + } // namespace Core diff --git a/src/core/core.h b/src/core/core.h index 333e4a76c..b811badba 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -6,6 +6,7 @@ #include #include +#include "boost/serialization/access.hpp" #include "common/common_types.h" #include "core/custom_tex_cache.h" #include "core/frontend/applets/mii_selector.h" @@ -15,7 +16,6 @@ #include "core/memory.h" #include "core/perf_stats.h" #include "core/telemetry_session.h" -class boost::serialization::access; class ARM_Interface; @@ -272,6 +272,10 @@ public: return registered_image_interface; } + void Save(std::ostream &stream) const; + + void Load(std::istream &stream); + private: /** * Initialize the emulated system. @@ -342,11 +346,7 @@ private: friend class boost::serialization::access; template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & GPU::g_regs; - ar & LCD::g_regs; - } + void serialize(Archive & ar, const unsigned int file_version); }; inline ARM_Interface& CPU() { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 9ee279129..fe33cf767 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -6,6 +6,7 @@ #include #include "boost/serialization/array.hpp" #include "boost/serialization/nvp.hpp" +#include "boost/serialization/unique_ptr.hpp" #include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" @@ -107,11 +108,17 @@ private: } }; -SERIALIZE_IMPL(MemorySystem::Impl) - MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; +template +void MemorySystem::serialize(Archive & ar, const unsigned int file_version) +{ + ar & impl; +} + +SERIALIZE_IMPL(MemorySystem) + void MemorySystem::SetCurrentPageTable(PageTable* page_table) { impl->current_page_table = page_table; } diff --git a/src/core/memory.h b/src/core/memory.h index e5582d16d..9c1455a80 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -9,7 +9,7 @@ #include #include #include -#include "boost/serialization/split_member.hpp" +#include "boost/serialization/access.hpp" #include "common/common_types.h" #include "core/mmio.h" @@ -324,6 +324,10 @@ private: class Impl; std::unique_ptr impl; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version); }; /// Determines if the given VAddr is valid for the specified process. From 6f00976ab59c8e8960c11a43e5d746146aa2884a Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 7 Aug 2019 17:08:52 +0100 Subject: [PATCH 004/129] video_core serialization --- src/common/archives.h | 11 ++-- src/core/core.cpp | 16 +++-- src/core/hw/gpu.cpp | 9 +-- src/video_core/CMakeLists.txt | 2 +- src/video_core/command_processor.cpp | 13 +++- src/video_core/command_processor.h | 2 +- src/video_core/pica_state.h | 90 ++++++++++++++++++++++++++++ src/video_core/video_core.cpp | 16 +++++ src/video_core/video_core.h | 4 ++ 9 files changed, 142 insertions(+), 21 deletions(-) diff --git a/src/common/archives.h b/src/common/archives.h index 76aa71054..490710d3c 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -1,11 +1,14 @@ #include "boost/archive/binary_iarchive.hpp" #include "boost/archive/binary_oarchive.hpp" -#define SERIALIZE_IMPL(A) template void A::serialize( \ - boost::archive::binary_iarchive & ar, \ +using iarchive = boost::archive::binary_iarchive; +using oarchive = boost::archive::binary_oarchive; + +#define SERIALIZE_IMPL(A) template void A::serialize( \ + iarchive & ar, \ const unsigned int file_version \ ); \ -template void A::serialize( \ - boost::archive::binary_oarchive & ar, \ +template void A::serialize( \ + oarchive & ar, \ const unsigned int file_version \ ); diff --git a/src/core/core.cpp b/src/core/core.cpp index cee6a3866..63730214f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -397,22 +397,28 @@ void System::Reset() { template void System::serialize(Archive & ar, const unsigned int file_version) { - ar & memory; ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); + ar & memory; } void System::Save(std::ostream &stream) const { - boost::archive::binary_oarchive oa{stream}; - oa & *this; + { + oarchive oa{stream}; + oa & *this; + } + VideoCore::Save(stream); } void System::Load(std::istream &stream) { - boost::archive::binary_iarchive ia{stream}; - ia & *this; + { + iarchive ia{stream}; + ia & *this; + } + VideoCore::Load(stream); } } // namespace Core diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index fcb60e6fe..b283b7d91 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -472,14 +472,7 @@ inline void Write(u32 addr, const T data) { if (config.trigger & 1) { MICROPROFILE_SCOPE(GPU_CmdlistProcessing); - u32* buffer = (u32*)g_memory->GetPhysicalPointer(config.GetPhysicalAddress()); - - if (Pica::g_debug_context && Pica::g_debug_context->recorder) { - Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, config.size, - config.GetPhysicalAddress()); - } - - Pica::CommandProcessor::ProcessCommandList(buffer, config.size); + Pica::CommandProcessor::ProcessCommandList(config.GetPhysicalAddress(), config.size); g_regs.command_processor_config.trigger = 0; } diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 4cb976354..8dbf5d8e0 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -94,7 +94,7 @@ endif() create_target_directory_groups(video_core) target_link_libraries(video_core PUBLIC common core) -target_link_libraries(video_core PRIVATE glad nihstro-headers) +target_link_libraries(video_core PRIVATE glad nihstro-headers boost_libs) if (ARCHITECTURE_x86_64) target_link_libraries(video_core PUBLIC xbyak) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 72f6f2161..3a5b35236 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -640,8 +640,17 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { reinterpret_cast(&id)); } -void ProcessCommandList(const u32* list, u32 size) { - g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = list; +void ProcessCommandList(PAddr list, u32 size) { + + u32* buffer = (u32*)VideoCore::g_memory->GetPhysicalPointer(list); + + if (Pica::g_debug_context && Pica::g_debug_context->recorder) { + Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, size, + list); + } + + g_state.cmd_list.addr = list; + g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = buffer; g_state.cmd_list.length = size / sizeof(u32); while (g_state.cmd_list.current_ptr < g_state.cmd_list.head_ptr + g_state.cmd_list.length) { diff --git a/src/video_core/command_processor.h b/src/video_core/command_processor.h index 82b154327..3b4e05519 100644 --- a/src/video_core/command_processor.h +++ b/src/video_core/command_processor.h @@ -32,6 +32,6 @@ static_assert(std::is_standard_layout::value == true, "CommandHeader does not use standard layout"); static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!"); -void ProcessCommandList(const u32* list, u32 size); +void ProcessCommandList(PAddr list, u32 size); } // namespace Pica::CommandProcessor diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 5a97ae952..1e5b1ecd2 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -5,6 +5,7 @@ #pragma once #include +#include "boost/serialization/split_member.hpp" #include "common/bit_field.h" #include "common/common_types.h" #include "common/vector_math.h" @@ -13,6 +14,18 @@ #include "video_core/regs.h" #include "video_core/shader/shader.h" +// NB, by defining this we can't use the built-in std::array serializer in this file +namespace boost::serialization { + +template +void serialize(Archive & ar, std::array &array, const unsigned int version) +{ + static_assert(sizeof(Value) == sizeof(u32)); + ar & *static_cast(static_cast(array.data())); +} + +} + namespace Pica { /// Struct used to describe current Pica state @@ -79,6 +92,18 @@ struct State { std::array alpha_map_table; std::array color_table; std::array color_diff_table; + + private: + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & noise_table; + ar & color_map_table; + ar & alpha_map_table; + ar & color_table; + ar & color_diff_table; + } } proctex; struct Lighting { @@ -101,6 +126,12 @@ struct State { float diff = static_cast(difference) / 2047.f; return neg_difference ? -diff : diff; } + + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & raw; + } }; std::array, 24> luts; @@ -126,8 +157,11 @@ struct State { std::array lut; } fog; +#undef SERIALIZE_RAW + /// Current Pica command list struct { + PAddr addr; // This exists only for serialization const u32* head_ptr; const u32* current_ptr; u32 length; @@ -141,6 +175,17 @@ struct State { u32 current_attribute = 0; // Indicates the immediate mode just started and the geometry pipeline needs to reconfigure bool reset_geometry_pipeline = true; + + private: + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + // ar & input_vertex; + ar & current_attribute; + ar & reset_geometry_pipeline; + } + } immediate; // the geometry shader needs to be kept in the global state because some shaders relie on @@ -161,6 +206,51 @@ struct State { int default_attr_counter = 0; u32 default_attr_write_buffer[3]{}; + +private: + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & regs.reg_array; + // ar & vs; + // ar & gs; + // ar & input_default_attributes; + ar & proctex; + for (auto i = 0; i < lighting.luts.size(); i++) { + ar & lighting.luts[i]; + } + ar & fog.lut; + ar & cmd_list.addr; + ar & cmd_list.length; + ar & immediate; + // ar & gs_unit; + // ar & geometry_pipeline; + // ar & primitive_assembler; + ar & vs_float_regs_counter; + ar & vs_uniform_write_buffer; + ar & gs_float_regs_counter; + ar & gs_uniform_write_buffer; + ar & default_attr_counter; + ar & default_attr_write_buffer; + boost::serialization::split_member(ar, *this, file_version); + } + + template + void save(Archive & ar, const unsigned int file_version) const + { + ar << static_cast(cmd_list.current_ptr - cmd_list.head_ptr); + } + + template + void load(Archive & ar, const unsigned int file_version) + { + u32 offset{}; + ar >> offset; + cmd_list.head_ptr = (u32*)VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr); + cmd_list.current_ptr = cmd_list.head_ptr + offset; + } }; extern State g_state; ///< Current Pica state diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index b7e1d4885..5bc1e8702 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -3,9 +3,11 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/logging/log.h" #include "core/settings.h" #include "video_core/pica.h" +#include "video_core/pica_state.h" #include "video_core/renderer_base.h" #include "video_core/renderer_opengl/gl_vars.h" #include "video_core/renderer_opengl/renderer_opengl.h" @@ -85,4 +87,18 @@ u16 GetResolutionScaleFactor() { } } +void Save(std::ostream &stream) +{ + oarchive oa{stream}; + oa & Pica::g_state; +} + +void Load(std::istream &stream) +{ + iarchive ia{stream}; + ia & Pica::g_state; + // TODO: Flush/reset things + +} + } // namespace VideoCore diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index f11b67839..1ec69f802 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include "core/frontend/emu_window.h" @@ -61,4 +62,7 @@ void RequestScreenshot(void* data, std::function callback, u16 GetResolutionScaleFactor(); +void Save(std::ostream &stream); +void Load(std::istream &stream); + } // namespace VideoCore From 45788b9c825c5361cca5614465fdec64ab7a5cd5 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 8 Aug 2019 05:25:24 +0100 Subject: [PATCH 005/129] Added shader state serialization --- src/common/vector_math.h | 28 ++++++++++++++++++++++++++++ src/video_core/pica_state.h | 30 ++++++++++++++++-------------- src/video_core/pica_types.h | 8 ++++++++ src/video_core/shader/shader.h | 24 ++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/common/vector_math.h b/src/common/vector_math.h index ba36744fc..171d4ebfd 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -32,6 +32,7 @@ #include #include +#include namespace Common { @@ -44,6 +45,14 @@ class Vec4; template class Vec2 { + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & x; + ar & y; + } + public: T x; T y; @@ -191,6 +200,15 @@ inline float Vec2::Normalize() { template class Vec3 { + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & x; + ar & y; + ar & z; + } + public: T x; T y; @@ -399,6 +417,16 @@ using Vec3f = Vec3; template class Vec4 { + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & x; + ar & y; + ar & z; + ar & w; + } + public: T x; T y; diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 1e5b1ecd2..10d1e637b 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -14,11 +14,15 @@ #include "video_core/regs.h" #include "video_core/shader/shader.h" -// NB, by defining this we can't use the built-in std::array serializer in this file +// Boost::serialization doesn't like union types for some reason, +// so we need to mark arrays of union values with a special serialization method +template +struct UnionArray : public std::array { }; + namespace boost::serialization { template -void serialize(Archive & ar, std::array &array, const unsigned int version) +void serialize(Archive& ar, UnionArray& array, const unsigned int version) { static_assert(sizeof(Value) == sizeof(u32)); ar & *static_cast(static_cast(array.data())); @@ -87,11 +91,11 @@ struct State { } }; - std::array noise_table; - std::array color_map_table; - std::array alpha_map_table; - std::array color_table; - std::array color_diff_table; + UnionArray noise_table; + UnionArray color_map_table; + UnionArray alpha_map_table; + UnionArray color_table; + UnionArray color_diff_table; private: friend class boost::serialization::access; @@ -134,7 +138,7 @@ struct State { } }; - std::array, 24> luts; + std::array, 24> luts; } lighting; struct { @@ -154,7 +158,7 @@ struct State { } }; - std::array lut; + UnionArray lut; } fog; #undef SERIALIZE_RAW @@ -214,13 +218,11 @@ private: void serialize(Archive & ar, const unsigned int file_version) { ar & regs.reg_array; - // ar & vs; - // ar & gs; + ar & vs; + ar & gs; // ar & input_default_attributes; ar & proctex; - for (auto i = 0; i < lighting.luts.size(); i++) { - ar & lighting.luts[i]; - } + ar & lighting.luts; ar & fog.lut; ar & cmd_list.addr; ar & cmd_list.length; diff --git a/src/video_core/pica_types.h b/src/video_core/pica_types.h index 5aca37b69..bef256e13 100644 --- a/src/video_core/pica_types.h +++ b/src/video_core/pica_types.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" namespace Pica { @@ -140,6 +141,13 @@ private: // Stored as a regular float, merely for convenience // TODO: Perform proper arithmetic on this! float value; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & value; + } }; using float24 = Float<16, 7>; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index bb6a5fae7..3f55d3064 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -193,6 +194,16 @@ struct Uniforms { static std::size_t GetIntUniformOffset(unsigned index) { return offsetof(Uniforms, i) + index * sizeof(Common::Vec4); } + +private: + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & f; + ar & b; + ar & i; + } }; struct ShaderSetup { @@ -237,6 +248,19 @@ private: bool swizzle_data_hash_dirty = true; u64 program_code_hash = 0xDEADC0DE; u64 swizzle_data_hash = 0xDEADC0DE; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int file_version) + { + ar & uniforms; + ar & program_code; + ar & swizzle_data; + ar & program_code_hash_dirty; + ar & swizzle_data_hash_dirty; + ar & program_code_hash; + ar & swizzle_data_hash; + } }; class ShaderEngine { From f79c9668a3a271a5038bb9d55bf32e701c678a11 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 11 Aug 2019 00:20:09 +0100 Subject: [PATCH 006/129] Added shader state; WIP kernel objects --- externals/boost | 2 +- src/common/CMakeLists.txt | 2 + src/common/serialization/atomic.h | 28 ++++ src/common/serialization/boost_vector.hpp | 189 ++++++++++++++++++++++ src/core/core.cpp | 6 +- src/core/hle/kernel/client_port.cpp | 5 +- src/core/hle/kernel/client_port.h | 16 +- src/core/hle/kernel/event.h | 10 ++ src/core/hle/kernel/handle_table.h | 12 ++ src/core/hle/kernel/kernel.cpp | 23 +++ src/core/hle/kernel/kernel.h | 9 ++ src/core/hle/kernel/memory.h | 11 ++ src/core/hle/kernel/mutex.h | 12 ++ src/core/hle/kernel/object.cpp | 12 +- src/core/hle/kernel/object.h | 11 ++ src/core/hle/kernel/process.cpp | 14 +- src/core/hle/kernel/process.h | 65 +++++++- src/core/hle/kernel/resource_limit.cpp | 6 +- src/core/hle/kernel/resource_limit.h | 40 ++++- src/core/hle/kernel/semaphore.h | 11 ++ src/core/hle/kernel/server_port.cpp | 9 +- src/core/hle/kernel/server_port.h | 2 - src/core/hle/kernel/server_session.cpp | 5 +- src/core/hle/kernel/server_session.h | 2 +- src/core/hle/kernel/thread.cpp | 9 +- src/core/hle/kernel/thread.h | 2 +- src/core/hle/kernel/vm_manager.h | 28 +++- src/core/hle/kernel/wait_object.h | 14 ++ src/core/hle/service/err_f.cpp | 1 + src/core/memory.cpp | 23 +-- src/core/mmio.h | 7 + src/video_core/pica_state.h | 6 +- src/video_core/shader/shader.h | 52 ++++++ 33 files changed, 576 insertions(+), 68 deletions(-) create mode 100644 src/common/serialization/atomic.h create mode 100644 src/common/serialization/boost_vector.hpp diff --git a/externals/boost b/externals/boost index d2a5baa1a..48130d387 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit d2a5baa1ad701671a7ef547ef71cb0f0c80ce2cf +Subproject commit 48130d387975d17aed1b34ef75c21020f2d710a8 diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 5abf93dbc..b0577f9d9 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -90,6 +90,8 @@ add_library(common STATIC scm_rev.cpp scm_rev.h scope_exit.h + serialization/atomic.h + serialization/boost_vector.hpp string_util.cpp string_util.h swap.h diff --git a/src/common/serialization/atomic.h b/src/common/serialization/atomic.h new file mode 100644 index 000000000..ef33202ff --- /dev/null +++ b/src/common/serialization/atomic.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +namespace boost::serialization +{ + template + void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) + { + boost::serialization::split_free(ar, value, file_version); + } + + template + void save(Archive& ar, const std::atomic& value, const unsigned int file_version) + { + ar << value.load(); + } + + template + void load(Archive& ar, std::atomic& value, const unsigned int file_version) + { + T tmp; + ar >> tmp; + value.store(tmp); + } + +} // namespace boost::serialization diff --git a/src/common/serialization/boost_vector.hpp b/src/common/serialization/boost_vector.hpp new file mode 100644 index 000000000..d97ebd208 --- /dev/null +++ b/src/common/serialization/boost_vector.hpp @@ -0,0 +1,189 @@ +#ifndef BOOST_SERIALIZATION_BOOST_VECTOR_HPP +#define BOOST_SERIALIZATION_BOOST_VECTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// boost_vector.hpp: serialization for boost vector templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// fast array serialization (C) Copyright 2005 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// default is being compatible with version 1.34.1 files, not 1.35 files +#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector< T > + +// the default versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + boost::serialization::stl::save_collection >( + ar, t + ); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + t.reserve(count); + stl::collection_load_impl(ar, t, count, item_version); +} + +// the optimized versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array( + static_cast(&t[0]), + count + ); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + collection_size_type count(t.size()); + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + unsigned int item_version=0; + if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array( + static_cast(&t[0]), + count + ); + } + +// dispatch to either default or optimized versions + +template +inline void save( + Archive & ar, + const boost::container::vector &t, + const unsigned int file_version +){ + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + save(ar,t,file_version, use_optimized()); +} + +template +inline void load( + Archive & ar, + boost::container::vector &t, + const unsigned int file_version +){ +#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP + if (ar.get_library_version()==boost::archive::library_version_type(5)) + { + load(ar,t,file_version, boost::is_arithmetic()); + return; + } +#endif + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + load(ar,t,file_version, use_optimized()); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + boost::container::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + boost::container::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(boost::container::vector) + +#endif // BOOST_SERIALIZATION_VECTOR_HPP diff --git a/src/core/core.cpp b/src/core/core.cpp index 63730214f..902340d41 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -5,7 +5,6 @@ #include #include #include "boost/serialization/array.hpp" -#include "boost/serialization/unique_ptr.hpp" #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" @@ -205,6 +204,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo kernel = std::make_unique(*memory, *timing, [this] { PrepareReschedule(); }, system_mode); + Kernel::g_kernel = kernel.get(); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -368,6 +368,7 @@ void System::Shutdown() { service_manager.reset(); dsp_core.reset(); cpu_core.reset(); + Kernel::g_kernel = nullptr; kernel.reset(); timing.reset(); app_loader.reset(); @@ -400,7 +401,8 @@ void System::serialize(Archive & ar, const unsigned int file_version) ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); - ar & memory; + ar & *memory.get(); + ar & *kernel.get(); } void System::Save(std::ostream &stream) const diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index d217dfb7c..dc0e08d9d 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -13,9 +13,6 @@ namespace Kernel { -ClientPort::ClientPort(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} -ClientPort::~ClientPort() = default; - ResultVal> ClientPort::Connect() { // Note: Threads do not wait for the server endpoint to call // AcceptSession before returning from this call. @@ -26,7 +23,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto [server, client] = kernel.CreateSessionPair(server_port->GetName(), SharedFrom(this)); + auto [server, client] = g_kernel->CreateSessionPair(server_port->GetName(), SharedFrom(this)); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(server); diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 423db0172..35544e37e 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -17,8 +17,6 @@ class ClientSession; class ClientPort final : public Object { public: - explicit ClientPort(KernelSystem& kernel); - ~ClientPort() override; friend class ServerPort; std::string GetTypeName() const override { @@ -52,13 +50,25 @@ public: void ConnectionClosed(); private: - KernelSystem& kernel; std::shared_ptr server_port; ///< ServerPort associated with this client port. u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have u32 active_sessions = 0; ///< Number of currently open sessions to this port std::string name; ///< Name of client port (optional) friend class KernelSystem; + + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & server_port; + ar & max_sessions; + ar & active_sessions; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index efc4a0c28..9e9da267a 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -49,6 +49,16 @@ private: std::string name; ///< Name of event (optional) friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & reset_type; + ar & signaled; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index bd5a5df6a..eabf06c26 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" @@ -116,6 +118,16 @@ private: u16 next_free_slot; KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & objects; + ar & generations; + ar & next_generation; + ar & next_free_slot; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ceb2f14f5..d8bd0f034 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" +#include "common/serialization/atomic.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/config_mem.h" #include "core/hle/kernel/handle_table.h" @@ -16,6 +18,8 @@ namespace Kernel { +KernelSystem* g_kernel; + /// Initialize the kernel KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, std::function prepare_reschedule_callback, u32 system_mode) @@ -101,4 +105,23 @@ void KernelSystem::AddNamedPort(std::string name, std::shared_ptr po named_ports.emplace(std::move(name), std::move(port)); } +template +void KernelSystem::serialize(Archive& ar, const unsigned int file_version) +{ + ar & named_ports; + // TODO: CPU + // NB: subsystem references and prepare_reschedule_callback are constant + ar & *resource_limits.get(); + ar & next_object_id; + //ar & *timer_manager.get(); + ar & next_process_id; + ar & process_list; + ar & current_process; + // ar & *thread_manager.get(); + //ar & *config_mem_handler.get(); + //ar & *shared_page_handler.get(); +} + +SERIALIZE_IMPL(KernelSystem) + } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 58f63938b..c662882f5 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/memory.h" #include "core/hle/result.h" @@ -283,6 +286,12 @@ private: std::unique_ptr shared_page_handler; std::unique_ptr ipc_recorder; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version); }; +extern KernelSystem* g_kernel; + } // namespace Kernel diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index bb4e174f7..9e9fe5eb4 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -60,6 +60,17 @@ struct MemoryRegionInfo { * @param size the size of the region to free. */ void Free(u32 offset, u32 size); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & base; + ar & size; + ar & used; + // TODO: boost icl / free_blocks + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 1f6358909..618685451 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -58,6 +58,18 @@ public: private: KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & lock_count; + ar & priority; + ar & name; + ar & holding_thread; + ar & kernel; // TODO: Check that this works! + } }; /** diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index f9ca68218..6ab1b1769 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp @@ -8,7 +8,17 @@ namespace Kernel { -Object::Object(KernelSystem& kernel) : object_id{kernel.GenerateObjectID()} {} +// TODO: Remove this +Object::Object(KernelSystem& kernel) +{ +} + +Object::Object() = default; + +void Object::Init(KernelSystem& kernel) +{ + object_id = kernel.GenerateObjectID(); +} Object::~Object() = default; diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 9547a83ed..8998cb88d 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/kernel.h" @@ -41,8 +42,11 @@ enum { class Object : NonCopyable, public std::enable_shared_from_this { public: explicit Object(KernelSystem& kernel); + Object(); virtual ~Object(); + virtual void Init(KernelSystem& kernel); + /// Returns a unique identifier for the object. For debugging purposes only. u32 GetObjectId() const { return object_id.load(std::memory_order_relaxed); @@ -64,6 +68,13 @@ public: private: std::atomic object_id; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & object_id; + } }; template diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c6aa2b895..63a5c3b68 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -18,7 +18,8 @@ namespace Kernel { std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { - auto codeset{std::make_shared(*this)}; + auto codeset{std::make_shared()}; + codeset->Init(*this); codeset->name = std::move(name); codeset->program_id = program_id; @@ -26,11 +27,9 @@ std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 progr return codeset; } -CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {} -CodeSet::~CodeSet() {} - std::shared_ptr KernelSystem::CreateProcess(std::shared_ptr code_set) { - auto process{std::make_shared(*this)}; + auto process{std::make_shared()}; + process->Init(*this); process->codeset = std::move(code_set); process->flags.raw = 0; @@ -401,9 +400,8 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe return RESULT_SUCCESS; } -Kernel::Process::Process(KernelSystem& kernel) - : Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) { - +Kernel::Process::Process() : kernel(*g_kernel), handle_table(*g_kernel), vm_manager(g_kernel->memory) +{ kernel.memory.RegisterPageTable(&vm_manager.page_table); } Kernel::Process::~Process() { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index dc2c878b8..6defd42c6 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,8 +11,13 @@ #include #include #include +#include +#include +#include +#include #include "common/bit_field.h" #include "common/common_types.h" +#include "common/serialization/boost_vector.hpp" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/vm_manager.h" @@ -25,6 +30,17 @@ struct AddressMapping { u32 size; bool read_only; bool unk_flag; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & address; + ar & size; + ar & read_only; + ar & unk_flag; + } }; union ProcessFlags { @@ -52,13 +68,20 @@ struct MemoryRegionInfo; class CodeSet final : public Object { public: - explicit CodeSet(KernelSystem& kernel); - ~CodeSet() override; - struct Segment { std::size_t offset = 0; VAddr addr = 0; u32 size = 0; + + private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & offset; + ar & addr; + ar & size; + } }; std::string GetTypeName() const override { @@ -106,11 +129,24 @@ public: std::string name; /// Title ID corresponding to the process u64 program_id; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + // TODO: memory reference + ar & segments; + ar & entrypoint; + ar & name; + ar & program_id; + } }; class Process final : public Object { public: - explicit Process(Kernel::KernelSystem& kernel); + explicit Process(); ~Process() override; std::string GetTypeName() const override { @@ -195,5 +231,26 @@ public: private: KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & handle_table; + ar & codeset; + ar & resource_limit; + ar & svc_access_mask; + ar & handle_table_size; + ar & (boost::container::vector >&)address_mappings; + ar & flags.raw; + ar & kernel_version; + ar & ideal_processor; + ar & process_id; + ar & vm_manager; + ar & memory_used; + ar & memory_region; + ar & tls_slots; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 8691c142e..fe19caff9 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -9,11 +9,9 @@ namespace Kernel { -ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {} -ResourceLimit::~ResourceLimit() {} - std::shared_ptr ResourceLimit::Create(KernelSystem& kernel, std::string name) { - auto resource_limit{std::make_shared(kernel)}; + auto resource_limit{std::make_shared()}; + resource_limit->Init(kernel); resource_limit->name = std::move(name); return resource_limit; diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 99ae8f2cf..06fe71587 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" @@ -33,8 +35,6 @@ enum ResourceTypes { class ResourceLimit final : public Object { public: - explicit ResourceLimit(KernelSystem& kernel); - ~ResourceLimit() override; /** * Creates a resource limit object. @@ -110,6 +110,35 @@ public: /// Current CPU time that the processes in this category are utilizing s32 current_cpu_time = 0; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + // NB most of these aren't used at all currently, but we're adding them here for forwards compatibility + ar & name; + ar & max_priority; + ar & max_commit; + ar & max_threads; + ar & max_events; + ar & max_mutexes; + ar & max_semaphores; + ar & max_timers; + ar & max_shared_mems; + ar & max_address_arbiters; + ar & max_cpu_time; + ar & current_commit; + ar & current_threads; + ar & current_events; + ar & current_mutexes; + ar & current_semaphores; + ar & current_timers; + ar & current_shared_mems; + ar & current_address_arbiters; + ar & current_cpu_time; + } }; class ResourceLimitList { @@ -126,6 +155,13 @@ public: private: std::array, 4> resource_limits; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & resource_limits; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 47b3eabf1..526be6812 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -43,6 +43,17 @@ public: * @return The number of free slots the semaphore had before this call */ ResultVal Release(s32 release_count); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & max_count; + ar & available_count; + ar & name; + } }; } // namespace Kernel diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index a69b42778..ca4cded3d 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -13,9 +13,6 @@ namespace Kernel { -ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {} -ServerPort::~ServerPort() {} - ResultVal> ServerPort::Accept() { if (pending_sessions.empty()) { return ERR_NO_PENDING_SESSIONS; @@ -36,8 +33,10 @@ void ServerPort::Acquire(Thread* thread) { } KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::string name) { - auto server_port{std::make_shared(*this)}; - auto client_port{std::make_shared(*this)}; + auto server_port{std::make_shared()}; + server_port->Init(*this); + auto client_port{std::make_shared()}; + client_port->Init(*this); server_port->name = name + "_Server"; client_port->name = name + "_Client"; diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 9b0f13480..c500fd1b2 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -20,8 +20,6 @@ class SessionRequestHandler; class ServerPort final : public WaitObject { public: - explicit ServerPort(KernelSystem& kernel); - ~ServerPort() override; std::string GetTypeName() const override { return "ServerPort"; diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 5855d83a5..c6a6261a5 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -13,7 +13,7 @@ namespace Kernel { -ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} +ServerSession::ServerSession() : kernel(*g_kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. @@ -30,7 +30,8 @@ ServerSession::~ServerSession() { ResultVal> ServerSession::Create(KernelSystem& kernel, std::string name) { - auto server_session{std::make_shared(kernel)}; + auto server_session{std::make_shared()}; + server_session->Init(kernel); server_session->name = std::move(name); server_session->parent = nullptr; diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 940f38f9b..3536bcbd1 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -38,7 +38,7 @@ class Thread; class ServerSession final : public WaitObject { public: ~ServerSession() override; - explicit ServerSession(KernelSystem& kernel); + explicit ServerSession(); std::string GetName() const override { return name; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 3b15ec35e..4c2344dcb 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -37,9 +37,9 @@ u32 ThreadManager::NewThreadId() { return next_thread_id++; } -Thread::Thread(KernelSystem& kernel) - : WaitObject(kernel), context(kernel.GetThreadManager().NewContext()), - thread_manager(kernel.GetThreadManager()) {} +Thread::Thread() + : context(g_kernel->GetThreadManager().NewContext()), + thread_manager(g_kernel->GetThreadManager()) {} Thread::~Thread() {} Thread* ThreadManager::GetCurrentThread() const { @@ -309,7 +309,8 @@ ResultVal> KernelSystem::CreateThread(std::string name, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } - auto thread{std::make_shared(*this)}; + auto thread{std::make_shared()}; + thread->Init(*this); thread_manager->thread_list.push_back(thread); thread_manager->ready_queue.prepare(priority); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index f2ef767ef..2db5dda91 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -149,7 +149,7 @@ private: class Thread final : public WaitObject { public: - explicit Thread(KernelSystem&); + explicit Thread(); ~Thread() override; std::string GetName() const override { diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 0d3ae1e44..6711c9b4d 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -8,7 +8,8 @@ #include #include #include -#include "boost/serialization/split_member.hpp" +#include +#include #include "common/common_types.h" #include "core/hle/result.h" #include "core/memory.h" @@ -81,6 +82,21 @@ struct VirtualMemoryArea { /// Tests if this area can be merged to the right with `next`. bool CanBeMergedWith(const VirtualMemoryArea& next) const; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & base; + ar & size; + ar & type; + ar & permissions; + ar & meminfo_state; + // TODO: backing memory ref + ar & paddr; + ar & mmio_handler; + } }; /** @@ -195,9 +211,10 @@ public: private: friend class boost::serialization::access; - template - void save(Archive & ar, const unsigned int file_version) + template + void save(Archive& ar, const unsigned int file_version) const { + ar & vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { ar << memory.GetFCRAMOffset(page_table.pointers[i]); } @@ -205,9 +222,10 @@ private: ar & page_table.attributes; } - template - void load(Archive & ar, const unsigned int file_version) + template + void load(Archive& ar, const unsigned int file_version) { + ar & vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { u32 offset{}; ar >> offset; diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index 41e803515..e08997721 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" @@ -62,6 +65,17 @@ private: /// Function to call when this object becomes available std::function hle_notifier; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & waiting_threads; + // NB: hle_notifier *not* serialized since it's a callback! + // Fortunately it's only used in one place (DSP) so we can reconstruct it there + } }; // Specialization of DynamicObjectCast for WaitObjects diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 13b2c7e46..b218eb793 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -14,6 +14,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/err_f.h" +#undef exception_info namespace Service::ERR { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index fe33cf767..a07cc2e13 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -5,8 +5,7 @@ #include #include #include "boost/serialization/array.hpp" -#include "boost/serialization/nvp.hpp" -#include "boost/serialization/unique_ptr.hpp" +#include "boost/serialization/binary_object.hpp" #include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" @@ -84,23 +83,17 @@ public: 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 serialize(Archive & ar, const unsigned int file_version) { // TODO: Skip n3ds ram when not used? - 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); + auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); + auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); + auto s_extra = boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); + ar & s_fcram; + ar & s_vram; + ar & s_extra; ar & cache_marker; // TODO: How the hell to do page tables.. // ar & page_table_list; @@ -114,7 +107,7 @@ MemorySystem::~MemorySystem() = default; template void MemorySystem::serialize(Archive & ar, const unsigned int file_version) { - ar & impl; + ar & *impl.get(); } SERIALIZE_IMPL(MemorySystem) diff --git a/src/core/mmio.h b/src/core/mmio.h index 30bafaf5f..0a8249c9a 100644 --- a/src/core/mmio.h +++ b/src/core/mmio.h @@ -32,6 +32,13 @@ public: virtual void Write64(VAddr addr, u64 data) = 0; virtual bool WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size) = 0; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + } }; using MMIORegionPointer = std::shared_ptr; diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 10d1e637b..376865397 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -161,8 +161,6 @@ struct State { UnionArray lut; } fog; -#undef SERIALIZE_RAW - /// Current Pica command list struct { PAddr addr; // This exists only for serialization @@ -185,7 +183,7 @@ struct State { template void serialize(Archive & ar, const unsigned int file_version) { - // ar & input_vertex; + ar & input_vertex; ar & current_attribute; ar & reset_geometry_pipeline; } @@ -220,7 +218,7 @@ private: ar & regs.reg_array; ar & vs; ar & gs; - // ar & input_default_attributes; + ar & input_default_attributes; ar & proctex; ar & lighting.luts; ar & fog.lut; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 3f55d3064..1a0f6ef8a 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -32,6 +33,14 @@ using SwizzleData = std::array; struct AttributeBuffer { alignas(16) Common::Vec4 attr[16]; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & attr; + } }; /// Handler type for receiving vertex outputs from vertex shader or geometry shader @@ -91,6 +100,19 @@ struct GSEmitter { GSEmitter(); ~GSEmitter(); void Emit(Common::Vec4 (&output_regs)[16]); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & buffer; + ar & vertex_id; + ar & prim_emit; + ar & winding; + ar & output_mask; + // Handlers are ignored because they're constant + } }; static_assert(std::is_standard_layout::value, "GSEmitter is not standard layout type"); @@ -108,6 +130,16 @@ struct UnitState { alignas(16) Common::Vec4 input[16]; alignas(16) Common::Vec4 temporary[16]; alignas(16) Common::Vec4 output[16]; + + private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & input; + ar & temporary; + ar & output; + } } registers; static_assert(std::is_pod::value, "Structure is not POD"); @@ -160,6 +192,17 @@ struct UnitState { void LoadInput(const ShaderRegs& config, const AttributeBuffer& input); void WriteOutput(const ShaderRegs& config, AttributeBuffer& output); + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & registers; + ar & conditional_code; + ar & address_registers; + // TODO: emitter_ptr + } }; /** @@ -173,6 +216,15 @@ struct GSUnitState : public UnitState { void ConfigOutput(const ShaderRegs& config); GSEmitter emitter; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & emitter; + } }; struct Uniforms { From 5035e68dadbdef6c8e6d5b856f8d15462a515faf Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 11 Aug 2019 15:19:45 +0100 Subject: [PATCH 007/129] Added derived kernel objects --- externals/boost | 2 +- src/common/archives.h | 5 +++++ src/core/hle/kernel/address_arbiter.cpp | 8 ++++++-- src/core/hle/kernel/address_arbiter.h | 17 ++++++++++++++++- src/core/hle/kernel/object.h | 1 + 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/externals/boost b/externals/boost index 48130d387..19ccdcc6f 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 48130d387975d17aed1b34ef75c21020f2d710a8 +Subproject commit 19ccdcc6fbd026f98ed83dea32ff0398120fbb32 diff --git a/src/common/archives.h b/src/common/archives.h index 490710d3c..f30886d90 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -12,3 +12,8 @@ template void A::serialize( \ oarchive & ar, \ const unsigned int file_version \ ); + +#define SERIALIZE_EXPORT_IMPL(A) \ +BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ +BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) \ +BOOST_CLASS_EXPORT_IMPLEMENT(A) diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index e52c0f272..c4fb4fd99 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/hle/kernel/address_arbiter.h" @@ -14,6 +15,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // Kernel namespace +SERIALIZE_EXPORT_IMPL(Kernel::AddressArbiter) + namespace Kernel { void AddressArbiter::WaitThread(std::shared_ptr thread, VAddr wait_address) { @@ -65,11 +68,12 @@ std::shared_ptr AddressArbiter::ResumeHighestPriorityThread(VAddr addres return thread; } -AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} +AddressArbiter::AddressArbiter() : kernel(*g_kernel) {} AddressArbiter::~AddressArbiter() {} std::shared_ptr KernelSystem::CreateAddressArbiter(std::string name) { - auto address_arbiter{std::make_shared(*this)}; + auto address_arbiter{std::make_shared()}; + address_arbiter->Init(*this); address_arbiter->name = std::move(name); diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index a4aff6a6e..3b29a84a4 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -6,6 +6,10 @@ #include #include +#include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" @@ -32,7 +36,7 @@ enum class ArbitrationType : u32 { class AddressArbiter final : public Object { public: - explicit AddressArbiter(KernelSystem& kernel); + explicit AddressArbiter(); ~AddressArbiter() override; std::string GetTypeName() const override { @@ -67,6 +71,17 @@ private: /// Threads waiting for the address arbiter to be signaled. std::vector> waiting_threads; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & name; + ar & waiting_threads; + } }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter) diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 8998cb88d..6adba034e 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -8,6 +8,7 @@ #include #include #include +#include "common/serialization/atomic.h" #include "common/common_types.h" #include "core/hle/kernel/kernel.h" From 06891d94542fcf5ec6e1c45435df097d48b8ca77 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 11 Aug 2019 22:29:00 +0100 Subject: [PATCH 008/129] Added client/server objects --- src/core/CMakeLists.txt | 1 + src/core/hle/kernel/client_port.cpp | 3 +++ src/core/hle/kernel/client_port.h | 3 +++ src/core/hle/kernel/client_session.cpp | 6 ++++-- src/core/hle/kernel/client_session.h | 17 ++++++++++++++++- src/core/hle/kernel/server_port.cpp | 3 +++ src/core/hle/kernel/server_port.h | 18 ++++++++++++++++++ src/core/hle/kernel/server_session.cpp | 7 +++++-- src/core/hle/kernel/server_session.h | 19 +++++++++++++++++++ src/core/hle/kernel/session.cpp | 18 +++++++++++++++--- src/core/hle/kernel/session.h | 6 ++++++ 11 files changed, 93 insertions(+), 8 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ed2642431..9ed9a856d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -162,6 +162,7 @@ add_library(core STATIC hle/kernel/server_session.cpp hle/kernel/server_session.h hle/kernel/session.h + hle/kernel/session.cpp hle/kernel/shared_memory.cpp hle/kernel/shared_memory.h hle/kernel/shared_page.cpp diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index dc0e08d9d..3334a278b 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/assert.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" @@ -11,6 +12,8 @@ #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" +SERIALIZE_EXPORT_IMPL(Kernel::ClientPort) + namespace Kernel { ResultVal> ClientPort::Connect() { diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 35544e37e..72cae85c3 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" @@ -72,3 +73,5 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ClientPort) diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 3e76f1a4e..ba9c2ec50 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include "common/assert.h" - +#include "common/archives.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/hle_ipc.h" @@ -11,9 +11,11 @@ #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::ClientSession) + namespace Kernel { -ClientSession::ClientSession(KernelSystem& kernel) : Object(kernel) {} +ClientSession::ClientSession() = default; ClientSession::~ClientSession() { // This destructor will be called automatically when the last ClientSession handle is closed by // the emulated application. diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index de2c7b0ba..2ffe68f8b 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -6,6 +6,9 @@ #include #include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" @@ -17,7 +20,7 @@ class Thread; class ClientSession final : public Object { public: - explicit ClientSession(KernelSystem& kernel); + explicit ClientSession(); ~ClientSession() override; friend class KernelSystem; @@ -46,6 +49,18 @@ public: /// The parent session, which links to the server endpoint. std::shared_ptr parent; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & name; + ar & parent; + } }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ClientSession) diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index ca4cded3d..191b43ea8 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/assert.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/errors.h" @@ -11,6 +12,8 @@ #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::ServerPort) + namespace Kernel { ResultVal> ServerPort::Accept() { diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index c500fd1b2..e0014ee7c 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -7,8 +7,13 @@ #include #include #include +#include +#include +#include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" +#include "core/hle/kernel/server_session.h" #include "core/hle/kernel/wait_object.h" #include "core/hle/result.h" @@ -58,6 +63,19 @@ public: bool ShouldWait(const Thread* thread) const override; void Acquire(Thread* thread) override; + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & name; + ar & pending_sessions; + //ar & hle_handler; + } }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ServerPort) diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index c6a6261a5..f2ceb899e 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include - +#include "common/archives.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" @@ -11,6 +11,8 @@ #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) + namespace Kernel { ServerSession::ServerSession() : kernel(*g_kernel) {} @@ -124,7 +126,8 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { KernelSystem::SessionPair KernelSystem::CreateSessionPair(const std::string& name, std::shared_ptr port) { auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap(); - auto client_session{std::make_shared(*this)}; + auto client_session{std::make_shared()}; + client_session->Init(*this); client_session->name = name + "_Client"; std::shared_ptr parent(new Session); diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 3536bcbd1..6112eefac 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -6,10 +6,14 @@ #include #include +#include +#include +#include #include "common/assert.h" #include "common/common_types.h" #include "core/hle/kernel/ipc.h" #include "core/hle/kernel/object.h" +#include "core/hle/kernel/session.h" #include "core/hle/kernel/wait_object.h" #include "core/hle/result.h" #include "core/memory.h" @@ -103,6 +107,21 @@ private: friend class KernelSystem; KernelSystem& kernel; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + ar & name; + ar & parent; + //ar & hle_handler; + ar & pending_requesting_threads; + ar & currently_handling; + //ar & mapped_buffer_context; + } }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ServerSession) diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index 642914744..f264c49bd 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -2,11 +2,23 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include "common/archives.h" #include "core/hle/kernel/session.h" -#include "core/hle/kernel/thread.h" +#include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/client_port.h" + +SERIALIZE_IMPL(Kernel::Session) namespace Kernel { -Session::Session() {} -Session::~Session() {} +template +void Session::serialize(Archive& ar, const unsigned int file_version) +{ + ar & client; + ar & server; + ar & port; +} + } // namespace Kernel diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index 17bb4d6c6..eca1a9252 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "core/hle/kernel/object.h" namespace Kernel { @@ -24,5 +25,10 @@ public: ClientSession* client = nullptr; ///< The client endpoint of the session. ServerSession* server = nullptr; ///< The server endpoint of the session. std::shared_ptr port; ///< The port that this session is associated with (optional). + +private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel From f557d26b40d4cc034bd9599b801ef5bf524d537c Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 12 Aug 2019 17:01:33 +0100 Subject: [PATCH 009/129] Added CPU, mutex, process, thread, timer --- externals/boost | 2 +- src/common/CMakeLists.txt | 1 + src/common/serialization/boost_flat_set.h | 37 ++++++++ src/common/thread_queue_list.h | 31 +++++++ src/core/arm/arm_interface.h | 102 +++++++++++++++++++++- src/core/arm/dynarmic/arm_dynarmic.cpp | 2 +- src/core/arm/dynarmic/arm_dynarmic.h | 2 +- src/core/arm/dyncom/arm_dyncom.cpp | 2 +- src/core/arm/dyncom/arm_dyncom.h | 2 +- src/core/hle/kernel/config_mem.h | 9 ++ src/core/hle/kernel/kernel.cpp | 10 +-- src/core/hle/kernel/mutex.cpp | 5 +- src/core/hle/kernel/mutex.h | 3 +- src/core/hle/kernel/process.cpp | 26 ++++++ src/core/hle/kernel/process.h | 24 +---- src/core/hle/kernel/shared_page.h | 9 ++ src/core/hle/kernel/thread.cpp | 26 ++++++ src/core/hle/kernel/thread.h | 18 ++++ src/core/hle/kernel/timer.cpp | 6 +- src/core/hle/kernel/timer.h | 23 ++++- 20 files changed, 299 insertions(+), 41 deletions(-) create mode 100644 src/common/serialization/boost_flat_set.h diff --git a/externals/boost b/externals/boost index 19ccdcc6f..f4850c297 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 19ccdcc6fbd026f98ed83dea32ff0398120fbb32 +Subproject commit f4850c2975a0d977b7479664b8d4a6f03300a042 diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index b0577f9d9..c0182ed48 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -91,6 +91,7 @@ add_library(common STATIC scm_rev.h scope_exit.h serialization/atomic.h + serialization/boost_flat_set.h serialization/boost_vector.hpp string_util.cpp string_util.h diff --git a/src/common/serialization/boost_flat_set.h b/src/common/serialization/boost_flat_set.h new file mode 100644 index 000000000..9a0ae77b0 --- /dev/null +++ b/src/common/serialization/boost_flat_set.h @@ -0,0 +1,37 @@ +#pragma once + +#include "common/common_types.h" +#include +#include + +namespace boost::serialization { + +template +void save(Archive& ar, const boost::container::flat_set& set, const unsigned int file_version) +{ + ar << static_cast(set.size()); + for (auto &v : set) { + ar << v; + } +} + +template +void load(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) +{ + u64 count{}; + ar >> count; + set.clear(); + for (auto i = 0; i < count; i++) { + T value{}; + ar >> value; + set.insert(value); + } +} + +template +void serialize(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) +{ + boost::serialization::split_free(ar, set, file_version); +} + +} diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 3e3d04b4d..ce57c01e9 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -6,6 +6,9 @@ #include #include +#include +#include +#include "common/common_types.h" namespace Common { @@ -156,6 +159,34 @@ private: Queue* first; // The priority level queues of thread ids. std::array queues; + + friend class boost::serialization::access; + template + void save(Archive& ar, const unsigned int file_version) const + { + s32 idx = first == UnlinkedTag() ? -1 : static_cast(first - &queues[0]); + ar << idx; + for (auto i = 0; i < NUM_QUEUES; i++) { + s32 idx1 = first == UnlinkedTag() ? -1 : static_cast(queues[i].next_nonempty - &queues[0]); + ar << idx1; + ar << queues[i].data; + } + } + + template + void load(Archive& ar, const unsigned int file_version) + { + s32 idx; + ar >> idx; + first = idx < 0 ? UnlinkedTag() : &queues[idx]; + for (auto i = 0; i < NUM_QUEUES; i++) { + ar >> idx; + queues[i].next_nonempty = idx < 0 ? UnlinkedTag() : &queues[idx]; + ar >> queues[i].data; + } + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; } // namespace Common diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 6e6da8626..483ba4371 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" @@ -16,6 +17,48 @@ public: virtual ~ARM_Interface() {} class ThreadContext { + friend class boost::serialization::access; + + template + void save(Archive& ar, const unsigned int file_version) const + { + for (auto i = 0; i < 16; i++) { + auto r = GetCpuRegister(i); + ar << r; + } + for (auto i = 0; i < 16; i++) { + auto r = GetFpuRegister(i); + ar << r; + } + auto r1 = GetCpsr(); + ar << r1; + auto r2 = GetFpscr(); + ar << r2; + auto r3 = GetFpexc(); + ar << r3; + } + + template + void load(Archive& ar, const unsigned int file_version) + { + u32 r; + for (auto i = 0; i < 16; i++) { + ar >> r; + SetCpuRegister(i, r); + } + for (auto i = 0; i < 16; i++) { + ar >> r; + SetFpuRegister(i, r); + } + ar >> r; + SetCpsr(r); + ar >> r; + SetFpscr(r); + ar >> r; + SetFpexc(r); + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() public: virtual ~ThreadContext() = default; @@ -143,7 +186,7 @@ public: * @param reg The CP15 register to retrieve the value from. * @return the value stored in the given CP15 register. */ - virtual u32 GetCP15Register(CP15Register reg) = 0; + virtual u32 GetCP15Register(CP15Register reg) const = 0; /** * Stores the given value into the indicated CP15 register. @@ -172,4 +215,61 @@ public: /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; + +private: + friend class boost::serialization::access; + + template + void save(Archive& ar, const unsigned int file_version) const + { + for (auto i = 0; i < 15; i++) { + auto r = GetReg(i); + ar << r; + } + auto pc = GetPC(); + ar << pc; + auto cpsr = GetCPSR(); + ar << cpsr; + for (auto i = 0; i < 32; i++) { + auto r = GetVFPReg(i); + ar << r; + } + for (auto i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + auto r = GetVFPSystemReg(static_cast(i)); + ar << r; + } + for (auto i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + auto r = GetCP15Register(static_cast(i)); + ar << r; + } + } + + template + void load(Archive& ar, const unsigned int file_version) + { + u32 r; + for (auto i = 0; i < 15; i++) { + ar >> r; + SetReg(i, r); + } + ar >> r; + SetPC(r); + ar >> r; + SetCPSR(r); + for (auto i = 0; i < 32; i++) { + ar >> r; + SetVFPReg(i, r); + } + for (auto i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + ar >> r; + SetVFPSystemReg(static_cast(i), r); + } + for (auto i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + ar >> r; + SetCP15Register(static_cast(i), r); + } + // TODO: Clear caches etc? + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index f494b5228..a422db6af 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -235,7 +235,7 @@ void ARM_Dynarmic::SetCPSR(u32 cpsr) { jit->SetCpsr(cpsr); } -u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) { +u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) const { return interpreter_state->CP15[reg]; } diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 559dbf5a8..ff9a104b5 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -40,7 +40,7 @@ public: void SetVFPSystemReg(VFPSystemRegister reg, u32 value) override; u32 GetCPSR() const override; void SetCPSR(u32 cpsr) override; - u32 GetCP15Register(CP15Register reg) override; + u32 GetCP15Register(CP15Register reg) const override; void SetCP15Register(CP15Register reg, u32 value) override; std::unique_ptr NewContext() const override; diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index d54b0cb95..6b67644e7 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -138,7 +138,7 @@ void ARM_DynCom::SetCPSR(u32 cpsr) { state->Cpsr = cpsr; } -u32 ARM_DynCom::GetCP15Register(CP15Register reg) { +u32 ARM_DynCom::GetCP15Register(CP15Register reg) const { return state->CP15[reg]; } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 99c6ab460..7497b765f 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -41,7 +41,7 @@ public: void SetVFPSystemReg(VFPSystemRegister reg, u32 value) override; u32 GetCPSR() const override; void SetCPSR(u32 cpsr) override; - u32 GetCP15Register(CP15Register reg) override; + u32 GetCP15Register(CP15Register reg) const override; void SetCP15Register(CP15Register reg, u32 value) override; std::unique_ptr NewContext() const override; diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index ecb97c6bd..26fc0bccb 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -9,6 +9,7 @@ // bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm // putting this as a subset of HLE for now. +#include #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -56,6 +57,14 @@ public: private: ConfigMemDef config_mem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + auto o_config_mem = boost::serialization::binary_object(&config_mem, sizeof(config_mem)); + ar & o_config_mem; + } }; } // namespace ConfigMem diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index d8bd0f034..32d76d0d3 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -109,17 +109,17 @@ template void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { ar & named_ports; - // TODO: CPU + ar & *current_cpu.get(); // NB: subsystem references and prepare_reschedule_callback are constant ar & *resource_limits.get(); ar & next_object_id; - //ar & *timer_manager.get(); + ar & *timer_manager.get(); ar & next_process_id; ar & process_list; ar & current_process; - // ar & *thread_manager.get(); - //ar & *config_mem_handler.get(); - //ar & *shared_page_handler.get(); + ar & *thread_manager.get(); + ar & *config_mem_handler.get(); + ar & *shared_page_handler.get(); } SERIALIZE_IMPL(KernelSystem) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 467b1ae1e..b9a32ef23 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -23,11 +23,12 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } -Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} +Mutex::Mutex() : kernel(*g_kernel) {} Mutex::~Mutex() {} std::shared_ptr KernelSystem::CreateMutex(bool initial_locked, std::string name) { - auto mutex{std::make_shared(*this)}; + auto mutex{std::make_shared()}; + mutex->Init(*this); mutex->lock_count = 0; mutex->name = std::move(name); diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 618685451..4f0c2c2b5 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -17,7 +17,7 @@ class Thread; class Mutex final : public WaitObject { public: - explicit Mutex(KernelSystem& kernel); + explicit Mutex(); ~Mutex() override; std::string GetTypeName() const override { @@ -68,7 +68,6 @@ private: ar & priority; ar & name; ar & holding_thread; - ar & kernel; // TODO: Check that this works! } }; diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 63a5c3b68..49de1e69e 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -4,9 +4,13 @@ #include #include +#include +#include +#include "common/archives.h" #include "common/assert.h" #include "common/common_funcs.h" #include "common/logging/log.h" +#include "common/serialization/boost_vector.hpp" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" @@ -17,6 +21,28 @@ namespace Kernel { +template +void Process::serialize(Archive& ar, const unsigned int file_version) +{ + ar & boost::serialization::base_object(*this); + ar & handle_table; + ar & codeset; + ar & resource_limit; + ar & svc_access_mask; + ar & handle_table_size; + ar & (boost::container::vector >&)address_mappings; + ar & flags.raw; + ar & kernel_version; + ar & ideal_processor; + ar & process_id; + ar & vm_manager; + ar & memory_used; + ar & memory_region; + ar & tls_slots; +} + +SERIALIZE_IMPL(Process) + std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { auto codeset{std::make_shared()}; codeset->Init(*this); diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 6defd42c6..edda20c1f 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,13 +11,10 @@ #include #include #include -#include -#include -#include #include +#include #include "common/bit_field.h" #include "common/common_types.h" -#include "common/serialization/boost_vector.hpp" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/vm_manager.h" @@ -234,23 +231,6 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & handle_table; - ar & codeset; - ar & resource_limit; - ar & svc_access_mask; - ar & handle_table_size; - ar & (boost::container::vector >&)address_mappings; - ar & flags.raw; - ar & kernel_version; - ar & ideal_processor; - ar & process_id; - ar & vm_manager; - ar & memory_used; - ar & memory_region; - ar & tls_slots; - } + void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index 5092b4869..58cd46334 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -104,6 +105,14 @@ private: std::chrono::seconds init_time; SharedPageDef shared_page; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + auto o_shared_page = boost::serialization::binary_object(&shared_page, sizeof(shared_page)); + ar & o_shared_page; + } }; } // namespace SharedPage diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 4c2344dcb..9fa5df33a 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -6,10 +6,12 @@ #include #include #include +#include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/math_util.h" +#include "common/serialization/boost_flat_set.h" #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" @@ -25,6 +27,30 @@ namespace Kernel { +template +void Thread::serialize(Archive& ar, const unsigned int file_version) +{ + ar & *context.get(); + ar & thread_id; + ar & status; + ar & entry_point; + ar & stack_top; + ar & nominal_priority; + ar & current_priority; + ar & last_running_ticks; + ar & processor_id; + ar & tls_address; + ar & held_mutexes; + ar & pending_mutexes; + ar & owner_process; + ar & wait_objects; + ar & wait_address; + ar & name; + // TODO: How the hell to do wakeup_callback +} + +SERIALIZE_IMPL(Thread) + bool Thread::ShouldWait(const Thread* thread) const { return status != ThreadStatus::Dead; } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 2db5dda91..fc9170675 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "common/thread_queue_list.h" #include "core/arm/arm_interface.h" @@ -145,6 +148,17 @@ private: friend class Thread; friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & next_thread_id; + ar & current_thread; + ar & ready_queue; + ar & wakeup_callback_table; + ar & thread_list; + } }; class Thread final : public WaitObject { @@ -305,6 +319,10 @@ public: private: ThreadManager& thread_manager; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version); }; /** diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 9c3d0f725..f073c3312 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -14,15 +14,15 @@ namespace Kernel { -Timer::Timer(KernelSystem& kernel) - : WaitObject(kernel), kernel(kernel), timer_manager(kernel.GetTimerManager()) {} +Timer::Timer() : kernel(*g_kernel), timer_manager(g_kernel->GetTimerManager()) {} Timer::~Timer() { Cancel(); timer_manager.timer_callback_table.erase(callback_id); } std::shared_ptr KernelSystem::CreateTimer(ResetType reset_type, std::string name) { - auto timer{std::make_shared(*this)}; + auto timer{std::make_shared()}; + timer->Init(*this); timer->reset_type = reset_type; timer->signaled = false; diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index 6865f5243..690350611 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -4,6 +4,7 @@ #pragma once +#include #include "common/common_types.h" #include "core/core_timing.h" #include "core/hle/kernel/object.h" @@ -33,11 +34,19 @@ private: friend class Timer; friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & next_timer_callback_id; + ar & timer_callback_table; + } }; class Timer final : public WaitObject { public: - explicit Timer(KernelSystem& kernel); + explicit Timer(); ~Timer() override; std::string GetTypeName() const override { @@ -103,6 +112,18 @@ private: TimerManager& timer_manager; friend class KernelSystem; + + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & reset_type; + ar & initial_delay; + ar & interval_delay; + ar & signaled; + ar & name; + ar & callback_id; + } }; } // namespace Kernel From dc0d1ebc95fbaa04034b96db9523470a161f4ed4 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 13 Aug 2019 17:37:04 +0100 Subject: [PATCH 010/129] Added a TODO --- TODO | 80 ++++++++++++++++++++++++++++++++++ src/video_core/pica_state.h | 2 +- src/video_core/shader/shader.h | 2 +- 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 000000000..3f15f3fb5 --- /dev/null +++ b/TODO @@ -0,0 +1,80 @@ +☐ Save/load UI +✔ CPU @done(19-08-13 15:41) +✔ Memory @done(19-08-13 15:41) +✔ DSP @done(19-08-13 15:41) +☐ MMIO +☐ Movie +☐ Perf stats +☐ Settings +☐ Telemetry session +✔ HW @done(19-08-13 15:41) + ✔ GPU regs @done(19-08-13 15:41) + ✔ LCD regs @done(19-08-13 15:41) +☐ Video core @started(19-08-13 16:43) + ☐ Geometry pipeline + ✔ PICA state @done(19-08-13 15:41) + ☐ Primitive assembly + ✔ Shader @done(19-08-13 16:03) +☐ HLE @started(19-08-13 16:43) + ☐ Kernel @started(19-08-13 16:43) + ✔ Address arbiter @done(19-08-13 16:40) + ✔ Client port @done(19-08-13 16:40) + ✔ Client session @done(19-08-13 16:40) + ✔ Config mem @done(19-08-13 16:40) + ☐ Event + ✔ Handle table @done(19-08-13 16:42) + ☐ HLE IPC + ☐ IPC + ☐ Memory @started(19-08-13 16:43) + ☐ Mutex @started(19-08-13 16:43) + ✔ Object @done(19-08-13 15:41) + ☐ Process @started(19-08-13 16:43) + ✔ Resource limit @done(19-08-13 16:43) + ☐ Semaphore @started(19-08-13 16:44) + ✔ Server port @done(19-08-13 16:44) + ✔ Server session @done(19-08-13 16:44) + ✔ Session @done(19-08-13 16:44) + ☐ Shared memory + ☐ Shared page @started(19-08-13 16:44) + ☐ SVC + ☐ Thread @started(19-08-13 16:45) + ✔ Timer @done(19-08-13 16:45) + ☐ VM Manager @started(19-08-13 16:46) + ✔ Wait object @done(19-08-13 16:46) + ☐ Service + ☐ AC + ☐ ACT + ☐ AM + ☐ APT + ☐ BOSS + ☐ CAM + ☐ CECD + ☐ CGF + ☐ CSND + ☐ DLP + ☐ DSP + ☐ ERR + ☐ FRD + ☐ FS + ☐ GSP + ☐ HID + ☐ HTTP + ☐ IR + ☐ LDR_RO + ☐ MIC + ☐ MVD + ☐ NDM + ☐ NEWS + ☐ NFC + ☐ NIM + ☐ NS + ☐ NWM + ☐ PM + ☐ PS + ☐ PTM + ☐ PXI + ☐ QTM + ☐ SM + ☐ SOC + ☐ SSL + ☐ Y2R \ No newline at end of file diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 376865397..f0a9a119d 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -225,7 +225,7 @@ private: ar & cmd_list.addr; ar & cmd_list.length; ar & immediate; - // ar & gs_unit; + ar & gs_unit; // ar & geometry_pipeline; // ar & primitive_assembler; ar & vs_float_regs_counter; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 1a0f6ef8a..ffa60f3b5 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -201,7 +201,7 @@ private: ar & registers; ar & conditional_code; ar & address_registers; - // TODO: emitter_ptr + // emitter_ptr is only set by GSUnitState and is serialized there } }; From acc89b22514d4ab61ef9d2b9f6be4143fd07ee7c Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 21 Dec 2019 23:37:41 +0000 Subject: [PATCH 011/129] Fixed an include --- src/video_core/pica_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index f0a9a119d..ba9f8235e 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -9,6 +9,7 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/vector_math.h" +#include "video_core/video_core.h" #include "video_core/geometry_pipeline.h" #include "video_core/primitive_assembly.h" #include "video_core/regs.h" From c284192a87ae7fe2ec4ff0e3b5e86863a44a445c Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 22 Dec 2019 15:53:04 +0000 Subject: [PATCH 012/129] Serialize geometry_pipeline --- TODO | 6 +- externals/boost | 2 +- src/core/hle/kernel/kernel.cpp | 3 +- src/video_core/geometry_pipeline.cpp | 139 +++++++++++++++++++++++++-- src/video_core/geometry_pipeline.h | 5 + src/video_core/pica_state.h | 2 +- 6 files changed, 144 insertions(+), 13 deletions(-) diff --git a/TODO b/TODO index 3f15f3fb5..840caba1b 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) ☐ Video core @started(19-08-13 16:43) - ☐ Geometry pipeline + ✔ Geometry pipeline @done(19-12-22 15:52) ✔ PICA state @done(19-08-13 15:41) ☐ Primitive assembly ✔ Shader @done(19-08-13 16:03) @@ -35,9 +35,11 @@ ✔ Server session @done(19-08-13 16:44) ✔ Session @done(19-08-13 16:44) ☐ Shared memory - ☐ Shared page @started(19-08-13 16:44) + ✘ Shared page @started(19-08-13 16:44) @cancelled(19-12-22 11:19) + Not needed right now as shared_page is read-only and derived from other data ☐ SVC ☐ Thread @started(19-08-13 16:45) + This requires refactoring wakeup_callback to be an object ref ✔ Timer @done(19-08-13 16:45) ☐ VM Manager @started(19-08-13 16:46) ✔ Wait object @done(19-08-13 16:46) diff --git a/externals/boost b/externals/boost index f4850c297..55725b779 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit f4850c2975a0d977b7479664b8d4a6f03300a042 +Subproject commit 55725b7796c7faa0a4af869e412d0410bd47612d diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 32d76d0d3..2dd0a34bf 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -119,7 +119,8 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version) ar & current_process; ar & *thread_manager.get(); ar & *config_mem_handler.get(); - ar & *shared_page_handler.get(); + // Shared page data is read-only at the moment, so doesn't need serializing + //ar & *shared_page_handler.get(); } SERIALIZE_IMPL(KernelSystem) diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp index 3a24b71c9..44a2fd6da 100644 --- a/src/video_core/geometry_pipeline.cpp +++ b/src/video_core/geometry_pipeline.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include +#include +#include "common/archives.h" #include "video_core/geometry_pipeline.h" #include "video_core/pica_state.h" #include "video_core/regs.h" @@ -30,6 +34,13 @@ public: * @return if the buffer is full and the geometry shader should be invoked */ virtual bool SubmitVertex(const Shader::AttributeBuffer& input) = 0; + +private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + } + friend class boost::serialization::access; }; // In the Point mode, vertex attributes are sent to the input registers in the geometry shader unit. @@ -40,7 +51,7 @@ public: // TODO: what happens when the input size is not divisible by the output size? class GeometryPipeline_Point : public GeometryPipelineBackend { public: - GeometryPipeline_Point(const Regs& regs, Shader::GSUnitState& unit) : regs(regs), unit(unit) { + GeometryPipeline_Point() : regs(g_state.regs), unit(g_state.gs_unit) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 0); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -79,6 +90,39 @@ private: Common::Vec4* buffer_cur; Common::Vec4* buffer_end; unsigned int vs_output_num; + + template + static void serialize_common(Class* self, Archive& ar, const unsigned int version) + { + ar & boost::serialization::base_object(*self); + ar & self->attribute_buffer; + ar & self->vs_output_num; + } + + template + void save(Archive & ar, const unsigned int version) const + { + serialize_common(this, ar, version); + auto buffer_idx = static_cast(buffer_cur - attribute_buffer.attr); + auto buffer_size = static_cast(buffer_end - attribute_buffer.attr); + ar << buffer_idx; + ar << buffer_size; + } + + template + void load(Archive & ar, const unsigned int version) + { + serialize_common(this, ar, version); + u32 buffer_idx, buffer_size; + ar >> buffer_idx; + ar >> buffer_size; + buffer_cur = attribute_buffer.attr + buffer_idx; + buffer_end = attribute_buffer.attr + buffer_size; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class boost::serialization::access; }; // In VariablePrimitive mode, vertex attributes are buffered into the uniform registers in the @@ -86,8 +130,8 @@ private: // value in the batch. This mode is usually used for subdivision. class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_VariablePrimitive(const Regs& regs, Shader::ShaderSetup& setup) - : regs(regs), setup(setup) { + GeometryPipeline_VariablePrimitive() + : regs(g_state.regs), setup(g_state.gs) { ASSERT(regs.pipeline.variable_primitive == 1); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -144,6 +188,37 @@ private: unsigned int total_vertex_num; Common::Vec4* buffer_cur; unsigned int vs_output_num; + + template + static void serialize_common(Class* self, Archive& ar, const unsigned int version) + { + ar & boost::serialization::base_object(*self); + ar & self->need_index; + ar & self->main_vertex_num; + ar & self->total_vertex_num; + ar & self->vs_output_num; + } + + template + void save(Archive & ar, const unsigned int version) const + { + serialize_common(this, ar, version); + auto buffer_idx = static_cast(buffer_cur - setup.uniforms.f); + ar << buffer_idx; + } + + template + void load(Archive & ar, const unsigned int version) + { + serialize_common(this, ar, version); + u32 buffer_idx; + ar >> buffer_idx; + buffer_cur = setup.uniforms.f + buffer_idx; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class boost::serialization::access; }; // In FixedPrimitive mode, vertex attributes are buffered into the uniform registers in the geometry @@ -151,8 +226,8 @@ private: // particle system. class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_FixedPrimitive(const Regs& regs, Shader::ShaderSetup& setup) - : regs(regs), setup(setup) { + GeometryPipeline_FixedPrimitive() + : regs(g_state.regs), setup(g_state.gs) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -190,6 +265,42 @@ private: Common::Vec4* buffer_cur; Common::Vec4* buffer_end; unsigned int vs_output_num; + + template + static void serialize_common(Class* self, Archive& ar, const unsigned int version) + { + ar & boost::serialization::base_object(*self); + ar & self->vs_output_num; + } + + template + void save(Archive & ar, const unsigned int version) const + { + serialize_common(this, ar, version); + auto buffer_offset = static_cast(buffer_begin - setup.uniforms.f); + auto buffer_idx = static_cast(buffer_cur - setup.uniforms.f); + auto buffer_size = static_cast(buffer_end - setup.uniforms.f); + ar << buffer_offset; + ar << buffer_idx; + ar << buffer_size; + } + + template + void load(Archive & ar, const unsigned int version) + { + serialize_common(this, ar, version); + u32 buffer_offset, buffer_idx, buffer_size; + ar >> buffer_offset; + ar >> buffer_idx; + ar >> buffer_size; + buffer_begin = setup.uniforms.f + buffer_offset; + buffer_cur = setup.uniforms.f + buffer_idx; + buffer_end = setup.uniforms.f + buffer_size; + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + friend class boost::serialization::access; }; GeometryPipeline::GeometryPipeline(State& state) : state(state) {} @@ -231,13 +342,13 @@ void GeometryPipeline::Reconfigure() { switch (state.regs.pipeline.gs_config.mode) { case PipelineRegs::GSMode::Point: - backend = std::make_unique(state.regs, state.gs_unit); + backend = std::make_unique(); break; case PipelineRegs::GSMode::VariablePrimitive: - backend = std::make_unique(state.regs, state.gs); + backend = std::make_unique(); break; case PipelineRegs::GSMode::FixedPrimitive: - backend = std::make_unique(state.regs, state.gs); + backend = std::make_unique(); break; default: UNREACHABLE(); @@ -271,4 +382,16 @@ void GeometryPipeline::SubmitVertex(const Shader::AttributeBuffer& input) { } } +template +void GeometryPipeline::serialize(Archive& ar, const unsigned int version) { + // vertex_handler and shader_engine are always set to the same value + ar & backend; +} + } // namespace Pica + +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Pica::GeometryPipelineBackend) +SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_Point) +SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_VariablePrimitive) +SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_FixedPrimitive) +SERIALIZE_IMPL(Pica::GeometryPipeline) diff --git a/src/video_core/geometry_pipeline.h b/src/video_core/geometry_pipeline.h index 91fdd3192..1ca2d00c4 100644 --- a/src/video_core/geometry_pipeline.h +++ b/src/video_core/geometry_pipeline.h @@ -45,5 +45,10 @@ private: Shader::ShaderEngine* shader_engine; std::unique_ptr backend; State& state; + + template + void serialize(Archive& ar, const unsigned int version); + + friend class boost::serialization::access; }; } // namespace Pica diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index ba9f8235e..d7ae04c1b 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -227,7 +227,7 @@ private: ar & cmd_list.length; ar & immediate; ar & gs_unit; - // ar & geometry_pipeline; + ar & geometry_pipeline; // ar & primitive_assembler; ar & vs_float_regs_counter; ar & vs_uniform_write_buffer; From 050c3bdee59a41858cfc69f03adf5f14698090a3 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 22 Dec 2019 16:06:26 +0000 Subject: [PATCH 013/129] Serialize primitive_assembly --- TODO | 5 ++++- src/video_core/pica_state.h | 2 +- src/video_core/primitive_assembly.h | 12 ++++++++++++ src/video_core/shader/shader.h | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 840caba1b..95bdaa926 100644 --- a/TODO +++ b/TODO @@ -7,16 +7,19 @@ ☐ Perf stats ☐ Settings ☐ Telemetry session +☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) ☐ Video core @started(19-08-13 16:43) ✔ Geometry pipeline @done(19-12-22 15:52) + Required more use of g_state ✔ PICA state @done(19-08-13 15:41) - ☐ Primitive assembly + ✔ Primitive assembly @done(19-12-22 16:05) ✔ Shader @done(19-08-13 16:03) ☐ HLE @started(19-08-13 16:43) ☐ Kernel @started(19-08-13 16:43) + Most of these require adding g_kernel ✔ Address arbiter @done(19-08-13 16:40) ✔ Client port @done(19-08-13 16:40) ✔ Client session @done(19-08-13 16:40) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index d7ae04c1b..95ee77662 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -228,7 +228,7 @@ private: ar & immediate; ar & gs_unit; ar & geometry_pipeline; - // ar & primitive_assembler; + ar & primitive_assembler; ar & vs_float_regs_counter; ar & vs_uniform_write_buffer; ar & gs_float_regs_counter; diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index fd5445aa8..1545a6b4c 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h @@ -6,6 +6,7 @@ #include #include "video_core/regs_pipeline.h" +namespace boost::serialization { class access; } namespace Pica { @@ -62,6 +63,17 @@ private: VertexType buffer[2]; bool strip_ready = false; bool winding = false; + + template + void serialize(Archive& ar, const unsigned int version) + { + ar & topology; + ar & buffer_index; + ar & buffer; + ar & strip_ready; + ar & winding; + } + friend class boost::serialization::access; }; } // namespace Pica diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index ffa60f3b5..f20e08d98 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -16,6 +16,7 @@ #include "common/common_types.h" #include "common/hash.h" #include "common/vector_math.h" +#include "common/pod.h" #include "video_core/pica_types.h" #include "video_core/regs_rasterizer.h" #include "video_core/regs_shader.h" @@ -64,6 +65,8 @@ struct OutputVertex { static void ValidateSemantics(const RasterizerRegs& regs); static OutputVertex FromAttributeBuffer(const RasterizerRegs& regs, const AttributeBuffer& output); + + SERIALIZE_AS_POD }; #define ASSERT_POS(var, pos) \ static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong " \ From 8c81500deec2e8368c112fbce98770c7b518f40e Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 22 Dec 2019 18:35:03 +0000 Subject: [PATCH 014/129] Serialize kernel/hle/memory --- TODO | 4 +-- .../serialization/boost_discrete_interval.hpp | 33 +++++++++++++++++++ src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/memory.h | 5 ++- 4 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/common/serialization/boost_discrete_interval.hpp diff --git a/TODO b/TODO index 95bdaa926..cad91b958 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) -☐ Video core @started(19-08-13 16:43) +✔ Video core @started(19-08-13 16:43) @done(19-12-22 16:06) ✔ Geometry pipeline @done(19-12-22 15:52) Required more use of g_state ✔ PICA state @done(19-08-13 15:41) @@ -28,7 +28,7 @@ ✔ Handle table @done(19-08-13 16:42) ☐ HLE IPC ☐ IPC - ☐ Memory @started(19-08-13 16:43) + ✔ Memory @started(19-08-13 16:43) @done(19-12-22 18:34) ☐ Mutex @started(19-08-13 16:43) ✔ Object @done(19-08-13 15:41) ☐ Process @started(19-08-13 16:43) diff --git a/src/common/serialization/boost_discrete_interval.hpp b/src/common/serialization/boost_discrete_interval.hpp new file mode 100644 index 000000000..dc920e439 --- /dev/null +++ b/src/common/serialization/boost_discrete_interval.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "common/common_types.h" +#include + +namespace boost::serialization { + +template +void save(Archive& ar, const boost::icl::discrete_interval& obj, const unsigned int file_version) +{ + ar << obj.lower(); + ar << obj.upper(); + ar << obj.bounds()._bits; +} + +template +void load(Archive& ar, boost::icl::discrete_interval& obj, const unsigned int file_version) +{ + DomainT upper, lower; + boost::icl::bound_type bounds; + ar >> upper; + ar >> lower; + ar >> bounds; + obj = boost::icl::discrete_interval(upper, lower, boost::icl::interval_bounds(bounds)); +} + +template +void serialize(Archive& ar, boost::icl::discrete_interval& obj, const unsigned int file_version) +{ + boost::serialization::split_free(ar, obj, file_version); +} + +} diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2dd0a34bf..6248311b9 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -108,6 +108,7 @@ void KernelSystem::AddNamedPort(std::string name, std::shared_ptr po template void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { + ar & memory_regions; ar & named_ports; ar & *current_cpu.get(); // NB: subsystem references and prepare_reschedule_callback are constant @@ -120,7 +121,6 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version) ar & *thread_manager.get(); ar & *config_mem_handler.get(); // Shared page data is read-only at the moment, so doesn't need serializing - //ar & *shared_page_handler.get(); } SERIALIZE_IMPL(KernelSystem) diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index 9e9fe5eb4..ed4ea1296 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -6,6 +6,8 @@ #include #include +#include +#include "common/serialization/boost_discrete_interval.hpp" #include "common/common_types.h" namespace Kernel { @@ -69,7 +71,8 @@ private: ar & base; ar & size; ar & used; - // TODO: boost icl / free_blocks + // This works because interval_set has exactly one member of type ImplSetT + ar & *(reinterpret_cast(&free_blocks)); } }; From 4f95575d418195d833a61704c54df29f4c58ec86 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 22 Dec 2019 23:37:17 +0000 Subject: [PATCH 015/129] Serialize some more kernel objects --- TODO | 21 +++++++++++++++------ src/common/archives.h | 1 + src/core/core.cpp | 2 ++ src/core/hle/kernel/event.cpp | 7 +++++-- src/core/hle/kernel/event.h | 5 ++++- src/core/hle/kernel/kernel.cpp | 1 + src/core/hle/kernel/mutex.cpp | 3 +++ src/core/hle/kernel/mutex.h | 3 +++ src/core/hle/kernel/process.cpp | 1 + src/core/hle/kernel/semaphore.cpp | 7 +++++-- src/core/hle/kernel/semaphore.h | 5 ++++- src/core/hle/kernel/shared_memory.h | 16 ++++++++++++++++ src/core/hle/kernel/thread.cpp | 2 ++ src/core/hle/kernel/thread.h | 3 +++ src/core/hle/kernel/vm_manager.h | 1 + 15 files changed, 66 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index cad91b958..6397b4ba9 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,10 @@ ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ DSP @done(19-08-13 15:41) +☐ Service manager +☐ App loader +☐ Archive manager +☐ Custom texture cache ☐ MMIO ☐ Movie ☐ Perf stats @@ -24,27 +28,32 @@ ✔ Client port @done(19-08-13 16:40) ✔ Client session @done(19-08-13 16:40) ✔ Config mem @done(19-08-13 16:40) - ☐ Event + ✔ Event @done(19-12-22 18:44) ✔ Handle table @done(19-08-13 16:42) ☐ HLE IPC ☐ IPC ✔ Memory @started(19-08-13 16:43) @done(19-12-22 18:34) - ☐ Mutex @started(19-08-13 16:43) + ✔ Mutex @done(19-08-13 16:43) ✔ Object @done(19-08-13 15:41) - ☐ Process @started(19-08-13 16:43) + ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) + ☐ Code set @started(19-12-22 18:41) + Needs a way to reference loaded images (so we don't serialize the entire ROM as well) ✔ Resource limit @done(19-08-13 16:43) - ☐ Semaphore @started(19-08-13 16:44) + ✔ Semaphore @done(19-08-13 16:44) ✔ Server port @done(19-08-13 16:44) ✔ Server session @done(19-08-13 16:44) ✔ Session @done(19-08-13 16:44) - ☐ Shared memory + ☐ Shared memory @started(19-12-22 21:20) + Need to figure out backing memory (a u8*) ✘ Shared page @started(19-08-13 16:44) @cancelled(19-12-22 11:19) Not needed right now as shared_page is read-only and derived from other data - ☐ SVC + ✔ SVC @done(19-12-22 21:32) + Nothing to do - all data is constant ☐ Thread @started(19-08-13 16:45) This requires refactoring wakeup_callback to be an object ref ✔ Timer @done(19-08-13 16:45) ☐ VM Manager @started(19-08-13 16:46) + Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) ☐ Service ☐ AC diff --git a/src/common/archives.h b/src/common/archives.h index f30886d90..a27afe80c 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -1,5 +1,6 @@ #include "boost/archive/binary_iarchive.hpp" #include "boost/archive/binary_oarchive.hpp" +#include "boost/serialization/export.hpp" using iarchive = boost::archive::binary_iarchive; using oarchive = boost::archive::binary_oarchive; diff --git a/src/core/core.cpp b/src/core/core.cpp index 902340d41..9aecf84c9 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -398,6 +398,8 @@ void System::Reset() { template void System::serialize(Archive & ar, const unsigned int file_version) { + ar & *cpu_core.get(); + //ar & *service_manager.get(); ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index f31162e35..7af667739 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -6,17 +6,20 @@ #include #include #include "common/assert.h" +#include "common/archives.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::Event) + namespace Kernel { -Event::Event(KernelSystem& kernel) : WaitObject(kernel) {} +Event::Event() : WaitObject() {} Event::~Event() {} std::shared_ptr KernelSystem::CreateEvent(ResetType reset_type, std::string name) { - auto evt{std::make_shared(*this)}; + auto evt{std::make_shared()}; evt->signaled = false; evt->reset_type = reset_type; diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 9e9da267a..bb97f6eb1 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -4,6 +4,7 @@ #pragma once +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" @@ -12,7 +13,7 @@ namespace Kernel { class Event final : public WaitObject { public: - explicit Event(KernelSystem& kernel); + explicit Event(); ~Event() override; std::string GetTypeName() const override { @@ -62,3 +63,5 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Event) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 6248311b9..4f9a02410 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -121,6 +121,7 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version) ar & *thread_manager.get(); ar & *config_mem_handler.get(); // Shared page data is read-only at the moment, so doesn't need serializing + // Deliberately don't include debugger info to allow debugging through loads } SERIALIZE_IMPL(KernelSystem) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index b9a32ef23..b8a3d143b 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/assert.h" #include "core/core.h" #include "core/hle/kernel/errors.h" @@ -12,6 +13,8 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::Mutex) + namespace Kernel { void ReleaseThreadMutexes(Thread* thread) { diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 4f0c2c2b5..f4449c0f2 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/wait_object.h" @@ -78,3 +79,5 @@ private: void ReleaseThreadMutexes(Thread* thread); } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Mutex) diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 49de1e69e..5fad4fd85 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -34,6 +34,7 @@ void Process::serialize(Archive& ar, const unsigned int file_version) ar & flags.raw; ar & kernel_version; ar & ideal_processor; + ar & status; ar & process_id; ar & vm_manager; ar & memory_used; diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index bbc8a385f..f60a653e5 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -3,14 +3,17 @@ // Refer to the license.txt file included. #include "common/assert.h" +#include "common/archives.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/semaphore.h" #include "core/hle/kernel/thread.h" +SERIALIZE_EXPORT_IMPL(Kernel::Semaphore) + namespace Kernel { -Semaphore::Semaphore(KernelSystem& kernel) : WaitObject(kernel) {} +Semaphore::Semaphore() : WaitObject() {} Semaphore::~Semaphore() {} ResultVal> KernelSystem::CreateSemaphore(s32 initial_count, @@ -20,7 +23,7 @@ ResultVal> KernelSystem::CreateSemaphore(s32 initial_ if (initial_count > max_count) return ERR_INVALID_COMBINATION_KERNEL; - auto semaphore{std::make_shared(*this)}; + auto semaphore{std::make_shared()}; // When the semaphore is created, some slots are reserved for other threads, // and the rest is reserved for the caller thread diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 526be6812..ff6a4434a 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" @@ -15,7 +16,7 @@ namespace Kernel { class Semaphore final : public WaitObject { public: - explicit Semaphore(KernelSystem& kernel); + explicit Semaphore(); ~Semaphore() override; std::string GetTypeName() const override { @@ -57,3 +58,5 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Semaphore) diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 0d781cfcc..42d783513 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" @@ -104,6 +105,21 @@ private: friend class KernelSystem; KernelSystem& kernel; + + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & linear_heap_phys_offset; + // TODO: backing blocks u8* (this is always FCRAM I think) + ar & size; + ar & permissions; + ar & other_permissions; + ar & owner_process; + ar & base_address; + ar & name; + ar & *(reinterpret_cast(&holding_memory));; + } + friend class boost::serialization::access; }; } // namespace Kernel diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 9fa5df33a..409dcc886 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -25,6 +25,8 @@ #include "core/hle/result.h" #include "core/memory.h" +SERIALIZE_EXPORT_IMPL(Kernel::Thread) + namespace Kernel { template diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index fc9170675..b423392e3 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "common/common_types.h" #include "common/thread_queue_list.h" #include "core/arm/arm_interface.h" @@ -337,3 +338,5 @@ std::shared_ptr SetupMainThread(KernelSystem& kernel, u32 entry_point, u std::shared_ptr owner_process); } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Thread) diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 6711c9b4d..e930fc64a 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -94,6 +94,7 @@ private: ar & permissions; ar & meminfo_state; // TODO: backing memory ref + // backing memory can be: Physical/FCRAM pointer, config mem, shared page ar & paddr; ar & mmio_handler; } From 7a5bde0b44b86d4d64e049ede824286942408fad Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 23 Dec 2019 11:41:07 +0000 Subject: [PATCH 016/129] Serialize service manager, server prt --- TODO | 9 ++++++--- src/core/core.cpp | 4 ++-- src/core/core.h | 2 +- src/core/hle/kernel/hle_ipc.h | 26 ++++++++++++++++++++++++++ src/core/hle/kernel/ipc.h | 15 +++++++++++++++ src/core/hle/kernel/server_port.cpp | 11 +++++++++++ src/core/hle/kernel/server_port.h | 8 +------- src/core/hle/kernel/server_session.h | 4 ++-- src/core/hle/kernel/session.cpp | 1 + src/core/hle/kernel/shared_memory.h | 2 +- src/core/hle/service/sm/sm.h | 11 +++++++++++ 11 files changed, 77 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 6397b4ba9..f3e1ea943 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,8 @@ ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ DSP @done(19-08-13 15:41) -☐ Service manager +✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) + ☐ Fix or ignore inverse map ☐ App loader ☐ Archive manager ☐ Custom texture cache @@ -30,8 +31,8 @@ ✔ Config mem @done(19-08-13 16:40) ✔ Event @done(19-12-22 18:44) ✔ Handle table @done(19-08-13 16:42) - ☐ HLE IPC - ☐ IPC + ✔ HLE IPC @done(19-12-23 00:36) + ✔ IPC @done(19-12-23 00:36) ✔ Memory @started(19-08-13 16:43) @done(19-12-22 18:34) ✔ Mutex @done(19-08-13 16:43) ✔ Object @done(19-08-13 15:41) @@ -42,6 +43,8 @@ ✔ Semaphore @done(19-08-13 16:44) ✔ Server port @done(19-08-13 16:44) ✔ Server session @done(19-08-13 16:44) + ☐ Mapped buffer context + This may not be needed! ✔ Session @done(19-08-13 16:44) ☐ Shared memory @started(19-12-22 21:20) Need to figure out backing memory (a u8*) diff --git a/src/core/core.cpp b/src/core/core.cpp index 9aecf84c9..8ca3a2ab5 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -235,7 +235,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo rpc_server = std::make_unique(); - service_manager = std::make_shared(*this); + service_manager = std::make_unique(*this); archive_manager = std::make_unique(*this); HW::Init(*memory); @@ -399,7 +399,7 @@ template void System::serialize(Archive & ar, const unsigned int file_version) { ar & *cpu_core.get(); - //ar & *service_manager.get(); + ar & *service_manager.get(); ar & GPU::g_regs; ar & LCD::g_regs; ar & dsp_core->GetDspMemory(); diff --git a/src/core/core.h b/src/core/core.h index b811badba..8bf04d365 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -305,7 +305,7 @@ private: std::unique_ptr telemetry_session; /// Service manager - std::shared_ptr service_manager; + std::unique_ptr service_manager; /// Frontend applets std::shared_ptr registered_mii_selector; diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 26942fe6b..be3a20e79 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -11,12 +11,19 @@ #include #include #include +#include +#include +#include +#include #include "common/common_types.h" #include "common/swap.h" #include "core/hle/ipc.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_session.h" +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler) +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler::SessionDataBase) + namespace Service { class ServiceFrameworkBase; } @@ -90,12 +97,31 @@ protected: std::shared_ptr session; std::unique_ptr data; + + private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & session; + ar & data; + } + friend class boost::serialization::access; }; /// List of sessions that are connected to this handler. A ServerSession whose server endpoint /// is an HLE implementation is kept alive by this list for the duration of the connection. std::vector connected_sessions; + +private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & connected_sessions; + } + friend class boost::serialization::access; }; +// NOTE: The below classes are ephemeral and don't need serialization + class MappedBuffer { public: MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, diff --git a/src/core/hle/kernel/ipc.h b/src/core/hle/kernel/ipc.h index b06079958..46d86a528 100644 --- a/src/core/hle/kernel/ipc.h +++ b/src/core/hle/kernel/ipc.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/common_types.h" #include "core/hle/ipc.h" #include "core/hle/kernel/thread.h" @@ -26,6 +27,20 @@ struct MappedBufferContext { std::unique_ptr buffer; std::unique_ptr reserve_buffer; + +private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & permissions; + ar & size; + ar & source_address; + ar & target_address; + // TODO: Check whether we need these. If we do, add a field for the size and/or change to a 'vector' + //ar & buffer; + //ar & reserve_buffer; + } + friend class boost::serialization::access; }; /// Performs IPC command buffer translation from one process to another. diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 191b43ea8..0aeb86a78 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -11,6 +11,7 @@ #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/thread.h" +#include "core/hle/kernel/hle_ipc.h" SERIALIZE_EXPORT_IMPL(Kernel::ServerPort) @@ -50,4 +51,14 @@ KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::strin return std::make_pair(std::move(server_port), std::move(client_port)); } +template +void ServerPort::serialize(Archive& ar, const unsigned int file_version) +{ + ar & boost::serialization::base_object(*this); + ar & name; + ar & pending_sessions; + ar & hle_handler; +} +SERIALIZE_IMPL(ServerPort) + } // namespace Kernel diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index e0014ee7c..f055cd267 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -67,13 +67,7 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & name; - ar & pending_sessions; - //ar & hle_handler; - } + void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 6112eefac..05b469c38 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -115,10 +115,10 @@ private: ar & boost::serialization::base_object(*this); ar & name; ar & parent; - //ar & hle_handler; + ar & hle_handler; ar & pending_requesting_threads; ar & currently_handling; - //ar & mapped_buffer_context; + ar & mapped_buffer_context; } }; diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index f264c49bd..a2a1f90f9 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -8,6 +8,7 @@ #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/hle_ipc.h" SERIALIZE_IMPL(Kernel::Session) diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 42d783513..8aaf3df1f 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -117,7 +117,7 @@ private: ar & owner_process; ar & base_address; ar & name; - ar & *(reinterpret_cast(&holding_memory));; + ar & *(reinterpret_cast(&holding_memory)); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 6e47fd152..9cdaff72d 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" @@ -80,6 +83,14 @@ private: // For IPC Recorder /// client port Object id -> service name std::unordered_map registered_services_inverse; + + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & registered_services; + ar & registered_services_inverse; // TODO: Instead, compute this from registered_services + } + friend class boost::serialization::access; }; } // namespace Service::SM From ac0337d8dfcd1a95090b5a8a6982d3bc91218e32 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 17:49:56 +0000 Subject: [PATCH 017/129] Started IPC services serialization --- TODO | 8 +++--- src/common/construct.h | 35 ++++++++++++++++++++++++++ src/core/hle/kernel/hle_ipc.h | 5 ++++ src/core/hle/service/ac/ac.cpp | 3 +++ src/core/hle/service/ac/ac.h | 46 ++++++++++++++++++++++++++++++++++ src/core/hle/service/service.h | 1 + src/core/hle/service/sm/sm.h | 19 +++++++++++--- src/core/memory.cpp | 2 +- 8 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 src/common/construct.h diff --git a/TODO b/TODO index f3e1ea943..bc62720d6 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,11 @@ ☐ Save/load UI ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) + ☐ Page tables + ☐ Skip N3DS RAM if unused ✔ DSP @done(19-08-13 15:41) ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) - ☐ Fix or ignore inverse map + ✔ Fix or ignore inverse map @done(19-12-23 12:46) ☐ App loader ☐ Archive manager ☐ Custom texture cache @@ -58,8 +60,8 @@ ☐ VM Manager @started(19-08-13 16:46) Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) - ☐ Service - ☐ AC + ☐ Service @started(19-12-23 12:49) + ☐ AC @started(19-12-23 12:48) ☐ ACT ☐ AM ☐ APT diff --git a/src/common/construct.h b/src/common/construct.h new file mode 100644 index 000000000..28f4cc349 --- /dev/null +++ b/src/common/construct.h @@ -0,0 +1,35 @@ +#include + +#define BOOST_SERIALIZATION_FRIENDS \ + friend class boost::serialization::access; \ + friend class construct_access; + +class construct_access { +public: + template + static inline void save_construct(Archive & ar, const T * t, const unsigned int file_version) { + t->save_construct(ar, file_version); + } + template + static inline void load_construct(Archive & ar, T * t, const unsigned int file_version) { + T::load_construct(ar, t, file_version); + } +}; + +#define BOOST_SERIALIZATION_CONSTRUCT(T) \ +namespace boost { namespace serialization { \ +\ + template \ + inline void save_construct_data( \ + Archive & ar, const T * t, const unsigned int file_version \ + ){ \ + construct_access::save_construct(ar, t, file_version); \ + } \ +\ + template \ + inline void load_construct_data( \ + Archive & ar, T * t, const unsigned int file_version \ + ){ \ + construct_access::load_construct(ar, t, file_version); \ + } \ +}} diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index be3a20e79..da89ad39a 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -75,6 +75,10 @@ public: /// in each service must inherit from this. struct SessionDataBase { virtual ~SessionDataBase() = default; + private: + template + void serialize(Archive& ar, const unsigned int file_version) { } + friend class boost::serialization::access; }; protected: @@ -94,6 +98,7 @@ protected: struct SessionInfo { SessionInfo(std::shared_ptr session, std::unique_ptr data); + SessionInfo() = default; std::shared_ptr session; std::unique_ptr data; diff --git a/src/core/hle/service/ac/ac.cpp b/src/core/hle/service/ac/ac.cpp index 9d40b9661..acae47fd5 100644 --- a/src/core/hle/service/ac/ac.cpp +++ b/src/core/hle/service/ac/ac.cpp @@ -5,6 +5,7 @@ #include #include "common/common_types.h" #include "common/logging/log.h" +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" @@ -16,6 +17,8 @@ #include "core/hle/service/ac/ac_u.h" #include "core/memory.h" +SERIALIZE_EXPORT_IMPL(Service::AC::Module::Interface) + namespace Service::AC { void Module::Interface::CreateDefaultConfig(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x1, 0, 0); diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h index f3554c876..12e304f59 100644 --- a/src/core/hle/service/ac/ac.h +++ b/src/core/hle/service/ac/ac.h @@ -6,6 +6,9 @@ #include #include +#include +#include +#include "common/construct.h" #include "core/hle/service/service.h" namespace Core { @@ -139,6 +142,34 @@ public: protected: std::shared_ptr ac; + + private: + template + void save_construct(Archive& ar, const unsigned int file_version) const + { + ar << ac; + ar << GetServiceName(); + ar << GetMaxSessions(); + } + + template + static void load_construct(Archive& ar, Interface* t, const unsigned int file_version) + { + std::shared_ptr ac; + std::string name; + u32 max_sessions; + ar >> ac; + ar >> name; + ar >> max_sessions; + ::new(t)Interface(ac, name.c_str(), max_sessions); + } + + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & boost::serialization::base_object(*this); + } + BOOST_SERIALIZATION_FRIENDS }; protected: @@ -153,8 +184,23 @@ protected: std::shared_ptr close_event; std::shared_ptr connect_event; std::shared_ptr disconnect_event; + +private: + template + void serialize(Archive& ar, const unsigned int file_version) + { + ar & ac_connected; + ar & close_event; + ar & connect_event; + ar & disconnect_event; + // default_config is never written to + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::AC + +BOOST_SERIALIZATION_CONSTRUCT(Service::AC::Module::Interface) +BOOST_CLASS_EXPORT_KEY(Service::AC::Module::Interface) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index db6a0ad23..f05c15f23 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -85,6 +85,7 @@ private: using InvokerFn = void(ServiceFrameworkBase* object, HandlerFnP member, Kernel::HLERequestContext& ctx); + // TODO: Replace all these with virtual functions! ServiceFrameworkBase(const char* service_name, u32 max_sessions, InvokerFn* handler_invoker); ~ServiceFrameworkBase() override; diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 9cdaff72d..d91732da9 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" @@ -85,11 +86,23 @@ private: std::unordered_map registered_services_inverse; template - void serialize(Archive& ar, const unsigned int file_version) + void save(Archive& ar, const unsigned int file_version) const { - ar & registered_services; - ar & registered_services_inverse; // TODO: Instead, compute this from registered_services + ar << registered_services; } + + template + void load(Archive& ar, const unsigned int file_version) + { + ar >> registered_services; + registered_services_inverse.clear(); + for (const auto& pair : registered_services) { + registered_services_inverse.emplace(pair.second->GetObjectId(), pair.first); + } + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() + friend class boost::serialization::access; }; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index a07cc2e13..7264e1ec4 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -56,7 +56,7 @@ private: std::array linear_heap{}; std::array new_linear_heap{}; - static_assert(sizeof(bool) == 1); // TODO: Maybe this isn't true? + static_assert(sizeof(bool) == 1); friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int file_version) From 3fd5c431f157964bd08fcde73b0352979ff15f91 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 22:39:02 +0000 Subject: [PATCH 018/129] Service serialization framework; done AC --- TODO | 2 +- src/common/construct.h | 4 --- src/core/hle/service/ac/ac.cpp | 14 +++++++++-- src/core/hle/service/ac/ac.h | 43 +++----------------------------- src/core/hle/service/ac/ac_i.cpp | 3 +++ src/core/hle/service/ac/ac_i.h | 7 ++++++ src/core/hle/service/service.h | 25 +++++++++++++++++++ 7 files changed, 51 insertions(+), 47 deletions(-) diff --git a/TODO b/TODO index bc62720d6..b9f4fe46b 100644 --- a/TODO +++ b/TODO @@ -61,7 +61,7 @@ Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) ☐ Service @started(19-12-23 12:49) - ☐ AC @started(19-12-23 12:48) + ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) ☐ ACT ☐ AM ☐ APT diff --git a/src/common/construct.h b/src/common/construct.h index 28f4cc349..6ef9af1ef 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -1,9 +1,5 @@ #include -#define BOOST_SERIALIZATION_FRIENDS \ - friend class boost::serialization::access; \ - friend class construct_access; - class construct_access { public: template diff --git a/src/core/hle/service/ac/ac.cpp b/src/core/hle/service/ac/ac.cpp index acae47fd5..356df5a63 100644 --- a/src/core/hle/service/ac/ac.cpp +++ b/src/core/hle/service/ac/ac.cpp @@ -17,8 +17,6 @@ #include "core/hle/service/ac/ac_u.h" #include "core/memory.h" -SERIALIZE_EXPORT_IMPL(Service::AC::Module::Interface) - namespace Service::AC { void Module::Interface::CreateDefaultConfig(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x1, 0, 0); @@ -182,4 +180,16 @@ void InstallInterfaces(Core::System& system) { std::make_shared(ac)->InstallAsService(service_manager); } +template +void Module::serialize(Archive& ar, const unsigned int) +{ + ar & ac_connected; + ar & close_event; + ar & connect_event; + ar & disconnect_event; + // default_config is never written to +} + } // namespace Service::AC + +SERIALIZE_IMPL(Service::AC::Module) diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h index 12e304f59..b7a079b33 100644 --- a/src/core/hle/service/ac/ac.h +++ b/src/core/hle/service/ac/ac.h @@ -8,7 +8,6 @@ #include #include #include -#include "common/construct.h" #include "core/hle/service/service.h" namespace Core { @@ -19,6 +18,8 @@ namespace Kernel { class Event; } +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Service::AC::Module::Interface) + namespace Service::AC { class Module final { public: @@ -142,34 +143,6 @@ public: protected: std::shared_ptr ac; - - private: - template - void save_construct(Archive& ar, const unsigned int file_version) const - { - ar << ac; - ar << GetServiceName(); - ar << GetMaxSessions(); - } - - template - static void load_construct(Archive& ar, Interface* t, const unsigned int file_version) - { - std::shared_ptr ac; - std::string name; - u32 max_sessions; - ar >> ac; - ar >> name; - ar >> max_sessions; - ::new(t)Interface(ac, name.c_str(), max_sessions); - } - - template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - } - BOOST_SERIALIZATION_FRIENDS }; protected: @@ -187,20 +160,10 @@ protected: private: template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & ac_connected; - ar & close_event; - ar & connect_event; - ar & disconnect_event; - // default_config is never written to - } + void serialize(Archive& ar, const unsigned int file_version); friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::AC - -BOOST_SERIALIZATION_CONSTRUCT(Service::AC::Module::Interface) -BOOST_CLASS_EXPORT_KEY(Service::AC::Module::Interface) diff --git a/src/core/hle/service/ac/ac_i.cpp b/src/core/hle/service/ac/ac_i.cpp index 0dde7bf90..e4cc4c1f1 100644 --- a/src/core/hle/service/ac/ac_i.cpp +++ b/src/core/hle/service/ac/ac_i.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/ac/ac_i.h" +#include "common/archives.h" namespace Service::AC { @@ -33,3 +34,5 @@ AC_I::AC_I(std::shared_ptr ac) : Module::Interface(std::move(ac), "ac:i" } } // namespace Service::AC + +SERIALIZE_EXPORT_IMPL(Service::AC::AC_I) diff --git a/src/core/hle/service/ac/ac_i.h b/src/core/hle/service/ac/ac_i.h index bca91aabe..d7ab22b25 100644 --- a/src/core/hle/service/ac/ac_i.h +++ b/src/core/hle/service/ac/ac_i.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "core/hle/service/ac/ac.h" namespace Service::AC { @@ -12,6 +13,12 @@ namespace Service::AC { class AC_I final : public Module::Interface { public: explicit AC_I(std::shared_ptr ac); + +private: + SERVICE_SERIALIZATION(AC_I, ac) }; } // namespace Service::AC + +BOOST_CLASS_EXPORT_KEY(Service::AC::AC_I) +BOOST_SERIALIZATION_CONSTRUCT(Service::AC::AC_I) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index f05c15f23..d124b0070 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -10,7 +10,9 @@ #include #include #include +#include #include "common/common_types.h" +#include "common/construct.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/object.h" #include "core/hle/service/sm/sm.h" @@ -194,3 +196,26 @@ struct ServiceModuleInfo { extern const std::array service_module_map; } // namespace Service + +#define SERVICE_SERIALIZATION(T, MFIELD) \ + template \ + void save_construct(Archive& ar, const unsigned int file_version) const \ + { \ + ar << MFIELD; \ + } \ + \ + template \ + static void load_construct(Archive& ar, T* t, const unsigned int file_version) \ + { \ + std::shared_ptr MFIELD; \ + ar >> MFIELD; \ + ::new(t)T(MFIELD); \ + } \ + \ + template \ + void serialize(Archive& ar, const unsigned int) \ + { \ + ar & boost::serialization::base_object(*this); \ + } \ + friend class boost::serialization::access; \ + friend class construct_access; From 89e4e49a63e53d7ed73170091037067a5c137be1 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 23:17:24 +0000 Subject: [PATCH 019/129] Finished AC and ACT service serialization --- TODO | 2 +- src/core/hle/service/ac/ac.h | 2 -- src/core/hle/service/ac/ac_i.h | 1 - src/core/hle/service/ac/ac_u.cpp | 3 +++ src/core/hle/service/ac/ac_u.h | 6 ++++++ src/core/hle/service/act/act.h | 6 +++++- src/core/hle/service/act/act_a.cpp | 3 +++ src/core/hle/service/act/act_a.h | 5 +++++ src/core/hle/service/act/act_u.cpp | 3 +++ src/core/hle/service/act/act_u.h | 5 +++++ src/core/hle/service/service.h | 2 ++ 11 files changed, 33 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index b9f4fe46b..a7488a20f 100644 --- a/TODO +++ b/TODO @@ -62,7 +62,7 @@ ✔ Wait object @done(19-08-13 16:46) ☐ Service @started(19-12-23 12:49) ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) - ☐ ACT + ✔ ACT @done(19-12-24 23:17) ☐ AM ☐ APT ☐ BOSS diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h index b7a079b33..0f31ca1b4 100644 --- a/src/core/hle/service/ac/ac.h +++ b/src/core/hle/service/ac/ac.h @@ -6,8 +6,6 @@ #include #include -#include -#include #include "core/hle/service/service.h" namespace Core { diff --git a/src/core/hle/service/ac/ac_i.h b/src/core/hle/service/ac/ac_i.h index d7ab22b25..e05bac803 100644 --- a/src/core/hle/service/ac/ac_i.h +++ b/src/core/hle/service/ac/ac_i.h @@ -5,7 +5,6 @@ #pragma once #include -#include #include "core/hle/service/ac/ac.h" namespace Service::AC { diff --git a/src/core/hle/service/ac/ac_u.cpp b/src/core/hle/service/ac/ac_u.cpp index d62d7ccb6..429942f7d 100644 --- a/src/core/hle/service/ac/ac_u.cpp +++ b/src/core/hle/service/ac/ac_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/ac/ac_u.h" +#include "common/archives.h" namespace Service::AC { @@ -33,3 +34,5 @@ AC_U::AC_U(std::shared_ptr ac) : Module::Interface(std::move(ac), "ac:u" } } // namespace Service::AC + +SERIALIZE_EXPORT_IMPL(Service::AC::AC_U) diff --git a/src/core/hle/service/ac/ac_u.h b/src/core/hle/service/ac/ac_u.h index 18efcd1e6..c15870b51 100644 --- a/src/core/hle/service/ac/ac_u.h +++ b/src/core/hle/service/ac/ac_u.h @@ -12,6 +12,12 @@ namespace Service::AC { class AC_U final : public Module::Interface { public: explicit AC_U(std::shared_ptr ac); + +private: + SERVICE_SERIALIZATION(AC_U, ac) }; } // namespace Service::AC + +BOOST_CLASS_EXPORT_KEY(Service::AC::AC_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::AC::AC_U) diff --git a/src/core/hle/service/act/act.h b/src/core/hle/service/act/act.h index 884678890..c327cdaef 100644 --- a/src/core/hle/service/act/act.h +++ b/src/core/hle/service/act/act.h @@ -20,9 +20,13 @@ public: Interface(std::shared_ptr act, const char* name); ~Interface(); - private: + protected: std::shared_ptr act; }; +private: + template + inline void serialize(Archive& ar, const unsigned int file_version) { } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); diff --git a/src/core/hle/service/act/act_a.cpp b/src/core/hle/service/act/act_a.cpp index 7a33f9175..b4bf750f7 100644 --- a/src/core/hle/service/act/act_a.cpp +++ b/src/core/hle/service/act/act_a.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/act/act_a.h" +#include "common/archives.h" namespace Service::ACT { @@ -24,3 +25,5 @@ ACT_A::ACT_A(std::shared_ptr act) : Module::Interface(std::move(act), "a } } // namespace Service::ACT + +SERIALIZE_EXPORT_IMPL(Service::ACT::ACT_A) diff --git a/src/core/hle/service/act/act_a.h b/src/core/hle/service/act/act_a.h index 48a79aab7..036a96182 100644 --- a/src/core/hle/service/act/act_a.h +++ b/src/core/hle/service/act/act_a.h @@ -11,6 +11,11 @@ namespace Service::ACT { class ACT_A final : public Module::Interface { public: explicit ACT_A(std::shared_ptr act); +private: + SERVICE_SERIALIZATION(ACT_A, act) }; } // namespace Service::ACT + +BOOST_CLASS_EXPORT_KEY(Service::ACT::ACT_A) +BOOST_SERIALIZATION_CONSTRUCT(Service::ACT::ACT_A) diff --git a/src/core/hle/service/act/act_u.cpp b/src/core/hle/service/act/act_u.cpp index 99978d9ca..599bec18a 100644 --- a/src/core/hle/service/act/act_u.cpp +++ b/src/core/hle/service/act/act_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/act/act_u.h" +#include "common/archives.h" namespace Service::ACT { @@ -20,3 +21,5 @@ ACT_U::ACT_U(std::shared_ptr act) : Module::Interface(std::move(act), "a } } // namespace Service::ACT + +SERIALIZE_EXPORT_IMPL(Service::ACT::ACT_U) diff --git a/src/core/hle/service/act/act_u.h b/src/core/hle/service/act/act_u.h index 3aca428e6..14d924025 100644 --- a/src/core/hle/service/act/act_u.h +++ b/src/core/hle/service/act/act_u.h @@ -11,6 +11,11 @@ namespace Service::ACT { class ACT_U final : public Module::Interface { public: explicit ACT_U(std::shared_ptr act); +private: + SERVICE_SERIALIZATION(ACT_U, act) }; } // namespace Service::ACT + +BOOST_CLASS_EXPORT_KEY(Service::ACT::ACT_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::ACT::ACT_U) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index d124b0070..bdad47ea8 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "common/construct.h" #include "core/hle/kernel/hle_ipc.h" From e707685c2a1cfbede81e30594d865b11268a5362 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 24 Dec 2019 23:53:51 +0000 Subject: [PATCH 020/129] Serialize AM services --- TODO | 2 +- src/core/hle/service/am/am.cpp | 8 +++++--- src/core/hle/service/am/am.h | 26 ++++++++++++++++++++++++-- src/core/hle/service/am/am_app.cpp | 3 +++ src/core/hle/service/am/am_app.h | 5 +++++ src/core/hle/service/am/am_net.cpp | 3 +++ src/core/hle/service/am/am_net.h | 5 +++++ src/core/hle/service/am/am_sys.cpp | 3 +++ src/core/hle/service/am/am_sys.h | 5 +++++ src/core/hle/service/am/am_u.cpp | 3 +++ src/core/hle/service/am/am_u.h | 5 +++++ src/core/hle/service/fs/archive.cpp | 3 ++- src/core/hle/service/fs/file.cpp | 10 +++++----- src/core/hle/service/fs/file.h | 4 ++-- 14 files changed, 71 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index a7488a20f..673ef0a14 100644 --- a/TODO +++ b/TODO @@ -63,7 +63,7 @@ ☐ Service @started(19-12-23 12:49) ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) ✔ ACT @done(19-12-24 23:17) - ☐ AM + ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) ☐ APT ☐ BOSS ☐ CAM diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 65b9c3e01..45ed29e6c 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1021,7 +1021,7 @@ void Module::Interface::BeginImportProgram(Kernel::HLERequestContext& ctx) { // Citra will store contents out to sdmc/nand const FileSys::Path cia_path = {}; auto file = std::make_shared( - am->system, std::make_unique(media_type), cia_path); + am->kernel, std::make_unique(media_type), cia_path); am->cia_installing = true; @@ -1048,7 +1048,7 @@ void Module::Interface::BeginImportProgramTemporarily(Kernel::HLERequestContext& // contents out to sdmc/nand const FileSys::Path cia_path = {}; auto file = std::make_shared( - am->system, std::make_unique(FS::MediaType::NAND), cia_path); + am->kernel, std::make_unique(FS::MediaType::NAND), cia_path); am->cia_installing = true; @@ -1450,11 +1450,13 @@ void Module::Interface::GetMetaDataFromCia(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(output_buffer); } -Module::Module(Core::System& system) : system(system) { +Module::Module(Core::System& system) : kernel(system.Kernel()) { ScanForAllTitles(); system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex"); } +Module::Module(Kernel::KernelSystem& kernel) : kernel(kernel) { } + Module::~Module() = default; void InstallInterfaces(Core::System& system) { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 0912dde40..88a70bf10 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "core/file_sys/cia_container.h" #include "core/file_sys/file_backend.h" @@ -150,6 +153,8 @@ std::string GetMediaTitlePath(Service::FS::MediaType media_type); class Module final { public: explicit Module(Core::System& system); + explicit Module(Kernel::KernelSystem& kernel); + Module() = default; ~Module(); class Interface : public ServiceFramework { @@ -557,7 +562,7 @@ public: */ void GetMetaDataFromCia(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr am; }; @@ -573,12 +578,29 @@ private: */ void ScanForAllTitles(); - Core::System& system; + Kernel::KernelSystem& kernel; bool cia_installing = false; std::array, 3> am_title_list; std::shared_ptr system_updater_mutex; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & cia_installing; + ar & am_title_list; + ar & system_updater_mutex; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::AM + +namespace boost::serialization { + template + inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) + { + ::new(t)Service::AM::Module(*Kernel::g_kernel); + } +} diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp index cee1aa81b..52d256ca2 100644 --- a/src/core/hle/service/am/am_app.cpp +++ b/src/core/hle/service/am/am_app.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/am/am_app.h" +#include "common/archives.h" namespace Service::AM { @@ -26,3 +27,5 @@ AM_APP::AM_APP(std::shared_ptr am) : Module::Interface(std::move(am), "a } } // namespace Service::AM + +SERIALIZE_EXPORT_IMPL(Service::AM::AM_APP) diff --git a/src/core/hle/service/am/am_app.h b/src/core/hle/service/am/am_app.h index 67cf8ba2e..e78b5ef70 100644 --- a/src/core/hle/service/am/am_app.h +++ b/src/core/hle/service/am/am_app.h @@ -11,6 +11,11 @@ namespace Service::AM { class AM_APP final : public Module::Interface { public: explicit AM_APP(std::shared_ptr am); +private: + SERVICE_SERIALIZATION(AM_APP, am) }; } // namespace Service::AM + +BOOST_CLASS_EXPORT_KEY(Service::AM::AM_APP) +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::AM_APP) diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index 120ee53e7..44c852c19 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/am/am_net.h" +#include "common/archives.h" namespace Service::AM { @@ -123,3 +124,5 @@ AM_NET::AM_NET(std::shared_ptr am) : Module::Interface(std::move(am), "a } } // namespace Service::AM + +SERIALIZE_EXPORT_IMPL(Service::AM::AM_NET) diff --git a/src/core/hle/service/am/am_net.h b/src/core/hle/service/am/am_net.h index a5adbd7e5..74e335b76 100644 --- a/src/core/hle/service/am/am_net.h +++ b/src/core/hle/service/am/am_net.h @@ -11,6 +11,11 @@ namespace Service::AM { class AM_NET final : public Module::Interface { public: explicit AM_NET(std::shared_ptr am); +private: + SERVICE_SERIALIZATION(AM_NET, am) }; } // namespace Service::AM + +BOOST_CLASS_EXPORT_KEY(Service::AM::AM_NET) +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::AM_NET) diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp index ca4affbc2..c6817fe87 100644 --- a/src/core/hle/service/am/am_sys.cpp +++ b/src/core/hle/service/am/am_sys.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/am/am_sys.h" +#include "common/archives.h" namespace Service::AM { @@ -71,3 +72,5 @@ AM_SYS::AM_SYS(std::shared_ptr am) : Module::Interface(std::move(am), "a } } // namespace Service::AM + +SERIALIZE_EXPORT_IMPL(Service::AM::AM_SYS) diff --git a/src/core/hle/service/am/am_sys.h b/src/core/hle/service/am/am_sys.h index b142916ca..028837f3d 100644 --- a/src/core/hle/service/am/am_sys.h +++ b/src/core/hle/service/am/am_sys.h @@ -11,6 +11,11 @@ namespace Service::AM { class AM_SYS final : public Module::Interface { public: explicit AM_SYS(std::shared_ptr am); +private: + SERVICE_SERIALIZATION(AM_SYS, am) }; } // namespace Service::AM + +BOOST_CLASS_EXPORT_KEY(Service::AM::AM_SYS) +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::AM_SYS) diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp index 840860ec0..c9b80bf06 100644 --- a/src/core/hle/service/am/am_u.cpp +++ b/src/core/hle/service/am/am_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/am/am_u.h" +#include "common/archives.h" namespace Service::AM { @@ -83,3 +84,5 @@ AM_U::AM_U(std::shared_ptr am) : Module::Interface(std::move(am), "am:u" } } // namespace Service::AM + +SERIALIZE_EXPORT_IMPL(Service::AM::AM_U) diff --git a/src/core/hle/service/am/am_u.h b/src/core/hle/service/am/am_u.h index 1d732c90a..b19d48167 100644 --- a/src/core/hle/service/am/am_u.h +++ b/src/core/hle/service/am/am_u.h @@ -11,6 +11,11 @@ namespace Service::AM { class AM_U final : public Module::Interface { public: explicit AM_U(std::shared_ptr am); +private: + SERVICE_SERIALIZATION(AM_U, am) }; } // namespace Service::AM + +BOOST_CLASS_EXPORT_KEY(Service::AM::AM_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::AM_U) diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 6e179978b..90dfad62f 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -27,6 +27,7 @@ #include "core/file_sys/file_backend.h" #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" +#include "core/core.h" namespace Service::FS { @@ -90,7 +91,7 @@ ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys: if (backend.Failed()) return std::make_tuple(backend.Code(), open_timeout_ns); - auto file = std::shared_ptr(new File(system, std::move(backend).Unwrap(), path)); + auto file = std::shared_ptr(new File(system.Kernel(), std::move(backend).Unwrap(), path)); return std::make_tuple(MakeResult>(std::move(file)), open_timeout_ns); } diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index e31f89d0e..946e27211 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -15,9 +15,9 @@ namespace Service::FS { -File::File(Core::System& system, std::unique_ptr&& backend, +File::File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path) - : ServiceFramework("", 1), path(path), backend(std::move(backend)), system(system) { + : ServiceFramework("", 1), path(path), backend(std::move(backend)), kernel(kernel) { static const FunctionInfo functions[] = { {0x08010100, &File::OpenSubFile, "OpenSubFile"}, {0x080200C2, &File::Read, "Read"}, @@ -197,7 +197,7 @@ void File::OpenLinkFile(Kernel::HLERequestContext& ctx) { using Kernel::ServerSession; IPC::RequestParser rp(ctx, 0x080C, 0, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - auto [server, client] = system.Kernel().CreateSessionPair(GetName()); + auto [server, client] = kernel.CreateSessionPair(GetName()); ClientConnected(server); FileSessionSlot* slot = GetSessionData(server); @@ -243,7 +243,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { using Kernel::ClientSession; using Kernel::ServerSession; - auto [server, client] = system.Kernel().CreateSessionPair(GetName()); + auto [server, client] = kernel.CreateSessionPair(GetName()); ClientConnected(server); FileSessionSlot* slot = GetSessionData(server); @@ -257,7 +257,7 @@ void File::OpenSubFile(Kernel::HLERequestContext& ctx) { } std::shared_ptr File::Connect() { - auto [server, client] = system.Kernel().CreateSessionPair(GetName()); + auto [server, client] = kernel.CreateSessionPair(GetName()); ClientConnected(server); FileSessionSlot* slot = GetSessionData(server); diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 062fcd5e7..ff4a5670a 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -25,7 +25,7 @@ struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { // Consider splitting ServiceFramework interface. class File final : public ServiceFramework { public: - File(Core::System& system, std::unique_ptr&& backend, + File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path); ~File() = default; @@ -59,7 +59,7 @@ private: void OpenLinkFile(Kernel::HLERequestContext& ctx); void OpenSubFile(Kernel::HLERequestContext& ctx); - Core::System& system; + Kernel::KernelSystem& kernel; }; } // namespace Service::FS From 3e752002c4245746b4c1bf47f75af48ed866cd97 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 25 Dec 2019 18:51:56 +0000 Subject: [PATCH 021/129] Replace g_kernel with Core::Global etc. --- TODO | 2 +- src/core/core.cpp | 9 +++++++-- src/core/global.h | 6 ++++++ src/core/hle/kernel/address_arbiter.cpp | 3 ++- src/core/hle/kernel/client_port.cpp | 3 ++- src/core/hle/kernel/kernel.cpp | 2 -- src/core/hle/kernel/kernel.h | 2 -- src/core/hle/kernel/mutex.cpp | 3 ++- src/core/hle/kernel/process.cpp | 7 ++++++- src/core/hle/kernel/process.h | 3 ++- src/core/hle/kernel/server_session.cpp | 3 ++- src/core/hle/kernel/thread.cpp | 5 +++-- src/core/hle/kernel/timer.cpp | 3 ++- src/core/hle/service/am/am.h | 3 ++- src/video_core/pica.cpp | 6 ++++++ 15 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 src/core/global.h diff --git a/TODO b/TODO index 673ef0a14..7309acb1a 100644 --- a/TODO +++ b/TODO @@ -26,7 +26,7 @@ ✔ Shader @done(19-08-13 16:03) ☐ HLE @started(19-08-13 16:43) ☐ Kernel @started(19-08-13 16:43) - Most of these require adding g_kernel + Most of these require adding Core::Global ✔ Address arbiter @done(19-08-13 16:40) ✔ Client port @done(19-08-13 16:40) ✔ Client session @done(19-08-13 16:40) diff --git a/src/core/core.cpp b/src/core/core.cpp index 8ca3a2ab5..055eadae2 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -25,6 +25,7 @@ #endif #include "core/custom_tex_cache.h" #include "core/gdbstub/gdbstub.h" +#include "core/global.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" @@ -46,6 +47,12 @@ namespace Core { /*static*/ System System::s_instance; +template <> +Core::System& Global() { return System::GetInstance(); } + +template <> +Kernel::KernelSystem& Global() { return System::GetInstance().Kernel(); } + System::ResultStatus System::RunLoop(bool tight_loop) { status = ResultStatus::Success; if (!cpu_core) { @@ -204,7 +211,6 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo kernel = std::make_unique(*memory, *timing, [this] { PrepareReschedule(); }, system_mode); - Kernel::g_kernel = kernel.get(); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -368,7 +374,6 @@ void System::Shutdown() { service_manager.reset(); dsp_core.reset(); cpu_core.reset(); - Kernel::g_kernel = nullptr; kernel.reset(); timing.reset(); app_loader.reset(); diff --git a/src/core/global.h b/src/core/global.h new file mode 100644 index 000000000..8dfd022d8 --- /dev/null +++ b/src/core/global.h @@ -0,0 +1,6 @@ +namespace Core { + +template +T& Global(); + +} // namespace Core diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index c4fb4fd99..ca120e6f9 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -11,6 +11,7 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" #include "core/memory.h" +#include "core/global.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Kernel namespace @@ -68,7 +69,7 @@ std::shared_ptr AddressArbiter::ResumeHighestPriorityThread(VAddr addres return thread; } -AddressArbiter::AddressArbiter() : kernel(*g_kernel) {} +AddressArbiter::AddressArbiter() : kernel(Core::Global()) {} AddressArbiter::~AddressArbiter() {} std::shared_ptr KernelSystem::CreateAddressArbiter(std::string name) { diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 3334a278b..f9202035c 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -11,6 +11,7 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" +#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::ClientPort) @@ -26,7 +27,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto [server, client] = g_kernel->CreateSessionPair(server_port->GetName(), SharedFrom(this)); + auto [server, client] = Core::Global().CreateSessionPair(server_port->GetName(), SharedFrom(this)); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(server); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 4f9a02410..a45973968 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -18,8 +18,6 @@ namespace Kernel { -KernelSystem* g_kernel; - /// Initialize the kernel KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, std::function prepare_reschedule_callback, u32 system_mode) diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index c662882f5..6ca3267fb 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -292,6 +292,4 @@ private: void serialize(Archive& ar, const unsigned int file_version); }; -extern KernelSystem* g_kernel; - } // namespace Kernel diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index b8a3d143b..16bcd3af2 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -12,6 +12,7 @@ #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" +#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Mutex) @@ -26,7 +27,7 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } -Mutex::Mutex() : kernel(*g_kernel) {} +Mutex::Mutex() : kernel(Core::Global()) {} Mutex::~Mutex() {} std::shared_ptr KernelSystem::CreateMutex(bool initial_locked, std::string name) { diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 5fad4fd85..72f882c56 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -18,6 +18,7 @@ #include "core/hle/kernel/thread.h" #include "core/hle/kernel/vm_manager.h" #include "core/memory.h" +#include "core/global.h" namespace Kernel { @@ -427,7 +428,11 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe return RESULT_SUCCESS; } -Kernel::Process::Process() : kernel(*g_kernel), handle_table(*g_kernel), vm_manager(g_kernel->memory) +Kernel::Process::Process() : Kernel::Process::Process(Core::Global()) +{ +} + +Kernel::Process::Process(KernelSystem& kernel) : kernel(kernel), handle_table(kernel), vm_manager(kernel.memory) { kernel.memory.RegisterPageTable(&vm_manager.page_table); } diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index edda20c1f..70a5f212b 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -143,7 +143,8 @@ private: class Process final : public Object { public: - explicit Process(); + Process(); + explicit Process(KernelSystem& kernel); ~Process() override; std::string GetTypeName() const override { diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index f2ceb899e..146142f08 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -10,12 +10,13 @@ #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" +#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) namespace Kernel { -ServerSession::ServerSession() : kernel(*g_kernel) {} +ServerSession::ServerSession() : kernel(Core::Global()) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 409dcc886..98fe85175 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -24,6 +24,7 @@ #include "core/hle/kernel/thread.h" #include "core/hle/result.h" #include "core/memory.h" +#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Thread) @@ -66,8 +67,8 @@ u32 ThreadManager::NewThreadId() { } Thread::Thread() - : context(g_kernel->GetThreadManager().NewContext()), - thread_manager(g_kernel->GetThreadManager()) {} + : context(Core::Global().GetThreadManager().NewContext()), + thread_manager(Core::Global().GetThreadManager()) {} Thread::~Thread() {} Thread* ThreadManager::GetCurrentThread() const { diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index f073c3312..422cf990c 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -11,10 +11,11 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" +#include "core/global.h" namespace Kernel { -Timer::Timer() : kernel(*g_kernel), timer_manager(g_kernel->GetTimerManager()) {} +Timer::Timer() : kernel(Core::Global()), timer_manager(Core::Global().GetTimerManager()) {} Timer::~Timer() { Cancel(); timer_manager.timer_callback_table.erase(callback_id); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 88a70bf10..771bbfb53 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -18,6 +18,7 @@ #include "core/hle/kernel/mutex.h" #include "core/hle/result.h" #include "core/hle/service/service.h" +#include "core/global.h" namespace Core { class System; @@ -601,6 +602,6 @@ namespace boost::serialization { template inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) { - ::new(t)Service::AM::Module(*Kernel::g_kernel); + ::new(t)Service::AM::Module(Core::Global()); } } diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp index 1475e3a92..0b5aaa682 100644 --- a/src/video_core/pica.cpp +++ b/src/video_core/pica.cpp @@ -8,6 +8,12 @@ #include "video_core/pica_state.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" +#include "core/global.h" + +namespace Core { + template <> + Pica::State& Global() { return Pica::g_state; } +} namespace Pica { From 5265c79056c4e3546b3550018f0f1cfc4b7d4414 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 25 Dec 2019 21:43:51 +0000 Subject: [PATCH 022/129] APT service serialization --- TODO | 2 +- src/common/serialization/optional.h | 91 +++++++++++++++++++++++ src/core/global.h | 5 ++ src/core/hle/kernel/shared_memory.cpp | 7 +- src/core/hle/kernel/shared_memory.h | 2 +- src/core/hle/service/ac/ac_i.h | 2 +- src/core/hle/service/ac/ac_u.h | 2 +- src/core/hle/service/act/act_a.h | 2 +- src/core/hle/service/act/act_u.h | 2 +- src/core/hle/service/am/am_app.h | 2 +- src/core/hle/service/am/am_net.h | 2 +- src/core/hle/service/am/am_sys.h | 2 +- src/core/hle/service/am/am_u.h | 2 +- src/core/hle/service/apt/applet_manager.h | 60 +++++++++++++++ src/core/hle/service/apt/apt.cpp | 28 +++++++ src/core/hle/service/apt/apt.h | 17 ++++- src/core/hle/service/apt/apt_a.cpp | 3 + src/core/hle/service/apt/apt_a.h | 5 ++ src/core/hle/service/apt/apt_s.cpp | 3 + src/core/hle/service/apt/apt_s.h | 5 ++ src/core/hle/service/apt/apt_u.cpp | 3 + src/core/hle/service/apt/apt_u.h | 5 ++ src/core/hle/service/apt/ns_s.cpp | 3 + src/core/hle/service/apt/ns_s.h | 5 ++ src/core/hle/service/service.h | 4 +- 25 files changed, 247 insertions(+), 17 deletions(-) create mode 100644 src/common/serialization/optional.h diff --git a/TODO b/TODO index 7309acb1a..9e591af8d 100644 --- a/TODO +++ b/TODO @@ -64,7 +64,7 @@ ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) ✔ ACT @done(19-12-24 23:17) ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) - ☐ APT + ✔ APT @done(19-12-25 21:41) ☐ BOSS ☐ CAM ☐ CECD diff --git a/src/common/serialization/optional.h b/src/common/serialization/optional.h new file mode 100644 index 000000000..5ab6af9b8 --- /dev/null +++ b/src/common/serialization/optional.h @@ -0,0 +1,91 @@ +#pragma once + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +namespace boost { +namespace serialization { + +template +void save( + Archive & ar, + const std::optional< T > & t, + const unsigned int /*version*/ +){ + // It is an inherent limitation to the serialization of optional.hpp + // that the underlying type must be either a pointer or must have a + // default constructor. It's possible that this could change sometime + // in the future, but for now, one will have to work around it. This can + // be done by serialization the optional as optional + #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + BOOST_STATIC_ASSERT( + boost::serialization::detail::is_default_constructible::value + || boost::is_pointer::value + ); + #endif + const bool tflag = t.has_value(); + ar << boost::serialization::make_nvp("initialized", tflag); + if (tflag){ + ar << boost::serialization::make_nvp("value", *t); + } +} + +template +void load( + Archive & ar, + std::optional< T > & t, + const unsigned int version +){ + bool tflag; + ar >> boost::serialization::make_nvp("initialized", tflag); + if(! tflag){ + t.reset(); + return; + } + + if(0 == version){ + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + } + if(! t.has_value()) + t = T(); + ar >> boost::serialization::make_nvp("value", *t); +} + +template +void serialize( + Archive & ar, + std::optional< T > & t, + const unsigned int version +){ + boost::serialization::split_free(ar, t, version); +} + +template +struct version > { + BOOST_STATIC_CONSTANT(int, value = 1); +}; + +} // serialization +} // boost diff --git a/src/core/global.h b/src/core/global.h index 8dfd022d8..d2e1cd97d 100644 --- a/src/core/global.h +++ b/src/core/global.h @@ -3,4 +3,9 @@ namespace Core { template T& Global(); +// Declare explicit specialisation to prevent im +class System; +template <> +System& Global(); + } // namespace Core diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 4cd305508..c76cdfa19 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -8,10 +8,11 @@ #include "core/hle/kernel/memory.h" #include "core/hle/kernel/shared_memory.h" #include "core/memory.h" +#include "core/global.h" namespace Kernel { -SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} +SharedMemory::SharedMemory() : Object(Core::Global()), kernel(Core::Global()) {} SharedMemory::~SharedMemory() { for (const auto& interval : holding_memory) { kernel.GetMemoryRegion(MemoryRegion::SYSTEM) @@ -27,7 +28,7 @@ SharedMemory::~SharedMemory() { ResultVal> KernelSystem::CreateSharedMemory( Process* owner_process, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { - auto shared_memory{std::make_shared(*this)}; + auto shared_memory{std::make_shared()}; shared_memory->owner_process = owner_process; shared_memory->name = std::move(name); @@ -72,7 +73,7 @@ ResultVal> KernelSystem::CreateSharedMemory( std::shared_ptr KernelSystem::CreateSharedMemoryForApplet( u32 offset, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) { - auto shared_memory{std::make_shared(*this)}; + auto shared_memory{std::make_shared()}; // Allocate memory in heap MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 8aaf3df1f..925f7783c 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -16,7 +16,7 @@ namespace Kernel { class SharedMemory final : public Object { public: - explicit SharedMemory(KernelSystem& kernel); + explicit SharedMemory(); ~SharedMemory() override; std::string GetTypeName() const override { diff --git a/src/core/hle/service/ac/ac_i.h b/src/core/hle/service/ac/ac_i.h index e05bac803..8e852fb9b 100644 --- a/src/core/hle/service/ac/ac_i.h +++ b/src/core/hle/service/ac/ac_i.h @@ -14,7 +14,7 @@ public: explicit AC_I(std::shared_ptr ac); private: - SERVICE_SERIALIZATION(AC_I, ac) + SERVICE_SERIALIZATION(AC_I, ac, Module) }; } // namespace Service::AC diff --git a/src/core/hle/service/ac/ac_u.h b/src/core/hle/service/ac/ac_u.h index c15870b51..117269f1f 100644 --- a/src/core/hle/service/ac/ac_u.h +++ b/src/core/hle/service/ac/ac_u.h @@ -14,7 +14,7 @@ public: explicit AC_U(std::shared_ptr ac); private: - SERVICE_SERIALIZATION(AC_U, ac) + SERVICE_SERIALIZATION(AC_U, ac, Module) }; } // namespace Service::AC diff --git a/src/core/hle/service/act/act_a.h b/src/core/hle/service/act/act_a.h index 036a96182..1e37c9bde 100644 --- a/src/core/hle/service/act/act_a.h +++ b/src/core/hle/service/act/act_a.h @@ -12,7 +12,7 @@ class ACT_A final : public Module::Interface { public: explicit ACT_A(std::shared_ptr act); private: - SERVICE_SERIALIZATION(ACT_A, act) + SERVICE_SERIALIZATION(ACT_A, act, Module) }; } // namespace Service::ACT diff --git a/src/core/hle/service/act/act_u.h b/src/core/hle/service/act/act_u.h index 14d924025..820aa862a 100644 --- a/src/core/hle/service/act/act_u.h +++ b/src/core/hle/service/act/act_u.h @@ -12,7 +12,7 @@ class ACT_U final : public Module::Interface { public: explicit ACT_U(std::shared_ptr act); private: - SERVICE_SERIALIZATION(ACT_U, act) + SERVICE_SERIALIZATION(ACT_U, act, Module) }; } // namespace Service::ACT diff --git a/src/core/hle/service/am/am_app.h b/src/core/hle/service/am/am_app.h index e78b5ef70..fae22d96f 100644 --- a/src/core/hle/service/am/am_app.h +++ b/src/core/hle/service/am/am_app.h @@ -12,7 +12,7 @@ class AM_APP final : public Module::Interface { public: explicit AM_APP(std::shared_ptr am); private: - SERVICE_SERIALIZATION(AM_APP, am) + SERVICE_SERIALIZATION(AM_APP, am, Module) }; } // namespace Service::AM diff --git a/src/core/hle/service/am/am_net.h b/src/core/hle/service/am/am_net.h index 74e335b76..4a50c6c07 100644 --- a/src/core/hle/service/am/am_net.h +++ b/src/core/hle/service/am/am_net.h @@ -12,7 +12,7 @@ class AM_NET final : public Module::Interface { public: explicit AM_NET(std::shared_ptr am); private: - SERVICE_SERIALIZATION(AM_NET, am) + SERVICE_SERIALIZATION(AM_NET, am, Module) }; } // namespace Service::AM diff --git a/src/core/hle/service/am/am_sys.h b/src/core/hle/service/am/am_sys.h index 028837f3d..c67052302 100644 --- a/src/core/hle/service/am/am_sys.h +++ b/src/core/hle/service/am/am_sys.h @@ -12,7 +12,7 @@ class AM_SYS final : public Module::Interface { public: explicit AM_SYS(std::shared_ptr am); private: - SERVICE_SERIALIZATION(AM_SYS, am) + SERVICE_SERIALIZATION(AM_SYS, am, Module) }; } // namespace Service::AM diff --git a/src/core/hle/service/am/am_u.h b/src/core/hle/service/am/am_u.h index b19d48167..c09e27c09 100644 --- a/src/core/hle/service/am/am_u.h +++ b/src/core/hle/service/am/am_u.h @@ -12,7 +12,7 @@ class AM_U final : public Module::Interface { public: explicit AM_U(std::shared_ptr am); private: - SERVICE_SERIALIZATION(AM_U, am) + SERVICE_SERIALIZATION(AM_U, am, Module) }; } // namespace Service::AM diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 6bc880bd4..9410b6b54 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -8,9 +8,12 @@ #include #include #include +#include +#include "common/serialization/optional.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" +#include "core/global.h" namespace Core { class System; @@ -84,6 +87,18 @@ struct MessageParameter { SignalType signal = SignalType::None; std::shared_ptr object = nullptr; std::vector buffer; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & sender_id; + ar & destination_id; + ar & signal; + ar & object; + ar & buffer; + } + friend class boost::serialization::access; }; /// Holds information about the parameters used in StartLibraryApplet @@ -161,6 +176,17 @@ public: u64 current_title_id; FS::MediaType current_media_type; + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & next_title_id; + ar & next_media_type; + ar & current_title_id; + ar & current_media_type; + } + friend class boost::serialization::access; }; ApplicationJumpParameters GetApplicationJumpParameters() const { @@ -199,6 +225,21 @@ private: title_id = 0; attributes.raw = 0; } + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & applet_id; + ar & slot; + ar & title_id; + ar & registered; + ar & loaded; + ar & attributes.raw; + ar & notification_event; + ar & parameter_event; + } + friend class boost::serialization::access; }; ApplicationJumpParameters app_jump_parameters{}; @@ -216,6 +257,25 @@ private: SignalType library_applet_closing_command; Core::System& system; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & next_parameter; + ar & app_jump_parameters; + ar & applet_slots; + ar & library_applet_closing_command; + } + friend class boost::serialization::access; }; } // namespace Service::APT + +namespace boost::serialization { + template + inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) + { + ::new(t)Service::APT::AppletManager(Core::Global()); + } +} diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index f7fb0660f..8e02d2bd4 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -5,6 +5,7 @@ #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" +#include "common/archives.h" #include "core/core.h" #include "core/file_sys/archive_ncch.h" #include "core/file_sys/file_backend.h" @@ -26,8 +27,35 @@ #include "core/hw/aes/ccm.h" #include "core/hw/aes/key.h" +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int) + { + ::new(t)Service::APT::Module(Core::Global()); + } + + template + void load_construct_data(iarchive& ar, Service::APT::Module* t, const unsigned int); +} + namespace Service::APT { +template +void Module::serialize(Archive& ar, const unsigned int) +{ + ar & shared_font_mem; + ar & shared_font_loaded; + ar & shared_font_relocated; + ar & lock; + ar & cpu_percent; + ar & unknown_ns_state_field; + ar & screen_capture_buffer; + ar & screen_capture_post_permission; + ar & applet_manager; +} + +SERIALIZE_IMPL(Module) + Module::NSInterface::NSInterface(std::shared_ptr apt, const char* name, u32 max_session) : ServiceFramework(name, max_session), apt(std::move(apt)) {} diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 2e2c219cd..c12dc3f55 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -6,11 +6,15 @@ #include #include +#include +#include +#include "common/archives.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" #include "core/hle/kernel/kernel.h" #include "core/hle/service/service.h" +#include "core/global.h" namespace Core { class System; @@ -65,7 +69,7 @@ public: NSInterface(std::shared_ptr apt, const char* name, u32 max_session); ~NSInterface(); - private: + protected: std::shared_ptr apt; }; @@ -601,7 +605,7 @@ public: */ void CheckNew3DS(Kernel::HLERequestContext& ctx); - private: + protected: bool application_reset_prepared{}; std::shared_ptr apt; }; @@ -630,8 +634,17 @@ private: ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value std::shared_ptr applet_manager; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::APT + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); +} diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 7d5c96139..db49c57d8 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/apt/apt_a.h" +#include "common/archives.h" namespace Service::APT { @@ -105,3 +106,5 @@ APT_A::APT_A(std::shared_ptr apt) } } // namespace Service::APT + +SERIALIZE_EXPORT_IMPL(Service::APT::APT_A) diff --git a/src/core/hle/service/apt/apt_a.h b/src/core/hle/service/apt/apt_a.h index f481fa1c9..1b81022df 100644 --- a/src/core/hle/service/apt/apt_a.h +++ b/src/core/hle/service/apt/apt_a.h @@ -11,6 +11,11 @@ namespace Service::APT { class APT_A final : public Module::APTInterface { public: explicit APT_A(std::shared_ptr apt); +private: + SERVICE_SERIALIZATION(APT_A, apt, Module) }; } // namespace Service::APT + +BOOST_CLASS_EXPORT_KEY(Service::APT::APT_A) +BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_A) diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index 1843bdd9a..4d151fb3d 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/apt/apt_s.h" +#include "common/archives.h" namespace Service::APT { @@ -105,3 +106,5 @@ APT_S::APT_S(std::shared_ptr apt) } } // namespace Service::APT + +SERIALIZE_EXPORT_IMPL(Service::APT::APT_S) diff --git a/src/core/hle/service/apt/apt_s.h b/src/core/hle/service/apt/apt_s.h index 7e041cbda..ef1c235b0 100644 --- a/src/core/hle/service/apt/apt_s.h +++ b/src/core/hle/service/apt/apt_s.h @@ -18,6 +18,11 @@ namespace Service::APT { class APT_S final : public Module::APTInterface { public: explicit APT_S(std::shared_ptr apt); +private: + SERVICE_SERIALIZATION(APT_S, apt, Module) }; } // namespace Service::APT + +BOOST_CLASS_EXPORT_KEY(Service::APT::APT_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_S) diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 0ecbd65da..7ebaf86e3 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/apt/apt_u.h" +#include "common/archives.h" namespace Service::APT { @@ -102,3 +103,5 @@ APT_U::APT_U(std::shared_ptr apt) } } // namespace Service::APT + +SERIALIZE_EXPORT_IMPL(Service::APT::APT_U) diff --git a/src/core/hle/service/apt/apt_u.h b/src/core/hle/service/apt/apt_u.h index 3b342ed55..79d2df651 100644 --- a/src/core/hle/service/apt/apt_u.h +++ b/src/core/hle/service/apt/apt_u.h @@ -18,6 +18,11 @@ namespace Service::APT { class APT_U final : public Module::APTInterface { public: explicit APT_U(std::shared_ptr apt); +private: + SERVICE_SERIALIZATION(APT_U, apt, Module) }; } // namespace Service::APT + +BOOST_CLASS_EXPORT_KEY(Service::APT::APT_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_U) diff --git a/src/core/hle/service/apt/ns_s.cpp b/src/core/hle/service/apt/ns_s.cpp index e9eb87174..b556845d3 100644 --- a/src/core/hle/service/apt/ns_s.cpp +++ b/src/core/hle/service/apt/ns_s.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/apt/ns_s.h" +#include "common/archives.h" namespace Service::NS { @@ -29,3 +30,5 @@ NS_S::NS_S(std::shared_ptr apt) } } // namespace Service::NS + +SERIALIZE_EXPORT_IMPL(Service::NS::NS_S) diff --git a/src/core/hle/service/apt/ns_s.h b/src/core/hle/service/apt/ns_s.h index 5a5b311b0..8f023e204 100644 --- a/src/core/hle/service/apt/ns_s.h +++ b/src/core/hle/service/apt/ns_s.h @@ -14,6 +14,11 @@ namespace Service::NS { class NS_S final : public Service::APT::Module::NSInterface { public: explicit NS_S(std::shared_ptr apt); +private: + SERVICE_SERIALIZATION(NS_S, apt, Service::APT::Module) }; } // namespace Service::NS + +BOOST_CLASS_EXPORT_KEY(Service::NS::NS_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::NS::NS_S) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index bdad47ea8..c0c48892a 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -199,7 +199,7 @@ extern const std::array service_module_map; } // namespace Service -#define SERVICE_SERIALIZATION(T, MFIELD) \ +#define SERVICE_SERIALIZATION(T, MFIELD, TMODULE) \ template \ void save_construct(Archive& ar, const unsigned int file_version) const \ { \ @@ -209,7 +209,7 @@ extern const std::array service_module_map; template \ static void load_construct(Archive& ar, T* t, const unsigned int file_version) \ { \ - std::shared_ptr MFIELD; \ + std::shared_ptr MFIELD; \ ar >> MFIELD; \ ::new(t)T(MFIELD); \ } \ From 1185d627924b9bd5dd13461e7581850a777e9d22 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 25 Dec 2019 23:19:01 +0000 Subject: [PATCH 023/129] BOSS service serialization --- TODO | 2 +- src/core/hle/service/apt/apt.h | 8 ++++++++ src/core/hle/service/boss/boss.h | 30 +++++++++++++++++++++++++++- src/core/hle/service/boss/boss_p.cpp | 3 +++ src/core/hle/service/boss/boss_p.h | 6 ++++++ src/core/hle/service/boss/boss_u.cpp | 3 +++ src/core/hle/service/boss/boss_u.h | 6 ++++++ 7 files changed, 56 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 9e591af8d..c6e3366e3 100644 --- a/TODO +++ b/TODO @@ -65,7 +65,7 @@ ✔ ACT @done(19-12-24 23:17) ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) ✔ APT @done(19-12-25 21:41) - ☐ BOSS + ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) ☐ CAM ☐ CECD ☐ CGF diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index c12dc3f55..45a93b350 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -608,6 +608,14 @@ public: protected: bool application_reset_prepared{}; std::shared_ptr apt; + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & application_reset_prepared; + } + friend class boost::serialization::access; }; private: diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index e0cb39b37..7017ce2b6 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -5,8 +5,10 @@ #pragma once #include +#include #include "core/hle/kernel/event.h" #include "core/hle/service/service.h" +#include "core/global.h" namespace Core { class System; @@ -952,19 +954,45 @@ public: */ void GetNsDataNewFlagPrivileged(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr boss; + private: u8 new_arrival_flag; u8 ns_data_new_flag; u8 ns_data_new_flag_privileged; u8 output_flag; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & new_arrival_flag; + ar & ns_data_new_flag; + ar & ns_data_new_flag_privileged; + ar & output_flag; + } + friend class boost::serialization::access; }; private: std::shared_ptr task_finish_event; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & task_finish_event; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::BOSS + +namespace boost::serialization { + template + inline void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) + { + ::new(t)Service::BOSS::Module(Core::Global()); + } +} diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp index cdc8f1036..4e48fe8f3 100644 --- a/src/core/hle/service/boss/boss_p.cpp +++ b/src/core/hle/service/boss/boss_p.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/boss/boss_p.h" +#include "common/archives.h" namespace Service::BOSS { @@ -84,3 +85,5 @@ BOSS_P::BOSS_P(std::shared_ptr boss) } } // namespace Service::BOSS + +SERIALIZE_EXPORT_IMPL(Service::BOSS::BOSS_P) diff --git a/src/core/hle/service/boss/boss_p.h b/src/core/hle/service/boss/boss_p.h index 9c84a1e9d..56f0cd4fc 100644 --- a/src/core/hle/service/boss/boss_p.h +++ b/src/core/hle/service/boss/boss_p.h @@ -11,6 +11,12 @@ namespace Service::BOSS { class BOSS_P final : public Module::Interface { public: explicit BOSS_P(std::shared_ptr boss); + +private: + SERVICE_SERIALIZATION(BOSS_P, boss, Module) }; } // namespace Service::BOSS + +BOOST_CLASS_EXPORT_KEY(Service::BOSS::BOSS_P) +BOOST_SERIALIZATION_CONSTRUCT(Service::BOSS::BOSS_P) diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp index c6aaba888..f839e9292 100644 --- a/src/core/hle/service/boss/boss_u.cpp +++ b/src/core/hle/service/boss/boss_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/boss/boss_u.h" +#include "common/archives.h" namespace Service::BOSS { @@ -72,3 +73,5 @@ BOSS_U::BOSS_U(std::shared_ptr boss) } } // namespace Service::BOSS + +SERIALIZE_EXPORT_IMPL(Service::BOSS::BOSS_U) diff --git a/src/core/hle/service/boss/boss_u.h b/src/core/hle/service/boss/boss_u.h index a93b4e502..195783b40 100644 --- a/src/core/hle/service/boss/boss_u.h +++ b/src/core/hle/service/boss/boss_u.h @@ -11,6 +11,12 @@ namespace Service::BOSS { class BOSS_U final : public Module::Interface { public: explicit BOSS_U(std::shared_ptr boss); + +private: + SERVICE_SERIALIZATION(BOSS_U, boss, Module) }; } // namespace Service::BOSS + +BOOST_CLASS_EXPORT_KEY(Service::BOSS::BOSS_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::BOSS::BOSS_U) From 17b9cbefef78aa006075d69855c328e569af280d Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 10:37:43 +0000 Subject: [PATCH 024/129] CAM service serialization --- TODO | 3 +- src/core/hle/service/cam/cam.cpp | 11 +++++ src/core/hle/service/cam/cam.h | 79 +++++++++++++++++++++++++++++- src/core/hle/service/cam/cam_c.cpp | 3 ++ src/core/hle/service/cam/cam_c.h | 6 +++ src/core/hle/service/cam/cam_q.cpp | 3 ++ src/core/hle/service/cam/cam_q.h | 9 ++++ src/core/hle/service/cam/cam_s.cpp | 3 ++ src/core/hle/service/cam/cam_s.h | 6 +++ src/core/hle/service/cam/cam_u.cpp | 3 ++ src/core/hle/service/cam/cam_u.h | 6 +++ 11 files changed, 129 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index c6e3366e3..354e61a2f 100644 --- a/TODO +++ b/TODO @@ -66,7 +66,8 @@ ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) ✔ APT @done(19-12-25 21:41) ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) - ☐ CAM + ☐ CAM @started(19-12-26 10:37) + Need to check capture_result ☐ CECD ☐ CGF ☐ CSND diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index bf1bab8c0..b7acd307c 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/bit_set.h" #include "common/logging/log.h" #include "core/core.h" @@ -22,6 +23,16 @@ namespace Service::CAM { +template +void Module::serialize(Archive& ar, const unsigned int) +{ + ar & cameras; + ar & ports; + ar & is_camera_reload_pending; +} + +SERIALIZE_IMPL(Module) + // built-in resolution parameters constexpr std::array PRESET_RESOLUTION{{ {640, 480, 0, 0, 639, 479}, // VGA diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 9f3d81990..229c882b5 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -12,6 +12,7 @@ #include "common/swap.h" #include "core/hle/result.h" #include "core/hle/service/service.h" +#include "core/global.h" namespace Core { class System; @@ -179,6 +180,19 @@ struct Resolution { u16 crop_y0; u16 crop_x1; u16 crop_y1; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & width; + ar & height; + ar & crop_x0; + ar & crop_y0; + ar & crop_x1; + ar & crop_y1; + } + friend class boost::serialization::access; }; struct PackageParameterWithoutContext { @@ -710,7 +724,7 @@ public: */ void DriverFinalize(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr cam; }; @@ -738,6 +752,17 @@ private: Effect effect{Effect::None}; OutputFormat format{OutputFormat::YUV422}; Resolution resolution = {0, 0, 0, 0, 0, 0}; + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & flip; + ar & effect; + ar & format; + ar & resolution; + } + friend class boost::serialization::access; }; struct CameraConfig { @@ -745,6 +770,17 @@ private: std::array contexts; int current_context{0}; FrameRate frame_rate{FrameRate::Rate_5}; + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & impl; + ar & contexts; + ar & current_context; + ar & frame_rate; + } + friend class boost::serialization::access; }; struct PortConfig { @@ -779,6 +815,32 @@ private: u32 dest_size{0}; // the destination size of the receiving process void Clear(); + + private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & camera_id; + ar & is_active; + ar & is_pending_receiving; + ar & is_busy; + ar & is_receiving; + ar & is_trimming; + ar & x0; + ar & y0; + ar & x1; + ar & y1; + ar & transfer_bytes; + ar & completion_event; + ar & buffer_error_interrupt_event; + ar & vsync_interrupt_event; + // TODO: Check if this is ever needed: + //ar & capture_result; + ar & dest_process; + ar & dest; + ar & dest_size; + } + friend class boost::serialization::access; }; void LoadCameraImplementation(CameraConfig& camera, int camera_id); @@ -786,8 +848,13 @@ private: Core::System& system; std::array cameras; std::array ports; - Core::TimingEventType* completion_event_callback; + // TODO: Make this *const + const Core::TimingEventType* completion_event_callback; std::atomic is_camera_reload_pending{false}; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; std::shared_ptr GetModule(Core::System& system); @@ -795,3 +862,11 @@ std::shared_ptr GetModule(Core::System& system); void InstallInterfaces(Core::System& system); } // namespace Service::CAM + +namespace boost::serialization { + template + inline void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) + { + ::new(t)Service::CAM::Module(Core::Global()); + } +} diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp index 80816c923..a29e9db3e 100644 --- a/src/core/hle/service/cam/cam_c.cpp +++ b/src/core/hle/service/cam/cam_c.cpp @@ -4,6 +4,7 @@ #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_c.h" +#include "common/archives.h" namespace Service::CAM { @@ -79,3 +80,5 @@ CAM_C::CAM_C(std::shared_ptr cam) : Module::Interface(std::move(cam), "c } } // namespace Service::CAM + +SERIALIZE_EXPORT_IMPL(Service::CAM::CAM_C) diff --git a/src/core/hle/service/cam/cam_c.h b/src/core/hle/service/cam/cam_c.h index d6dfcd6c5..c1ed355ac 100644 --- a/src/core/hle/service/cam/cam_c.h +++ b/src/core/hle/service/cam/cam_c.h @@ -11,6 +11,12 @@ namespace Service::CAM { class CAM_C final : public Module::Interface { public: explicit CAM_C(std::shared_ptr cam); + +private: + SERVICE_SERIALIZATION(CAM_C, cam, Module) }; } // namespace Service::CAM + +BOOST_CLASS_EXPORT_KEY(Service::CAM::CAM_C) +BOOST_SERIALIZATION_CONSTRUCT(Service::CAM::CAM_C) diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp index 71fc127d2..ac477bf04 100644 --- a/src/core/hle/service/cam/cam_q.cpp +++ b/src/core/hle/service/cam/cam_q.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "core/hle/service/cam/cam_q.h" +#include "common/archives.h" namespace Service::CAM { @@ -13,3 +14,5 @@ CAM_Q::CAM_Q() : ServiceFramework("cam:q", 1 /*TODO: find the true value*/) { } } // namespace Service::CAM + +SERIALIZE_EXPORT_IMPL(Service::CAM::CAM_Q) diff --git a/src/core/hle/service/cam/cam_q.h b/src/core/hle/service/cam/cam_q.h index d1124493b..33943ca21 100644 --- a/src/core/hle/service/cam/cam_q.h +++ b/src/core/hle/service/cam/cam_q.h @@ -11,6 +11,15 @@ namespace Service::CAM { class CAM_Q : public ServiceFramework { public: CAM_Q(); +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::CAM + +BOOST_CLASS_EXPORT_KEY(Service::CAM::CAM_Q) diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp index c4936f9b5..0797ed4e1 100644 --- a/src/core/hle/service/cam/cam_s.cpp +++ b/src/core/hle/service/cam/cam_s.cpp @@ -4,6 +4,7 @@ #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_s.h" +#include "common/archives.h" namespace Service::CAM { @@ -79,3 +80,5 @@ CAM_S::CAM_S(std::shared_ptr cam) : Module::Interface(std::move(cam), "c } } // namespace Service::CAM + +SERIALIZE_EXPORT_IMPL(Service::CAM::CAM_S) diff --git a/src/core/hle/service/cam/cam_s.h b/src/core/hle/service/cam/cam_s.h index 0c9d26644..cceb99b87 100644 --- a/src/core/hle/service/cam/cam_s.h +++ b/src/core/hle/service/cam/cam_s.h @@ -11,6 +11,12 @@ namespace Service::CAM { class CAM_S final : public Module::Interface { public: explicit CAM_S(std::shared_ptr cam); + +private: + SERVICE_SERIALIZATION(CAM_S, cam, Module) }; } // namespace Service::CAM + +BOOST_CLASS_EXPORT_KEY(Service::CAM::CAM_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::CAM::CAM_S) diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp index 3c3c4b17d..16c652a26 100644 --- a/src/core/hle/service/cam/cam_u.cpp +++ b/src/core/hle/service/cam/cam_u.cpp @@ -4,6 +4,7 @@ #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_u.h" +#include "common/archives.h" namespace Service::CAM { @@ -79,3 +80,5 @@ CAM_U::CAM_U(std::shared_ptr cam) : Module::Interface(std::move(cam), "c } } // namespace Service::CAM + +SERIALIZE_EXPORT_IMPL(Service::CAM::CAM_U) diff --git a/src/core/hle/service/cam/cam_u.h b/src/core/hle/service/cam/cam_u.h index 85b12559a..2b775a035 100644 --- a/src/core/hle/service/cam/cam_u.h +++ b/src/core/hle/service/cam/cam_u.h @@ -11,6 +11,12 @@ namespace Service::CAM { class CAM_U final : public Module::Interface { public: explicit CAM_U(std::shared_ptr cam); + +private: + SERVICE_SERIALIZATION(CAM_U, cam, Module) }; } // namespace Service::CAM + +BOOST_CLASS_EXPORT_KEY(Service::CAM::CAM_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::CAM::CAM_U) From a0c3b9178525df5d192048d266e3e1d0f8c1e3ef Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 17:56:44 +0000 Subject: [PATCH 025/129] Added CSND serialization --- TODO | 7 +++- src/core/hle/service/csnd/csnd_snd.cpp | 14 +++++++ src/core/hle/service/csnd/csnd_snd.h | 56 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 354e61a2f..e485f33a7 100644 --- a/TODO +++ b/TODO @@ -15,6 +15,7 @@ ☐ Settings ☐ Telemetry session ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE +☐ Review constructor/initialization code ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) @@ -69,8 +70,10 @@ ☐ CAM @started(19-12-26 10:37) Need to check capture_result ☐ CECD - ☐ CGF - ☐ CSND + ☐ Archive backend / file handles + ☐ CFG + Also needs archive backend.. + ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) ☐ DLP ☐ DSP ☐ ERR diff --git a/src/core/hle/service/csnd/csnd_snd.cpp b/src/core/hle/service/csnd/csnd_snd.cpp index 5c9fa13e9..d011a1c66 100644 --- a/src/core/hle/service/csnd/csnd_snd.cpp +++ b/src/core/hle/service/csnd/csnd_snd.cpp @@ -3,11 +3,25 @@ // Refer to the license.txt file included. #include "common/alignment.h" +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/csnd/csnd_snd.h" +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int) + { + ::new(t)Service::CSND::CSND_SND(Core::Global()); + } + + template + void load_construct_data(iarchive& ar, Service::CSND::CSND_SND* t, const unsigned int); +} + +SERIALIZE_EXPORT_IMPL(Service::CSND::CSND_SND) + namespace Service::CSND { enum class CommandId : u16 { diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index afdc3b1a8..0e2dd8cd8 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -5,6 +5,8 @@ #pragma once #include +#include +#include #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/service.h" @@ -33,6 +35,15 @@ enum class LoopMode : u8 { struct AdpcmState { s16 predictor = 0; u8 step_index = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & predictor; + ar & step_index; + } + friend class boost::serialization::access; }; struct Channel { @@ -52,6 +63,29 @@ struct Channel { LoopMode loop_mode = LoopMode::Manual; Encoding encoding = Encoding::Pcm8; u8 psg_duty = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & block1_address; + ar & block2_address; + ar & block1_size; + ar & block2_size; + ar & block1_adpcm_state; + ar & block2_adpcm_state; + ar & block2_adpcm_reload; + ar & left_channel_volume; + ar & right_channel_volume; + ar & left_capture_volume; + ar & right_capture_volume; + ar & sample_rate; + ar & linear_interpolation; + ar & loop_mode; + ar & encoding; + ar & psg_duty; + } + friend class boost::serialization::access; }; class CSND_SND final : public ServiceFramework { @@ -222,9 +256,31 @@ private: u32 type1_command_offset = 0; u32 acquired_channel_mask = 0; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & mutex; + ar & shared_memory; + ar & capture_units; + ar & channels; + ar & master_state_offset; + ar & channel_state_offset; + ar & capture_state_offset; + ar & type1_command_offset; + ar & acquired_channel_mask; + } + friend class boost::serialization::access; }; /// Initializes the CSND_SND Service void InstallInterfaces(Core::System& system); } // namespace Service::CSND + +BOOST_CLASS_EXPORT_KEY(Service::CSND::CSND_SND) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int); +} From 30fe2bfe38fb251989acb50df561ba512d9f27b6 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 18:02:59 +0000 Subject: [PATCH 026/129] Added DLP service serialization --- TODO | 2 +- src/core/hle/service/dlp/dlp_clnt.cpp | 3 +++ src/core/hle/service/dlp/dlp_clnt.h | 9 +++++++++ src/core/hle/service/dlp/dlp_fkcl.cpp | 3 +++ src/core/hle/service/dlp/dlp_fkcl.h | 9 +++++++++ src/core/hle/service/dlp/dlp_srvr.cpp | 3 +++ src/core/hle/service/dlp/dlp_srvr.h | 9 +++++++++ 7 files changed, 37 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index e485f33a7..27f720dca 100644 --- a/TODO +++ b/TODO @@ -74,7 +74,7 @@ ☐ CFG Also needs archive backend.. ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) - ☐ DLP + ✔ DLP @done(19-12-26 18:02) ☐ DSP ☐ ERR ☐ FRD diff --git a/src/core/hle/service/dlp/dlp_clnt.cpp b/src/core/hle/service/dlp/dlp_clnt.cpp index 63308f57e..df5b755e1 100644 --- a/src/core/hle/service/dlp/dlp_clnt.cpp +++ b/src/core/hle/service/dlp/dlp_clnt.cpp @@ -4,6 +4,9 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/service/dlp/dlp_clnt.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_CLNT) namespace Service::DLP { diff --git a/src/core/hle/service/dlp/dlp_clnt.h b/src/core/hle/service/dlp/dlp_clnt.h index db506b985..3f9020863 100644 --- a/src/core/hle/service/dlp/dlp_clnt.h +++ b/src/core/hle/service/dlp/dlp_clnt.h @@ -12,6 +12,15 @@ class DLP_CLNT final : public ServiceFramework { public: DLP_CLNT(); ~DLP_CLNT() = default; +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::DLP + +BOOST_CLASS_EXPORT_KEY(Service::DLP::DLP_CLNT) diff --git a/src/core/hle/service/dlp/dlp_fkcl.cpp b/src/core/hle/service/dlp/dlp_fkcl.cpp index 30a98c4bf..607c211d4 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.cpp +++ b/src/core/hle/service/dlp/dlp_fkcl.cpp @@ -4,6 +4,9 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/service/dlp/dlp_fkcl.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_FKCL) namespace Service::DLP { diff --git a/src/core/hle/service/dlp/dlp_fkcl.h b/src/core/hle/service/dlp/dlp_fkcl.h index a3b2ac86d..ae26b6220 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.h +++ b/src/core/hle/service/dlp/dlp_fkcl.h @@ -12,6 +12,15 @@ class DLP_FKCL final : public ServiceFramework { public: DLP_FKCL(); ~DLP_FKCL() = default; +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::DLP + +BOOST_CLASS_EXPORT_KEY(Service::DLP::DLP_FKCL) diff --git a/src/core/hle/service/dlp/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp index 9d7405941..0cff2e2bc 100644 --- a/src/core/hle/service/dlp/dlp_srvr.cpp +++ b/src/core/hle/service/dlp/dlp_srvr.cpp @@ -7,6 +7,9 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/dlp/dlp_srvr.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_SRVR) namespace Service::DLP { diff --git a/src/core/hle/service/dlp/dlp_srvr.h b/src/core/hle/service/dlp/dlp_srvr.h index 50d8d92b2..6af350c8e 100644 --- a/src/core/hle/service/dlp/dlp_srvr.h +++ b/src/core/hle/service/dlp/dlp_srvr.h @@ -15,6 +15,15 @@ public: private: void IsChild(Kernel::HLERequestContext& ctx); + + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::DLP + +BOOST_CLASS_EXPORT_KEY(Service::DLP::DLP_SRVR) From 452ae2e3714ba6f8de7902c8b6046e22a8f2f957 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 18:10:38 +0000 Subject: [PATCH 027/129] Added DSP service serialization --- TODO | 2 +- src/core/hle/service/dsp/dsp_dsp.cpp | 14 ++++++++++++++ src/core/hle/service/dsp/dsp_dsp.h | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 27f720dca..c3e8a57d7 100644 --- a/TODO +++ b/TODO @@ -75,7 +75,7 @@ Also needs archive backend.. ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) ✔ DLP @done(19-12-26 18:02) - ☐ DSP + ✔ DSP @done(19-12-26 18:10) ☐ ERR ☐ FRD ☐ FS diff --git a/src/core/hle/service/dsp/dsp_dsp.cpp b/src/core/hle/service/dsp/dsp_dsp.cpp index 37682edcc..519d39b0c 100644 --- a/src/core/hle/service/dsp/dsp_dsp.cpp +++ b/src/core/hle/service/dsp/dsp_dsp.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "audio_core/audio_types.h" +#include "common/archives.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" @@ -13,6 +14,19 @@ using DspPipe = AudioCore::DspPipe; using InterruptType = Service::DSP::DSP_DSP::InterruptType; +SERIALIZE_EXPORT_IMPL(Service::DSP::DSP_DSP) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int) + { + ::new(t)Service::DSP::DSP_DSP(Core::Global()); + } + + template + void load_construct_data(iarchive& ar, Service::DSP::DSP_DSP* t, const unsigned int); +} + namespace AudioCore { enum class DspPipe; } diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h index ef1f0b76d..b4c727091 100644 --- a/src/core/hle/service/dsp/dsp_dsp.h +++ b/src/core/hle/service/dsp/dsp_dsp.h @@ -264,8 +264,27 @@ private: /// Each DSP pipe has an associated interrupt std::array, AudioCore::num_dsp_pipe> pipes = {{}}; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + ar & semaphore_event; + ar & preset_semaphore; + ar & interrupt_zero; + ar & interrupt_one; + ar & pipes; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::DSP + +BOOST_CLASS_EXPORT_KEY(Service::DSP::DSP_DSP) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int); +} From 4354179156e38bac0819ba6c10c1a2245ba879d7 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 18:14:22 +0000 Subject: [PATCH 028/129] Added ERR service serialization --- TODO | 2 +- src/core/hle/service/err_f.cpp | 14 ++++++++++++++ src/core/hle/service/err_f.h | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index c3e8a57d7..4a07c0608 100644 --- a/TODO +++ b/TODO @@ -76,7 +76,7 @@ ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) ✔ DLP @done(19-12-26 18:02) ✔ DSP @done(19-12-26 18:10) - ☐ ERR + ✔ ERR @done(19-12-26 18:14) ☐ FRD ☐ FS ☐ GSP diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index b218eb793..0efc600e8 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "common/archives.h" #include "common/bit_field.h" #include "common/common_types.h" #include "common/logging/log.h" @@ -16,6 +17,19 @@ #include "core/hle/service/err_f.h" #undef exception_info +SERIALIZE_EXPORT_IMPL(Service::ERR::ERR_F) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int) + { + ::new(t)Service::ERR::ERR_F(Core::Global()); + } + + template + void load_construct_data(iarchive& ar, Service::ERR::ERR_F* t, const unsigned int); +} + namespace Service::ERR { enum class FatalErrType : u32 { diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h index 4a1684caf..a3d0cf11e 100644 --- a/src/core/hle/service/err_f.h +++ b/src/core/hle/service/err_f.h @@ -34,8 +34,22 @@ private: void ThrowFatalError(Kernel::HLERequestContext& ctx); Core::System& system; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::ERR + +BOOST_CLASS_EXPORT_KEY(Service::ERR::ERR_F) + +namespace boost::serialization { + template + void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int); +} From d1096de24525aa00b1cbdd490e4b4b76b6c8d915 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 26 Dec 2019 19:09:55 +0000 Subject: [PATCH 029/129] Added FRD service serialization --- TODO | 2 +- src/core/hle/service/frd/frd.h | 28 +++++++++++++++++++++++++++- src/core/hle/service/frd/frd_a.cpp | 3 +++ src/core/hle/service/frd/frd_a.h | 5 +++++ src/core/hle/service/frd/frd_u.cpp | 3 +++ src/core/hle/service/frd/frd_u.h | 5 +++++ 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 4a07c0608..5a483dc84 100644 --- a/TODO +++ b/TODO @@ -77,7 +77,7 @@ ✔ DLP @done(19-12-26 18:02) ✔ DSP @done(19-12-26 18:10) ✔ ERR @done(19-12-26 18:14) - ☐ FRD + ✔ FRD @done(19-12-26 19:09) ☐ FS ☐ GSP ☐ HID diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h index 200b51ebe..46dc96cad 100644 --- a/src/core/hle/service/frd/frd.h +++ b/src/core/hle/service/frd/frd.h @@ -18,10 +18,28 @@ struct FriendKey { u32 friend_id; u32 unknown; u64 friend_code; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & friend_id; + ar & unknown; + ar & friend_code; + } + friend class boost::serialization::access; }; struct MyPresence { u8 unknown[0x12C]; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & unknown; + } + friend class boost::serialization::access; }; struct Profile { @@ -130,13 +148,21 @@ public: */ void SetClientSdkVersion(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr frd; }; private: FriendKey my_friend_key = {0, 0, 0ull}; MyPresence my_presence = {}; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & my_friend_key; + ar & my_presence; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp index c68689cc0..6248891af 100644 --- a/src/core/hle/service/frd/frd_a.cpp +++ b/src/core/hle/service/frd/frd_a.cpp @@ -3,6 +3,9 @@ // Refer to the license.txt file included. #include "core/hle/service/frd/frd_a.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::FRD::FRD_A) namespace Service::FRD { diff --git a/src/core/hle/service/frd/frd_a.h b/src/core/hle/service/frd/frd_a.h index 97657a072..133d40dc1 100644 --- a/src/core/hle/service/frd/frd_a.h +++ b/src/core/hle/service/frd/frd_a.h @@ -11,6 +11,11 @@ namespace Service::FRD { class FRD_A final : public Module::Interface { public: explicit FRD_A(std::shared_ptr frd); +private: + SERVICE_SERIALIZATION(FRD_A, frd, Module) }; } // namespace Service::FRD + +BOOST_CLASS_EXPORT_KEY(Service::FRD::FRD_A) +BOOST_SERIALIZATION_CONSTRUCT(Service::FRD::FRD_A) diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp index 2cbc64243..ba499dd2b 100644 --- a/src/core/hle/service/frd/frd_u.cpp +++ b/src/core/hle/service/frd/frd_u.cpp @@ -3,6 +3,9 @@ // Refer to the license.txt file included. #include "core/hle/service/frd/frd_u.h" +#include "common/archives.h" + +SERIALIZE_EXPORT_IMPL(Service::FRD::FRD_U) namespace Service::FRD { diff --git a/src/core/hle/service/frd/frd_u.h b/src/core/hle/service/frd/frd_u.h index 5704d5e11..281334f51 100644 --- a/src/core/hle/service/frd/frd_u.h +++ b/src/core/hle/service/frd/frd_u.h @@ -11,6 +11,11 @@ namespace Service::FRD { class FRD_U final : public Module::Interface { public: explicit FRD_U(std::shared_ptr frd); +private: + SERVICE_SERIALIZATION(FRD_U, frd, Module) }; } // namespace Service::FRD + +BOOST_CLASS_EXPORT_KEY(Service::FRD::FRD_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::FRD::FRD_U) From 3ed8d95866eeebc8edfe3d886b4e24f84148563d Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 11:46:10 +0000 Subject: [PATCH 030/129] Serialize FS service; some compiler fixes --- src/core/hle/kernel/hle_ipc.h | 3 ++- src/core/hle/service/apt/apt.cpp | 11 +---------- src/core/hle/service/csnd/csnd_snd.cpp | 12 +----------- src/core/hle/service/csnd/csnd_snd.h | 1 + src/core/hle/service/dsp/dsp_dsp.cpp | 12 +----------- src/core/hle/service/fs/fs_user.cpp | 5 +++++ src/core/hle/service/fs/fs_user.h | 20 ++++++++++++++++++++ src/core/hle/service/service.h | 19 ++++++++++++++++++- src/tests/core/hle/kernel/hle_ipc.cpp | 3 +++ src/video_core/pica_state.h | 21 ++++++++++----------- 10 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index da89ad39a..162a2eb39 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -22,7 +22,6 @@ #include "core/hle/kernel/server_session.h" BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler) -BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler::SessionDataBase) namespace Service { class ServiceFrameworkBase; @@ -282,3 +281,5 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::SessionRequestHandler::SessionDataBase) diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 8e02d2bd4..d5a7fb001 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -27,16 +27,7 @@ #include "core/hw/aes/ccm.h" #include "core/hw/aes/key.h" -namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int) - { - ::new(t)Service::APT::Module(Core::Global()); - } - - template - void load_construct_data(iarchive& ar, Service::APT::Module* t, const unsigned int); -} +SERVICE_CONSTRUCT_IMPL(Service::APT::Module) namespace Service::APT { diff --git a/src/core/hle/service/csnd/csnd_snd.cpp b/src/core/hle/service/csnd/csnd_snd.cpp index d011a1c66..1a7a00964 100644 --- a/src/core/hle/service/csnd/csnd_snd.cpp +++ b/src/core/hle/service/csnd/csnd_snd.cpp @@ -9,17 +9,7 @@ #include "core/hle/result.h" #include "core/hle/service/csnd/csnd_snd.h" -namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int) - { - ::new(t)Service::CSND::CSND_SND(Core::Global()); - } - - template - void load_construct_data(iarchive& ar, Service::CSND::CSND_SND* t, const unsigned int); -} - +SERVICE_CONSTRUCT_IMPL(Service::CSND::CSND_SND) SERIALIZE_EXPORT_IMPL(Service::CSND::CSND_SND) namespace Service::CSND { diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index 0e2dd8cd8..44e4c030c 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -260,6 +260,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar & boost::serialization::base_object(*this); ar & mutex; ar & shared_memory; ar & capture_units; diff --git a/src/core/hle/service/dsp/dsp_dsp.cpp b/src/core/hle/service/dsp/dsp_dsp.cpp index 519d39b0c..9b0ef8986 100644 --- a/src/core/hle/service/dsp/dsp_dsp.cpp +++ b/src/core/hle/service/dsp/dsp_dsp.cpp @@ -15,17 +15,7 @@ using DspPipe = AudioCore::DspPipe; using InterruptType = Service::DSP::DSP_DSP::InterruptType; SERIALIZE_EXPORT_IMPL(Service::DSP::DSP_DSP) - -namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int) - { - ::new(t)Service::DSP::DSP_DSP(Core::Global()); - } - - template - void load_construct_data(iarchive& ar, Service::DSP::DSP_DSP* t, const unsigned int); -} +SERVICE_CONSTRUCT_IMPL(Service::DSP::DSP_DSP) namespace AudioCore { enum class DspPipe; diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index bca8e77e5..e027e837f 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" #include "common/file_util.h" @@ -25,6 +26,10 @@ #include "core/hle/service/fs/fs_user.h" #include "core/settings.h" +SERVICE_CONSTRUCT_IMPL(Service::FS::FS_USER) +SERIALIZE_EXPORT_IMPL(Service::FS::FS_USER) +SERIALIZE_EXPORT_IMPL(Service::FS::ClientSlot) + //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace FS_User diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 97b45714b..c001be0c5 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -22,6 +22,14 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { // behaviour is modified. Since we don't emulate fs:REG mechanism, we assume the program ID is // the same as codeset ID and fetch from there directly. u64 program_id = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) + { + ar & program_id; + } + friend class boost::serialization::access; }; class FS_USER final : public ServiceFramework { @@ -545,8 +553,20 @@ private: Core::System& system; ArchiveManager& archives; + + template + void serialize(Archive& ar, const unsigned int) + { + ar & boost::serialization::base_object(*this); + ar & priority; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::FS + +SERVICE_CONSTRUCT(Service::FS::FS_USER) +BOOST_CLASS_EXPORT_KEY(Service::FS::FS_USER) +BOOST_CLASS_EXPORT_KEY(Service::FS::ClientSlot) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index c0c48892a..4961678df 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -220,4 +220,21 @@ extern const std::array service_module_map; ar & boost::serialization::base_object(*this); \ } \ friend class boost::serialization::access; \ - friend class construct_access; + friend class ::construct_access; + +#define SERVICE_CONSTRUCT(T) \ +namespace boost::serialization { \ + template \ + void load_construct_data(Archive& ar, T* t, const unsigned int); \ +} + +#define SERVICE_CONSTRUCT_IMPL(T) \ +namespace boost::serialization { \ + template \ + void load_construct_data(Archive& ar, T* t, const unsigned int) \ + { \ + ::new(t)T(Core::Global()); \ + } \ + template \ + void load_construct_data(iarchive& ar, T* t, const unsigned int); \ +} \ No newline at end of file diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index fb549f829..e405f6729 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/ipc.h" @@ -14,6 +15,8 @@ #include "core/hle/kernel/process.h" #include "core/hle/kernel/server_session.h" +SERIALIZE_EXPORT_IMPL(Kernel::SessionRequestHandler::SessionDataBase) + namespace Kernel { static std::shared_ptr MakeObject(Kernel::KernelSystem& kernel) { diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 95ee77662..30cef3496 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -18,18 +18,17 @@ // Boost::serialization doesn't like union types for some reason, // so we need to mark arrays of union values with a special serialization method template -struct UnionArray : public std::array { }; - -namespace boost::serialization { - -template -void serialize(Archive& ar, UnionArray& array, const unsigned int version) +struct UnionArray : public std::array { - static_assert(sizeof(Value) == sizeof(u32)); - ar & *static_cast(static_cast(array.data())); -} - -} +private: + template + void serialize(Archive& ar, const unsigned int) + { + static_assert(sizeof(Value) == sizeof(u32)); + ar & *static_cast(static_cast(this->data())); + } + friend class boost::serialization::access; +}; namespace Pica { From 6917eaf53b0260cf9ef0d1311a59d460f6329715 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 18:52:33 +0000 Subject: [PATCH 031/129] Use load_construct_data for kernel objects --- TODO | 5 ++-- src/audio_core/dsp_interface.h | 1 - src/common/CMakeLists.txt | 4 +++ src/common/archives.h | 12 ++++----- src/common/construct.h | 30 ++++++++++----------- src/common/serialization/atomic.h | 36 ++++++++++++------------- src/core/core.cpp | 2 +- src/core/hle/kernel/address_arbiter.cpp | 5 ++-- src/core/hle/kernel/address_arbiter.h | 3 ++- src/core/hle/kernel/client_port.cpp | 5 +++- src/core/hle/kernel/client_port.h | 4 +++ src/core/hle/kernel/client_session.cpp | 2 +- src/core/hle/kernel/client_session.h | 3 ++- src/core/hle/kernel/event.cpp | 4 +-- src/core/hle/kernel/event.h | 3 ++- src/core/hle/kernel/mutex.cpp | 5 ++-- src/core/hle/kernel/mutex.h | 3 ++- src/core/hle/kernel/object.cpp | 12 +-------- src/core/hle/kernel/object.h | 17 +++++++++--- src/core/hle/kernel/process.cpp | 20 +++++++------- src/core/hle/kernel/process.h | 11 ++++++-- src/core/hle/kernel/resource_limit.cpp | 9 +++++-- src/core/hle/kernel/resource_limit.h | 5 ++++ src/core/hle/kernel/semaphore.cpp | 4 +-- src/core/hle/kernel/semaphore.h | 3 ++- src/core/hle/kernel/server_port.cpp | 9 ++++--- src/core/hle/kernel/server_port.h | 3 +++ src/core/hle/kernel/server_session.cpp | 8 +++--- src/core/hle/kernel/server_session.h | 3 ++- src/core/hle/kernel/shared_memory.cpp | 9 ++++--- src/core/hle/kernel/shared_memory.h | 5 +++- src/core/hle/kernel/thread.cpp | 9 +++---- src/core/hle/kernel/thread.h | 3 ++- src/core/hle/kernel/timer.cpp | 9 ++++--- src/core/hle/kernel/timer.h | 5 +++- 35 files changed, 158 insertions(+), 113 deletions(-) diff --git a/TODO b/TODO index 5a483dc84..be118365d 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,7 @@ ✔ Memory @done(19-08-13 15:41) ☐ Page tables ☐ Skip N3DS RAM if unused -✔ DSP @done(19-08-13 15:41) +☐ DSP ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) ✔ Fix or ignore inverse map @done(19-12-23 12:46) ☐ App loader @@ -16,6 +16,7 @@ ☐ Telemetry session ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE ☐ Review constructor/initialization code +☐ Fix CI ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) @@ -78,7 +79,7 @@ ✔ DSP @done(19-12-26 18:10) ✔ ERR @done(19-12-26 18:14) ✔ FRD @done(19-12-26 19:09) - ☐ FS + ✔ FS @done(19-12-27 11:46) ☐ GSP ☐ HID ☐ HTTP diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h index 29ec13d61..fc3d7cab2 100644 --- a/src/audio_core/dsp_interface.h +++ b/src/audio_core/dsp_interface.h @@ -6,7 +6,6 @@ #include #include -#include "boost/serialization/array.hpp" #include "audio_core/audio_types.h" #include "audio_core/time_stretch.h" #include "common/common_types.h" diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c0182ed48..ac745d868 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -54,6 +54,7 @@ add_custom_command(OUTPUT scm_rev.cpp add_library(common STATIC alignment.h announce_multiplayer_room.h + archives.h assert.h detached_tasks.cpp detached_tasks.h @@ -66,6 +67,7 @@ add_library(common STATIC common_funcs.h common_paths.h common_types.h + construct.h file_util.cpp file_util.h hash.h @@ -91,8 +93,10 @@ add_library(common STATIC scm_rev.h scope_exit.h serialization/atomic.h + serialization/boost_discrete_interval.hpp serialization/boost_flat_set.h serialization/boost_vector.hpp + serialization/optional.h string_util.cpp string_util.h swap.h diff --git a/src/common/archives.h b/src/common/archives.h index a27afe80c..74cd9e08f 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -6,12 +6,12 @@ using iarchive = boost::archive::binary_iarchive; using oarchive = boost::archive::binary_oarchive; #define SERIALIZE_IMPL(A) template void A::serialize( \ - iarchive & ar, \ - const unsigned int file_version \ -); \ -template void A::serialize( \ - oarchive & ar, \ - const unsigned int file_version \ + iarchive & ar, \ + const unsigned int file_version \ +); \ +template void A::serialize( \ + oarchive & ar, \ + const unsigned int file_version \ ); #define SERIALIZE_EXPORT_IMPL(A) \ diff --git a/src/common/construct.h b/src/common/construct.h index 6ef9af1ef..4e230ca43 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -12,20 +12,18 @@ public: } }; -#define BOOST_SERIALIZATION_CONSTRUCT(T) \ -namespace boost { namespace serialization { \ -\ - template \ - inline void save_construct_data( \ - Archive & ar, const T * t, const unsigned int file_version \ - ){ \ - construct_access::save_construct(ar, t, file_version); \ - } \ -\ - template \ - inline void load_construct_data( \ - Archive & ar, T * t, const unsigned int file_version \ - ){ \ - construct_access::load_construct(ar, t, file_version); \ - } \ +#define BOOST_SERIALIZATION_CONSTRUCT(T) \ +namespace boost { namespace serialization { \ +template \ +inline void save_construct_data( \ + Archive & ar, const T * t, const unsigned int file_version \ +){ \ + construct_access::save_construct(ar, t, file_version); \ +} \ +template \ +inline void load_construct_data( \ + Archive & ar, T * t, const unsigned int file_version \ +){ \ + construct_access::load_construct(ar, t, file_version); \ +} \ }} diff --git a/src/common/serialization/atomic.h b/src/common/serialization/atomic.h index ef33202ff..665914df3 100644 --- a/src/common/serialization/atomic.h +++ b/src/common/serialization/atomic.h @@ -3,26 +3,26 @@ #include #include -namespace boost::serialization +namespace boost::serialization { + +template +void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) { - template - void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) - { - boost::serialization::split_free(ar, value, file_version); - } + boost::serialization::split_free(ar, value, file_version); +} - template - void save(Archive& ar, const std::atomic& value, const unsigned int file_version) - { - ar << value.load(); - } +template +void save(Archive& ar, const std::atomic& value, const unsigned int file_version) +{ + ar << value.load(); +} - template - void load(Archive& ar, std::atomic& value, const unsigned int file_version) - { - T tmp; - ar >> tmp; - value.store(tmp); - } +template +void load(Archive& ar, std::atomic& value, const unsigned int file_version) +{ + T tmp; + ar >> tmp; + value.store(tmp); +} } // namespace boost::serialization diff --git a/src/core/core.cpp b/src/core/core.cpp index 055eadae2..2df38f3ed 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -4,7 +4,7 @@ #include #include -#include "boost/serialization/array.hpp" +#include #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index ca120e6f9..e5e017daa 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -69,12 +69,11 @@ std::shared_ptr AddressArbiter::ResumeHighestPriorityThread(VAddr addres return thread; } -AddressArbiter::AddressArbiter() : kernel(Core::Global()) {} +AddressArbiter::AddressArbiter(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} AddressArbiter::~AddressArbiter() {} std::shared_ptr KernelSystem::CreateAddressArbiter(std::string name) { - auto address_arbiter{std::make_shared()}; - address_arbiter->Init(*this); + auto address_arbiter{std::make_shared(*this)}; address_arbiter->name = std::move(name); diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 3b29a84a4..793d274ca 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -36,7 +36,7 @@ enum class ArbitrationType : u32 { class AddressArbiter final : public Object { public: - explicit AddressArbiter(); + explicit AddressArbiter(KernelSystem& kernel); ~AddressArbiter() override; std::string GetTypeName() const override { @@ -85,3 +85,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter) +CONSTRUCT_KERNEL_OBJECT(Kernel::AddressArbiter) diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index f9202035c..618c7d0d7 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -17,6 +17,9 @@ SERIALIZE_EXPORT_IMPL(Kernel::ClientPort) namespace Kernel { +ClientPort::ClientPort(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} +ClientPort::~ClientPort() = default; + ResultVal> ClientPort::Connect() { // Note: Threads do not wait for the server endpoint to call // AcceptSession before returning from this call. @@ -27,7 +30,7 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto [server, client] = Core::Global().CreateSessionPair(server_port->GetName(), SharedFrom(this)); + auto [server, client] = kernel.CreateSessionPair(server_port->GetName(), SharedFrom(this)); if (server_port->hle_handler) server_port->hle_handler->ClientConnected(server); diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 72cae85c3..c5b032f1f 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -18,6 +18,8 @@ class ClientSession; class ClientPort final : public Object { public: + explicit ClientPort(KernelSystem& kernel); + ~ClientPort() override; friend class ServerPort; std::string GetTypeName() const override { @@ -51,6 +53,7 @@ public: void ConnectionClosed(); private: + KernelSystem& kernel; std::shared_ptr server_port; ///< ServerPort associated with this client port. u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have u32 active_sessions = 0; ///< Number of currently open sessions to this port @@ -75,3 +78,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::ClientPort) +CONSTRUCT_KERNEL_OBJECT(Kernel::ClientPort) diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index ba9c2ec50..0b00576d3 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -15,7 +15,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::ClientSession) namespace Kernel { -ClientSession::ClientSession() = default; +ClientSession::ClientSession(KernelSystem& kernel) : Object(kernel) {} ClientSession::~ClientSession() { // This destructor will be called automatically when the last ClientSession handle is closed by // the emulated application. diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 2ffe68f8b..1ddbfb348 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -20,7 +20,7 @@ class Thread; class ClientSession final : public Object { public: - explicit ClientSession(); + explicit ClientSession(KernelSystem& kernel); ~ClientSession() override; friend class KernelSystem; @@ -64,3 +64,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::ClientSession) +CONSTRUCT_KERNEL_OBJECT(Kernel::ClientSession) diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 7af667739..2375d6733 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -15,11 +15,11 @@ SERIALIZE_EXPORT_IMPL(Kernel::Event) namespace Kernel { -Event::Event() : WaitObject() {} +Event::Event(KernelSystem& kernel) : WaitObject(kernel) {} Event::~Event() {} std::shared_ptr KernelSystem::CreateEvent(ResetType reset_type, std::string name) { - auto evt{std::make_shared()}; + auto evt{std::make_shared(*this)}; evt->signaled = false; evt->reset_type = reset_type; diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index bb97f6eb1..509ab5c6c 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -13,7 +13,7 @@ namespace Kernel { class Event final : public WaitObject { public: - explicit Event(); + explicit Event(KernelSystem& kernel); ~Event() override; std::string GetTypeName() const override { @@ -65,3 +65,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::Event) +CONSTRUCT_KERNEL_OBJECT(Kernel::Event) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 16bcd3af2..4badd88ce 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -27,12 +27,11 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } -Mutex::Mutex() : kernel(Core::Global()) {} +Mutex::Mutex(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} Mutex::~Mutex() {} std::shared_ptr KernelSystem::CreateMutex(bool initial_locked, std::string name) { - auto mutex{std::make_shared()}; - mutex->Init(*this); + auto mutex{std::make_shared(*this)}; mutex->lock_count = 0; mutex->name = std::move(name); diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index f4449c0f2..a164b70da 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -18,7 +18,7 @@ class Thread; class Mutex final : public WaitObject { public: - explicit Mutex(); + explicit Mutex(KernelSystem& kernel); ~Mutex() override; std::string GetTypeName() const override { @@ -81,3 +81,4 @@ void ReleaseThreadMutexes(Thread* thread); } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::Mutex) +CONSTRUCT_KERNEL_OBJECT(Kernel::Mutex) diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index 6ab1b1769..f9ca68218 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp @@ -8,17 +8,7 @@ namespace Kernel { -// TODO: Remove this -Object::Object(KernelSystem& kernel) -{ -} - -Object::Object() = default; - -void Object::Init(KernelSystem& kernel) -{ - object_id = kernel.GenerateObjectID(); -} +Object::Object(KernelSystem& kernel) : object_id{kernel.GenerateObjectID()} {} Object::~Object() = default; diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 6adba034e..a61e47c17 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -8,9 +8,12 @@ #include #include #include +#include +#include #include "common/serialization/atomic.h" #include "common/common_types.h" #include "core/hle/kernel/kernel.h" +#include "core/global.h" namespace Kernel { @@ -43,11 +46,8 @@ enum { class Object : NonCopyable, public std::enable_shared_from_this { public: explicit Object(KernelSystem& kernel); - Object(); virtual ~Object(); - virtual void Init(KernelSystem& kernel); - /// Returns a unique identifier for the object. For debugging purposes only. u32 GetObjectId() const { return object_id.load(std::memory_order_relaxed); @@ -99,3 +99,14 @@ inline std::shared_ptr DynamicObjectCast(std::shared_ptr object) { } } // namespace Kernel + +BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::Object) + +#define CONSTRUCT_KERNEL_OBJECT(T) \ +namespace boost::serialization { \ +template \ +inline void load_construct_data( \ + Archive & ar, T * t, const unsigned int file_version \ +){ \ + ::new(t)T(Core::Global()); \ +}} diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 72f882c56..12afe1f89 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -20,6 +20,9 @@ #include "core/memory.h" #include "core/global.h" +SERIALIZE_EXPORT_IMPL(Kernel::Process) +SERIALIZE_EXPORT_IMPL(Kernel::CodeSet) + namespace Kernel { template @@ -46,8 +49,7 @@ void Process::serialize(Archive& ar, const unsigned int file_version) SERIALIZE_IMPL(Process) std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { - auto codeset{std::make_shared()}; - codeset->Init(*this); + auto codeset{std::make_shared(*this)}; codeset->name = std::move(name); codeset->program_id = program_id; @@ -55,9 +57,11 @@ std::shared_ptr KernelSystem::CreateCodeSet(std::string name, u64 progr return codeset; } +CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {} +CodeSet::~CodeSet() {} + std::shared_ptr KernelSystem::CreateProcess(std::shared_ptr code_set) { - auto process{std::make_shared()}; - process->Init(*this); + auto process{std::make_shared(*this)}; process->codeset = std::move(code_set); process->flags.raw = 0; @@ -428,12 +432,8 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe return RESULT_SUCCESS; } -Kernel::Process::Process() : Kernel::Process::Process(Core::Global()) -{ -} - -Kernel::Process::Process(KernelSystem& kernel) : kernel(kernel), handle_table(kernel), vm_manager(kernel.memory) -{ +Kernel::Process::Process(KernelSystem& kernel) + : Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) { kernel.memory.RegisterPageTable(&vm_manager.page_table); } Kernel::Process::~Process() { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 70a5f212b..5746a1c6a 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -65,6 +65,9 @@ struct MemoryRegionInfo; class CodeSet final : public Object { public: + explicit CodeSet(KernelSystem& kernel); + ~CodeSet() override; + struct Segment { std::size_t offset = 0; VAddr addr = 0; @@ -143,8 +146,7 @@ private: class Process final : public Object { public: - Process(); - explicit Process(KernelSystem& kernel); + explicit Process(Kernel::KernelSystem& kernel); ~Process() override; std::string GetTypeName() const override { @@ -235,3 +237,8 @@ private: void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::CodeSet) +BOOST_CLASS_EXPORT_KEY(Kernel::Process) +CONSTRUCT_KERNEL_OBJECT(Kernel::CodeSet) +CONSTRUCT_KERNEL_OBJECT(Kernel::Process) diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index fe19caff9..9affa685a 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -3,15 +3,20 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/kernel/resource_limit.h" +SERIALIZE_EXPORT_IMPL(Kernel::ResourceLimit) + namespace Kernel { +ResourceLimit::ResourceLimit(KernelSystem& kernel) : Object(kernel) {} +ResourceLimit::~ResourceLimit() {} + std::shared_ptr ResourceLimit::Create(KernelSystem& kernel, std::string name) { - auto resource_limit{std::make_shared()}; - resource_limit->Init(kernel); + auto resource_limit{std::make_shared(kernel)}; resource_limit->name = std::move(name); return resource_limit; diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 06fe71587..0d64f1216 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -35,6 +35,8 @@ enum ResourceTypes { class ResourceLimit final : public Object { public: + explicit ResourceLimit(KernelSystem& kernel); + ~ResourceLimit() override; /** * Creates a resource limit object. @@ -165,3 +167,6 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::ResourceLimit) +CONSTRUCT_KERNEL_OBJECT(Kernel::ResourceLimit) diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index f60a653e5..c637f5f4d 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -13,7 +13,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::Semaphore) namespace Kernel { -Semaphore::Semaphore() : WaitObject() {} +Semaphore::Semaphore(KernelSystem& kernel) : WaitObject(kernel) {} Semaphore::~Semaphore() {} ResultVal> KernelSystem::CreateSemaphore(s32 initial_count, @@ -23,7 +23,7 @@ ResultVal> KernelSystem::CreateSemaphore(s32 initial_ if (initial_count > max_count) return ERR_INVALID_COMBINATION_KERNEL; - auto semaphore{std::make_shared()}; + auto semaphore{std::make_shared(*this)}; // When the semaphore is created, some slots are reserved for other threads, // and the rest is reserved for the caller thread diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index ff6a4434a..f28c30ec7 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -16,7 +16,7 @@ namespace Kernel { class Semaphore final : public WaitObject { public: - explicit Semaphore(); + explicit Semaphore(KernelSystem& kernel); ~Semaphore() override; std::string GetTypeName() const override { @@ -60,3 +60,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::Semaphore) +CONSTRUCT_KERNEL_OBJECT(Kernel::Semaphore) diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 0aeb86a78..46aa8f758 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -17,6 +17,9 @@ SERIALIZE_EXPORT_IMPL(Kernel::ServerPort) namespace Kernel { +ServerPort::ServerPort(KernelSystem& kernel) : WaitObject(kernel) {} +ServerPort::~ServerPort() {} + ResultVal> ServerPort::Accept() { if (pending_sessions.empty()) { return ERR_NO_PENDING_SESSIONS; @@ -37,10 +40,8 @@ void ServerPort::Acquire(Thread* thread) { } KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::string name) { - auto server_port{std::make_shared()}; - server_port->Init(*this); - auto client_port{std::make_shared()}; - client_port->Init(*this); + auto server_port{std::make_shared(*this)}; + auto client_port{std::make_shared(*this)}; server_port->name = name + "_Server"; client_port->name = name + "_Client"; diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index f055cd267..2f00e586e 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -25,6 +25,8 @@ class SessionRequestHandler; class ServerPort final : public WaitObject { public: + explicit ServerPort(KernelSystem& kernel); + ~ServerPort() override; std::string GetTypeName() const override { return "ServerPort"; @@ -73,3 +75,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::ServerPort) +CONSTRUCT_KERNEL_OBJECT(Kernel::ServerPort) diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 146142f08..e0c4087f1 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -16,7 +16,7 @@ SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) namespace Kernel { -ServerSession::ServerSession() : kernel(Core::Global()) {} +ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by // the emulated application. @@ -33,8 +33,7 @@ ServerSession::~ServerSession() { ResultVal> ServerSession::Create(KernelSystem& kernel, std::string name) { - auto server_session{std::make_shared()}; - server_session->Init(kernel); + auto server_session{std::make_shared(kernel)}; server_session->name = std::move(name); server_session->parent = nullptr; @@ -127,8 +126,7 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { KernelSystem::SessionPair KernelSystem::CreateSessionPair(const std::string& name, std::shared_ptr port) { auto server_session = ServerSession::Create(*this, name + "_Server").Unwrap(); - auto client_session{std::make_shared()}; - client_session->Init(*this); + auto client_session{std::make_shared(*this)}; client_session->name = name + "_Client"; std::shared_ptr parent(new Session); diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 05b469c38..6eb5673f6 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -42,7 +42,7 @@ class Thread; class ServerSession final : public WaitObject { public: ~ServerSession() override; - explicit ServerSession(); + explicit ServerSession(KernelSystem& kernel); std::string GetName() const override { return name; @@ -125,3 +125,4 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::ServerSession) +CONSTRUCT_KERNEL_OBJECT(Kernel::ServerSession) diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index c76cdfa19..14c9751e8 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/logging/log.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" @@ -10,9 +11,11 @@ #include "core/memory.h" #include "core/global.h" +SERIALIZE_EXPORT_IMPL(Kernel::SharedMemory) + namespace Kernel { -SharedMemory::SharedMemory() : Object(Core::Global()), kernel(Core::Global()) {} +SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} SharedMemory::~SharedMemory() { for (const auto& interval : holding_memory) { kernel.GetMemoryRegion(MemoryRegion::SYSTEM) @@ -28,7 +31,7 @@ SharedMemory::~SharedMemory() { ResultVal> KernelSystem::CreateSharedMemory( Process* owner_process, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { - auto shared_memory{std::make_shared()}; + auto shared_memory{std::make_shared(*this)}; shared_memory->owner_process = owner_process; shared_memory->name = std::move(name); @@ -73,7 +76,7 @@ ResultVal> KernelSystem::CreateSharedMemory( std::shared_ptr KernelSystem::CreateSharedMemoryForApplet( u32 offset, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) { - auto shared_memory{std::make_shared()}; + auto shared_memory{std::make_shared(*this)}; // Allocate memory in heap MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 925f7783c..88727be6d 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -16,7 +16,7 @@ namespace Kernel { class SharedMemory final : public Object { public: - explicit SharedMemory(); + explicit SharedMemory(KernelSystem& kernel); ~SharedMemory() override; std::string GetTypeName() const override { @@ -123,3 +123,6 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::SharedMemory) +CONSTRUCT_KERNEL_OBJECT(Kernel::SharedMemory) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 98fe85175..c824b58a6 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -66,9 +66,9 @@ u32 ThreadManager::NewThreadId() { return next_thread_id++; } -Thread::Thread() - : context(Core::Global().GetThreadManager().NewContext()), - thread_manager(Core::Global().GetThreadManager()) {} +Thread::Thread(KernelSystem& kernel) + : WaitObject(kernel), context(kernel.GetThreadManager().NewContext()), + thread_manager(kernel.GetThreadManager()) {} Thread::~Thread() {} Thread* ThreadManager::GetCurrentThread() const { @@ -338,8 +338,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } - auto thread{std::make_shared()}; - thread->Init(*this); + auto thread{std::make_shared(*this)}; thread_manager->thread_list.push_back(thread); thread_manager->ready_queue.prepare(priority); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index b423392e3..09341560a 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -164,7 +164,7 @@ private: class Thread final : public WaitObject { public: - explicit Thread(); + explicit Thread(KernelSystem&); ~Thread() override; std::string GetName() const override { @@ -340,3 +340,4 @@ std::shared_ptr SetupMainThread(KernelSystem& kernel, u32 entry_point, u } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::Thread) +CONSTRUCT_KERNEL_OBJECT(Kernel::Thread) diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 422cf990c..f1a31cdf9 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" @@ -13,17 +14,19 @@ #include "core/hle/kernel/timer.h" #include "core/global.h" +SERIALIZE_EXPORT_IMPL(Kernel::Timer) + namespace Kernel { -Timer::Timer() : kernel(Core::Global()), timer_manager(Core::Global().GetTimerManager()) {} +Timer::Timer(KernelSystem& kernel) + : WaitObject(kernel), kernel(kernel), timer_manager(kernel.GetTimerManager()) {} Timer::~Timer() { Cancel(); timer_manager.timer_callback_table.erase(callback_id); } std::shared_ptr KernelSystem::CreateTimer(ResetType reset_type, std::string name) { - auto timer{std::make_shared()}; - timer->Init(*this); + auto timer{std::make_shared(*this)}; timer->reset_type = reset_type; timer->signaled = false; diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index 690350611..f61ec1c11 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -46,7 +46,7 @@ private: class Timer final : public WaitObject { public: - explicit Timer(); + explicit Timer(KernelSystem& kernel); ~Timer() override; std::string GetTypeName() const override { @@ -127,3 +127,6 @@ private: }; } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::Timer) +CONSTRUCT_KERNEL_OBJECT(Kernel::Timer) From d482fb359c306bf4301b1aa523afc514d4ed8217 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 20:36:17 +0000 Subject: [PATCH 032/129] Attempting to fix mingw on windows --- src/core/hle/service/apt/apt.h | 1 + src/core/hle/service/service.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 45a93b350..14c07feb3 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -13,6 +13,7 @@ #include "common/common_types.h" #include "common/swap.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/service/apt/applet_manager.h" #include "core/hle/service/service.h" #include "core/global.h" diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 4961678df..b16a4065f 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -237,4 +237,4 @@ namespace boost::serialization { \ } \ template \ void load_construct_data(iarchive& ar, T* t, const unsigned int); \ -} \ No newline at end of file +} From 7b846ffa9891fb86ad7f236cdc76bd63d6839f11 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 21:07:29 +0000 Subject: [PATCH 033/129] clang-format fixes --- src/common/archives.h | 19 ++-- src/common/construct.h | 36 ++++---- src/common/pod.h | 31 +++---- src/common/serialization/atomic.h | 9 +- src/common/serialization/boost_flat_set.h | 15 ++-- src/common/serialization/optional.h | 75 +++++++--------- src/common/thread_queue_list.h | 10 +-- src/common/vector_math.h | 33 ++++--- src/core/arm/arm_interface.h | 12 +-- src/core/core.cpp | 39 +++++---- src/core/core.h | 8 +- src/core/hle/kernel/address_arbiter.cpp | 2 +- src/core/hle/kernel/address_arbiter.h | 9 +- src/core/hle/kernel/client_port.cpp | 2 +- src/core/hle/kernel/client_port.h | 14 ++- src/core/hle/kernel/client_session.cpp | 2 +- src/core/hle/kernel/client_session.h | 9 +- src/core/hle/kernel/config_mem.h | 5 +- src/core/hle/kernel/event.cpp | 2 +- src/core/hle/kernel/event.h | 11 ++- src/core/hle/kernel/handle_table.h | 11 ++- src/core/hle/kernel/hle_ipc.h | 21 +++-- src/core/hle/kernel/ipc.h | 18 ++-- src/core/hle/kernel/kernel.cpp | 25 +++--- src/core/hle/kernel/memory.h | 13 ++- src/core/hle/kernel/mutex.cpp | 2 +- src/core/hle/kernel/mutex.h | 13 ++- src/core/hle/kernel/object.h | 24 +++-- src/core/hle/kernel/process.cpp | 39 +++++---- src/core/hle/kernel/process.h | 35 ++++---- src/core/hle/kernel/resource_limit.h | 53 ++++++------ src/core/hle/kernel/semaphore.cpp | 2 +- src/core/hle/kernel/semaphore.h | 13 ++- src/core/hle/kernel/server_port.cpp | 13 ++- src/core/hle/kernel/server_session.cpp | 2 +- src/core/hle/kernel/server_session.h | 17 ++-- src/core/hle/kernel/session.cpp | 15 ++-- src/core/hle/kernel/shared_memory.cpp | 2 +- src/core/hle/kernel/shared_memory.h | 19 ++-- src/core/hle/kernel/shared_page.h | 5 +- src/core/hle/kernel/thread.cpp | 37 ++++---- src/core/hle/kernel/thread.h | 15 ++-- src/core/hle/kernel/timer.cpp | 2 +- src/core/hle/kernel/timer.h | 22 +++-- src/core/hle/kernel/vm_manager.h | 35 ++++---- src/core/hle/kernel/wait_object.h | 7 +- src/core/hle/service/ac/ac.cpp | 13 ++- src/core/hle/service/ac/ac_i.cpp | 2 +- src/core/hle/service/ac/ac_u.cpp | 2 +- src/core/hle/service/act/act.h | 3 +- src/core/hle/service/act/act_a.cpp | 2 +- src/core/hle/service/act/act_a.h | 1 + src/core/hle/service/act/act_u.cpp | 2 +- src/core/hle/service/act/act_u.h | 1 + src/core/hle/service/am/am.cpp | 2 +- src/core/hle/service/am/am.h | 22 +++-- src/core/hle/service/am/am_app.cpp | 2 +- src/core/hle/service/am/am_app.h | 1 + src/core/hle/service/am/am_net.cpp | 2 +- src/core/hle/service/am/am_net.h | 1 + src/core/hle/service/am/am_sys.cpp | 2 +- src/core/hle/service/am/am_sys.h | 1 + src/core/hle/service/am/am_u.cpp | 2 +- src/core/hle/service/am/am_u.h | 1 + src/core/hle/service/apt/applet_manager.h | 65 +++++++------- src/core/hle/service/apt/apt.cpp | 23 +++-- src/core/hle/service/apt/apt.h | 14 ++- src/core/hle/service/apt/apt_a.cpp | 2 +- src/core/hle/service/apt/apt_a.h | 1 + src/core/hle/service/apt/apt_s.cpp | 2 +- src/core/hle/service/apt/apt_s.h | 1 + src/core/hle/service/apt/apt_u.cpp | 2 +- src/core/hle/service/apt/apt_u.h | 1 + src/core/hle/service/apt/ns_s.cpp | 2 +- src/core/hle/service/apt/ns_s.h | 1 + src/core/hle/service/boss/boss.h | 27 +++--- src/core/hle/service/boss/boss_p.cpp | 2 +- src/core/hle/service/boss/boss_u.cpp | 2 +- src/core/hle/service/cam/cam.cpp | 9 +- src/core/hle/service/cam/cam.h | 87 +++++++++---------- src/core/hle/service/cam/cam_c.cpp | 2 +- src/core/hle/service/cam/cam_q.cpp | 2 +- src/core/hle/service/cam/cam_q.h | 6 +- src/core/hle/service/cam/cam_s.cpp | 2 +- src/core/hle/service/cam/cam_u.cpp | 2 +- src/core/hle/service/csnd/csnd_snd.h | 69 +++++++-------- src/core/hle/service/dlp/dlp_clnt.cpp | 2 +- src/core/hle/service/dlp/dlp_clnt.h | 6 +- src/core/hle/service/dlp/dlp_fkcl.cpp | 2 +- src/core/hle/service/dlp/dlp_fkcl.h | 6 +- src/core/hle/service/dlp/dlp_srvr.cpp | 2 +- src/core/hle/service/dlp/dlp_srvr.h | 5 +- src/core/hle/service/dsp/dsp_dsp.h | 19 ++-- src/core/hle/service/err_f.cpp | 15 ++-- src/core/hle/service/err_f.h | 9 +- src/core/hle/service/frd/frd.h | 21 ++--- src/core/hle/service/frd/frd_a.cpp | 2 +- src/core/hle/service/frd/frd_a.h | 1 + src/core/hle/service/frd/frd_u.cpp | 2 +- src/core/hle/service/frd/frd_u.h | 1 + src/core/hle/service/fs/archive.cpp | 2 +- src/core/hle/service/fs/fs_user.h | 12 ++- src/core/hle/service/service.h | 69 +++++++-------- src/core/hle/service/sm/sm.h | 8 +- src/core/memory.cpp | 37 ++++---- src/core/memory.h | 15 ++-- src/core/mmio.h | 4 +- src/tests/core/hle/kernel/hle_ipc.cpp | 6 +- src/video_core/command_processor.cpp | 3 +- src/video_core/geometry_pipeline.cpp | 57 +++++------- src/video_core/pica.cpp | 8 +- src/video_core/pica_state.h | 101 ++++++++++------------ src/video_core/pica_types.h | 7 +- src/video_core/primitive_assembly.h | 17 ++-- src/video_core/shader/shader.h | 77 ++++++++--------- src/video_core/video_core.cpp | 11 +-- src/video_core/video_core.h | 6 +- 117 files changed, 797 insertions(+), 925 deletions(-) diff --git a/src/common/archives.h b/src/common/archives.h index 74cd9e08f..29f23865b 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -5,16 +5,11 @@ using iarchive = boost::archive::binary_iarchive; using oarchive = boost::archive::binary_oarchive; -#define SERIALIZE_IMPL(A) template void A::serialize( \ - iarchive & ar, \ - const unsigned int file_version \ -); \ -template void A::serialize( \ - oarchive & ar, \ - const unsigned int file_version \ -); +#define SERIALIZE_IMPL(A) \ + template void A::serialize(iarchive & ar, const unsigned int file_version); \ + template void A::serialize(oarchive & ar, const unsigned int file_version); -#define SERIALIZE_EXPORT_IMPL(A) \ -BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ -BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) \ -BOOST_CLASS_EXPORT_IMPLEMENT(A) +#define SERIALIZE_EXPORT_IMPL(A) \ + BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ + BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) \ + BOOST_CLASS_EXPORT_IMPLEMENT(A) diff --git a/src/common/construct.h b/src/common/construct.h index 4e230ca43..6b2b3ceeb 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -2,28 +2,26 @@ class construct_access { public: - template - static inline void save_construct(Archive & ar, const T * t, const unsigned int file_version) { + template + static inline void save_construct(Archive& ar, const T* t, const unsigned int file_version) { t->save_construct(ar, file_version); } - template - static inline void load_construct(Archive & ar, T * t, const unsigned int file_version) { + template + static inline void load_construct(Archive& ar, T* t, const unsigned int file_version) { T::load_construct(ar, t, file_version); } }; -#define BOOST_SERIALIZATION_CONSTRUCT(T) \ -namespace boost { namespace serialization { \ -template \ -inline void save_construct_data( \ - Archive & ar, const T * t, const unsigned int file_version \ -){ \ - construct_access::save_construct(ar, t, file_version); \ -} \ -template \ -inline void load_construct_data( \ - Archive & ar, T * t, const unsigned int file_version \ -){ \ - construct_access::load_construct(ar, t, file_version); \ -} \ -}} +#define BOOST_SERIALIZATION_CONSTRUCT(T) \ + namespace boost { \ + namespace serialization { \ + template \ + inline void save_construct_data(Archive& ar, const T* t, const unsigned int file_version) { \ + construct_access::save_construct(ar, t, file_version); \ + } \ + template \ + inline void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ + construct_access::load_construct(ar, t, file_version); \ + } \ + } \ + } diff --git a/src/common/pod.h b/src/common/pod.h index e7224644a..bb7095417 100644 --- a/src/common/pod.h +++ b/src/common/pod.h @@ -1,20 +1,17 @@ #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); \ +#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/common/serialization/atomic.h b/src/common/serialization/atomic.h index 665914df3..dbc4c0dec 100644 --- a/src/common/serialization/atomic.h +++ b/src/common/serialization/atomic.h @@ -6,20 +6,17 @@ namespace boost::serialization { template -void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) -{ +void serialize(Archive& ar, std::atomic& value, const unsigned int file_version) { boost::serialization::split_free(ar, value, file_version); } template -void save(Archive& ar, const std::atomic& value, const unsigned int file_version) -{ +void save(Archive& ar, const std::atomic& value, const unsigned int file_version) { ar << value.load(); } template -void load(Archive& ar, std::atomic& value, const unsigned int file_version) -{ +void load(Archive& ar, std::atomic& value, const unsigned int file_version) { T tmp; ar >> tmp; value.store(tmp); diff --git a/src/common/serialization/boost_flat_set.h b/src/common/serialization/boost_flat_set.h index 9a0ae77b0..7fe0fe097 100644 --- a/src/common/serialization/boost_flat_set.h +++ b/src/common/serialization/boost_flat_set.h @@ -1,23 +1,21 @@ #pragma once -#include "common/common_types.h" #include #include +#include "common/common_types.h" namespace boost::serialization { template -void save(Archive& ar, const boost::container::flat_set& set, const unsigned int file_version) -{ +void save(Archive& ar, const boost::container::flat_set& set, const unsigned int file_version) { ar << static_cast(set.size()); - for (auto &v : set) { + for (auto& v : set) { ar << v; } } template -void load(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) -{ +void load(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) { u64 count{}; ar >> count; set.clear(); @@ -29,9 +27,8 @@ void load(Archive& ar, boost::container::flat_set& set, const unsigned int fi } template -void serialize(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) -{ +void serialize(Archive& ar, boost::container::flat_set& set, const unsigned int file_version) { boost::serialization::split_free(ar, set, file_version); } -} +} // namespace boost::serialization diff --git a/src/common/serialization/optional.h b/src/common/serialization/optional.h index 5ab6af9b8..4e794058e 100644 --- a/src/common/serialization/optional.h +++ b/src/common/serialization/optional.h @@ -7,85 +7,70 @@ #include #include +#include +#include +#include #include -#include #include #include +#include #include #include -#include -#include -#include // function specializations must be defined in the appropriate // namespace - boost::serialization namespace boost { namespace serialization { -template -void save( - Archive & ar, - const std::optional< T > & t, - const unsigned int /*version*/ -){ - // It is an inherent limitation to the serialization of optional.hpp - // that the underlying type must be either a pointer or must have a - // default constructor. It's possible that this could change sometime - // in the future, but for now, one will have to work around it. This can - // be done by serialization the optional as optional - #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - BOOST_STATIC_ASSERT( - boost::serialization::detail::is_default_constructible::value - || boost::is_pointer::value - ); - #endif +template +void save(Archive& ar, const std::optional& t, const unsigned int /*version*/ +) { +// It is an inherent limitation to the serialization of optional.hpp +// that the underlying type must be either a pointer or must have a +// default constructor. It's possible that this could change sometime +// in the future, but for now, one will have to work around it. This can +// be done by serialization the optional as optional +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + BOOST_STATIC_ASSERT(boost::serialization::detail::is_default_constructible::value || + boost::is_pointer::value); +#endif const bool tflag = t.has_value(); ar << boost::serialization::make_nvp("initialized", tflag); - if (tflag){ + if (tflag) { ar << boost::serialization::make_nvp("value", *t); } } -template -void load( - Archive & ar, - std::optional< T > & t, - const unsigned int version -){ +template +void load(Archive& ar, std::optional& t, const unsigned int version) { bool tflag; ar >> boost::serialization::make_nvp("initialized", tflag); - if(! tflag){ + if (!tflag) { t.reset(); return; } - if(0 == version){ + if (0 == version) { boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - if(boost::archive::library_version_type(3) < library_version){ + boost::archive::library_version_type library_version(ar.get_library_version()); + if (boost::archive::library_version_type(3) < library_version) { ar >> BOOST_SERIALIZATION_NVP(item_version); } } - if(! t.has_value()) + if (!t.has_value()) t = T(); ar >> boost::serialization::make_nvp("value", *t); } -template -void serialize( - Archive & ar, - std::optional< T > & t, - const unsigned int version -){ +template +void serialize(Archive& ar, std::optional& t, const unsigned int version) { boost::serialization::split_free(ar, t, version); } -template -struct version > { +template +struct version> { BOOST_STATIC_CONSTANT(int, value = 1); }; -} // serialization -} // boost +} // namespace serialization +} // namespace boost diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index ce57c01e9..093d86781 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -162,20 +162,20 @@ private: friend class boost::serialization::access; template - void save(Archive& ar, const unsigned int file_version) const - { + void save(Archive& ar, const unsigned int file_version) const { s32 idx = first == UnlinkedTag() ? -1 : static_cast(first - &queues[0]); ar << idx; for (auto i = 0; i < NUM_QUEUES; i++) { - s32 idx1 = first == UnlinkedTag() ? -1 : static_cast(queues[i].next_nonempty - &queues[0]); + s32 idx1 = first == UnlinkedTag() + ? -1 + : static_cast(queues[i].next_nonempty - &queues[0]); ar << idx1; ar << queues[i].data; } } template - void load(Archive& ar, const unsigned int file_version) - { + void load(Archive& ar, const unsigned int file_version) { s32 idx; ar >> idx; first = idx < 0 ? UnlinkedTag() : &queues[idx]; diff --git a/src/common/vector_math.h b/src/common/vector_math.h index 171d4ebfd..ba7bd1aa7 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -46,11 +46,10 @@ class Vec4; template class Vec2 { friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & x; - ar & y; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& x; + ar& y; } public: @@ -201,12 +200,11 @@ inline float Vec2::Normalize() { template class Vec3 { friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & x; - ar & y; - ar & z; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& x; + ar& y; + ar& z; } public: @@ -418,13 +416,12 @@ using Vec3f = Vec3; template class Vec4 { friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & x; - ar & y; - ar & z; - ar & w; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& x; + ar& y; + ar& z; + ar& w; } public: diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 483ba4371..be30499d1 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -20,8 +20,7 @@ public: friend class boost::serialization::access; template - void save(Archive& ar, const unsigned int file_version) const - { + void save(Archive& ar, const unsigned int file_version) const { for (auto i = 0; i < 16; i++) { auto r = GetCpuRegister(i); ar << r; @@ -39,8 +38,7 @@ public: } template - void load(Archive& ar, const unsigned int file_version) - { + void load(Archive& ar, const unsigned int file_version) { u32 r; for (auto i = 0; i < 16; i++) { ar >> r; @@ -220,8 +218,7 @@ private: friend class boost::serialization::access; template - void save(Archive& ar, const unsigned int file_version) const - { + void save(Archive& ar, const unsigned int file_version) const { for (auto i = 0; i < 15; i++) { auto r = GetReg(i); ar << r; @@ -245,8 +242,7 @@ private: } template - void load(Archive& ar, const unsigned int file_version) - { + void load(Archive& ar, const unsigned int file_version) { u32 r; for (auto i = 0; i < 15; i++) { ar >> r; diff --git a/src/core/core.cpp b/src/core/core.cpp index 2df38f3ed..6812a9474 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -48,10 +48,14 @@ namespace Core { /*static*/ System System::s_instance; template <> -Core::System& Global() { return System::GetInstance(); } +Core::System& Global() { + return System::GetInstance(); +} template <> -Kernel::KernelSystem& Global() { return System::GetInstance().Kernel(); } +Kernel::KernelSystem& Global() { + return System::GetInstance().Kernel(); +} System::ResultStatus System::RunLoop(bool tight_loop) { status = ResultStatus::Success; @@ -209,8 +213,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique(*memory, *timing, - [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique( + *memory, *timing, [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -400,32 +404,29 @@ void System::Reset() { Load(*m_emu_window, m_filepath); } -template -void System::serialize(Archive & ar, const unsigned int file_version) -{ - ar & *cpu_core.get(); - ar & *service_manager.get(); - ar & GPU::g_regs; - ar & LCD::g_regs; +template +void System::serialize(Archive& ar, const unsigned int file_version) { + ar&* cpu_core.get(); + ar&* service_manager.get(); + ar& GPU::g_regs; + ar& LCD::g_regs; ar & dsp_core->GetDspMemory(); - ar & *memory.get(); - ar & *kernel.get(); + ar&* memory.get(); + ar&* kernel.get(); } -void System::Save(std::ostream &stream) const -{ +void System::Save(std::ostream& stream) const { { oarchive oa{stream}; - oa & *this; + oa&* this; } VideoCore::Save(stream); } -void System::Load(std::istream &stream) -{ +void System::Load(std::istream& stream) { { iarchive ia{stream}; - ia & *this; + ia&* this; } VideoCore::Load(stream); } diff --git a/src/core/core.h b/src/core/core.h index 8bf04d365..75e0e1a54 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -272,9 +272,9 @@ public: return registered_image_interface; } - void Save(std::ostream &stream) const; + void Save(std::ostream& stream) const; - void Load(std::istream &stream); + void Load(std::istream& stream); private: /** @@ -345,8 +345,8 @@ private: std::atomic shutdown_requested; friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version); + template + void serialize(Archive& ar, const unsigned int file_version); }; inline ARM_Interface& CPU() { diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index e5e017daa..7b8329c4d 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -6,12 +6,12 @@ #include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "core/global.h" #include "core/hle/kernel/address_arbiter.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" #include "core/memory.h" -#include "core/global.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Kernel namespace diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 793d274ca..19b80315f 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -74,11 +74,10 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & name; - ar & waiting_threads; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& name; + ar& waiting_threads; } }; diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 618c7d0d7..e7e8a8014 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -4,6 +4,7 @@ #include "common/archives.h" #include "common/assert.h" +#include "core/global.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/errors.h" @@ -11,7 +12,6 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::ClientPort) diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index c5b032f1f..1d0f5c024 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -61,17 +61,15 @@ private: friend class KernelSystem; - private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & server_port; - ar & max_sessions; - ar & active_sessions; - ar & name; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& server_port; + ar& max_sessions; + ar& active_sessions; + ar& name; } }; diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 0b00576d3..a47e6411b 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/assert.h" #include "common/archives.h" +#include "common/assert.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/hle_ipc.h" diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 1ddbfb348..38f39c299 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -53,11 +53,10 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & name; - ar & parent; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& name; + ar& parent; } }; diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index 26fc0bccb..e4e895516 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -60,10 +60,9 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { + void serialize(Archive& ar, const unsigned int file_version) { auto o_config_mem = boost::serialization::binary_object(&config_mem, sizeof(config_mem)); - ar & o_config_mem; + ar& o_config_mem; } }; diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 2375d6733..9f26847b0 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -5,8 +5,8 @@ #include #include #include -#include "common/assert.h" #include "common/archives.h" +#include "common/assert.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 509ab5c6c..892718533 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -53,12 +53,11 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & reset_type; - ar & signaled; - ar & name; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& reset_type; + ar& signaled; + ar& name; } }; diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index eabf06c26..728ab5fa3 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -121,12 +121,11 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & objects; - ar & generations; - ar & next_generation; - ar & next_free_slot; + void serialize(Archive& ar, const unsigned int file_version) { + ar& objects; + ar& generations; + ar& next_generation; + ar& next_free_slot; } }; diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 162a2eb39..2177b733e 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -11,10 +11,10 @@ #include #include #include -#include -#include -#include #include +#include +#include +#include #include "common/common_types.h" #include "common/swap.h" #include "core/hle/ipc.h" @@ -74,9 +74,10 @@ public: /// in each service must inherit from this. struct SessionDataBase { virtual ~SessionDataBase() = default; + private: template - void serialize(Archive& ar, const unsigned int file_version) { } + void serialize(Archive& ar, const unsigned int file_version) {} friend class boost::serialization::access; }; @@ -104,10 +105,9 @@ protected: private: template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & session; - ar & data; + void serialize(Archive& ar, const unsigned int file_version) { + ar& session; + ar& data; } friend class boost::serialization::access; }; @@ -117,9 +117,8 @@ protected: private: template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & connected_sessions; + void serialize(Archive& ar, const unsigned int file_version) { + ar& connected_sessions; } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/ipc.h b/src/core/hle/kernel/ipc.h index 46d86a528..2c69617d4 100644 --- a/src/core/hle/kernel/ipc.h +++ b/src/core/hle/kernel/ipc.h @@ -30,15 +30,15 @@ struct MappedBufferContext { private: template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & permissions; - ar & size; - ar & source_address; - ar & target_address; - // TODO: Check whether we need these. If we do, add a field for the size and/or change to a 'vector' - //ar & buffer; - //ar & reserve_buffer; + void serialize(Archive& ar, const unsigned int file_version) { + ar& permissions; + ar& size; + ar& source_address; + ar& target_address; + // TODO: Check whether we need these. If we do, add a field for the size and/or change to a + // 'vector' + // ar & buffer; + // ar & reserve_buffer; } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a45973968..7edef2505 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -104,20 +104,19 @@ void KernelSystem::AddNamedPort(std::string name, std::shared_ptr po } template -void KernelSystem::serialize(Archive& ar, const unsigned int file_version) -{ - ar & memory_regions; - ar & named_ports; - ar & *current_cpu.get(); +void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { + ar& memory_regions; + ar& named_ports; + ar&* current_cpu.get(); // NB: subsystem references and prepare_reschedule_callback are constant - ar & *resource_limits.get(); - ar & next_object_id; - ar & *timer_manager.get(); - ar & next_process_id; - ar & process_list; - ar & current_process; - ar & *thread_manager.get(); - ar & *config_mem_handler.get(); + ar&* resource_limits.get(); + ar& next_object_id; + ar&* timer_manager.get(); + ar& next_process_id; + ar& process_list; + ar& current_process; + ar&* thread_manager.get(); + ar&* config_mem_handler.get(); // Shared page data is read-only at the moment, so doesn't need serializing // Deliberately don't include debugger info to allow debugging through loads } diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index ed4ea1296..f4b0a6d98 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -7,8 +7,8 @@ #include #include #include -#include "common/serialization/boost_discrete_interval.hpp" #include "common/common_types.h" +#include "common/serialization/boost_discrete_interval.hpp" namespace Kernel { @@ -66,13 +66,12 @@ struct MemoryRegionInfo { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & base; - ar & size; - ar & used; + void serialize(Archive& ar, const unsigned int file_version) { + ar& base; + ar& size; + ar& used; // This works because interval_set has exactly one member of type ImplSetT - ar & *(reinterpret_cast(&free_blocks)); + ar&*(reinterpret_cast(&free_blocks)); } }; diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 4badd88ce..6aff80224 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -7,12 +7,12 @@ #include "common/archives.h" #include "common/assert.h" #include "core/core.h" +#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Mutex) diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index a164b70da..4adf674c3 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -62,13 +62,12 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & lock_count; - ar & priority; - ar & name; - ar & holding_thread; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& lock_count; + ar& priority; + ar& name; + ar& holding_thread; } }; diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index a61e47c17..57b208dc1 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -10,10 +10,10 @@ #include #include #include -#include "common/serialization/atomic.h" #include "common/common_types.h" -#include "core/hle/kernel/kernel.h" +#include "common/serialization/atomic.h" #include "core/global.h" +#include "core/hle/kernel/kernel.h" namespace Kernel { @@ -72,9 +72,8 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & object_id; + void serialize(Archive& ar, const unsigned int file_version) { + ar& object_id; } }; @@ -102,11 +101,10 @@ inline std::shared_ptr DynamicObjectCast(std::shared_ptr object) { BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::Object) -#define CONSTRUCT_KERNEL_OBJECT(T) \ -namespace boost::serialization { \ -template \ -inline void load_construct_data( \ - Archive & ar, T * t, const unsigned int file_version \ -){ \ - ::new(t)T(Core::Global()); \ -}} +#define CONSTRUCT_KERNEL_OBJECT(T) \ + namespace boost::serialization { \ + template \ + inline void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ + ::new (t) T(Core::Global()); \ + } \ + } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 12afe1f89..78b695e97 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -11,6 +11,7 @@ #include "common/common_funcs.h" #include "common/logging/log.h" #include "common/serialization/boost_vector.hpp" +#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" @@ -18,7 +19,6 @@ #include "core/hle/kernel/thread.h" #include "core/hle/kernel/vm_manager.h" #include "core/memory.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Process) SERIALIZE_EXPORT_IMPL(Kernel::CodeSet) @@ -26,24 +26,25 @@ SERIALIZE_EXPORT_IMPL(Kernel::CodeSet) namespace Kernel { template -void Process::serialize(Archive& ar, const unsigned int file_version) -{ - ar & boost::serialization::base_object(*this); - ar & handle_table; - ar & codeset; - ar & resource_limit; - ar & svc_access_mask; - ar & handle_table_size; - ar & (boost::container::vector >&)address_mappings; - ar & flags.raw; - ar & kernel_version; - ar & ideal_processor; - ar & status; - ar & process_id; - ar & vm_manager; - ar & memory_used; - ar & memory_region; - ar & tls_slots; +void Process::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& handle_table; + ar& codeset; + ar& resource_limit; + ar& svc_access_mask; + ar& handle_table_size; + ar&(boost::container::vector< + AddressMapping, boost::container::dtl::static_storage_allocator>&) + address_mappings; + ar& flags.raw; + ar& kernel_version; + ar& ideal_processor; + ar& status; + ar& process_id; + ar& vm_manager; + ar& memory_used; + ar& memory_region; + ar& tls_slots; } SERIALIZE_IMPL(Process) diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 5746a1c6a..f9aa76c67 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/handle_table.h" @@ -31,12 +31,11 @@ struct AddressMapping { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & address; - ar & size; - ar & read_only; - ar & unk_flag; + void serialize(Archive& ar, const unsigned int file_version) { + ar& address; + ar& size; + ar& read_only; + ar& unk_flag; } }; @@ -76,11 +75,10 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & offset; - ar & addr; - ar & size; + void serialize(Archive& ar, const unsigned int file_version) { + ar& offset; + ar& addr; + ar& size; } }; @@ -133,14 +131,13 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); // TODO: memory reference - ar & segments; - ar & entrypoint; - ar & name; - ar & program_id; + ar& segments; + ar& entrypoint; + ar& name; + ar& program_id; } }; diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 0d64f1216..8593a03a3 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -116,30 +116,30 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - // NB most of these aren't used at all currently, but we're adding them here for forwards compatibility - ar & name; - ar & max_priority; - ar & max_commit; - ar & max_threads; - ar & max_events; - ar & max_mutexes; - ar & max_semaphores; - ar & max_timers; - ar & max_shared_mems; - ar & max_address_arbiters; - ar & max_cpu_time; - ar & current_commit; - ar & current_threads; - ar & current_events; - ar & current_mutexes; - ar & current_semaphores; - ar & current_timers; - ar & current_shared_mems; - ar & current_address_arbiters; - ar & current_cpu_time; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + // NB most of these aren't used at all currently, but we're adding them here for forwards + // compatibility + ar& name; + ar& max_priority; + ar& max_commit; + ar& max_threads; + ar& max_events; + ar& max_mutexes; + ar& max_semaphores; + ar& max_timers; + ar& max_shared_mems; + ar& max_address_arbiters; + ar& max_cpu_time; + ar& current_commit; + ar& current_threads; + ar& current_events; + ar& current_mutexes; + ar& current_semaphores; + ar& current_timers; + ar& current_shared_mems; + ar& current_address_arbiters; + ar& current_cpu_time; } }; @@ -160,9 +160,8 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & resource_limits; + void serialize(Archive& ar, const unsigned int file_version) { + ar& resource_limits; } }; diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index c637f5f4d..7aefc8605 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/assert.h" #include "common/archives.h" +#include "common/assert.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/semaphore.h" diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index f28c30ec7..a7ab192a6 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -5,8 +5,8 @@ #pragma once #include -#include #include +#include #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" @@ -48,12 +48,11 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & max_count; - ar & available_count; - ar & name; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& max_count; + ar& available_count; + ar& name; } }; diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 46aa8f758..077150222 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -7,11 +7,11 @@ #include "common/assert.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/errors.h" +#include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/thread.h" -#include "core/hle/kernel/hle_ipc.h" SERIALIZE_EXPORT_IMPL(Kernel::ServerPort) @@ -53,12 +53,11 @@ KernelSystem::PortPair KernelSystem::CreatePortPair(u32 max_sessions, std::strin } template -void ServerPort::serialize(Archive& ar, const unsigned int file_version) -{ - ar & boost::serialization::base_object(*this); - ar & name; - ar & pending_sessions; - ar & hle_handler; +void ServerPort::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& name; + ar& pending_sessions; + ar& hle_handler; } SERIALIZE_IMPL(ServerPort) diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index e0c4087f1..4b393b63d 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -4,13 +4,13 @@ #include #include "common/archives.h" +#include "core/global.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 6eb5673f6..331ac8397 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -110,15 +110,14 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & name; - ar & parent; - ar & hle_handler; - ar & pending_requesting_threads; - ar & currently_handling; - ar & mapped_buffer_context; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& name; + ar& parent; + ar& hle_handler; + ar& pending_requesting_threads; + ar& currently_handling; + ar& mapped_buffer_context; } }; diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index a2a1f90f9..1ec1039dc 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -4,22 +4,21 @@ #include #include "common/archives.h" -#include "core/hle/kernel/session.h" -#include "core/hle/kernel/client_session.h" -#include "core/hle/kernel/server_session.h" #include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/session.h" SERIALIZE_IMPL(Kernel::Session) namespace Kernel { template -void Session::serialize(Archive& ar, const unsigned int file_version) -{ - ar & client; - ar & server; - ar & port; +void Session::serialize(Archive& ar, const unsigned int file_version) { + ar& client; + ar& server; + ar& port; } } // namespace Kernel diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 14c9751e8..55c374dc5 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -5,11 +5,11 @@ #include #include "common/archives.h" #include "common/logging/log.h" +#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/shared_memory.h" #include "core/memory.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::SharedMemory) diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 88727be6d..f2fa1a728 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -107,17 +107,16 @@ private: KernelSystem& kernel; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & linear_heap_phys_offset; + void serialize(Archive& ar, const unsigned int file_version) { + ar& linear_heap_phys_offset; // TODO: backing blocks u8* (this is always FCRAM I think) - ar & size; - ar & permissions; - ar & other_permissions; - ar & owner_process; - ar & base_address; - ar & name; - ar & *(reinterpret_cast(&holding_memory)); + ar& size; + ar& permissions; + ar& other_permissions; + ar& owner_process; + ar& base_address; + ar& name; + ar&*(reinterpret_cast(&holding_memory)); } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index 58cd46334..b3e1a48b6 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -108,10 +108,9 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { + void serialize(Archive& ar, const unsigned int file_version) { auto o_shared_page = boost::serialization::binary_object(&shared_page, sizeof(shared_page)); - ar & o_shared_page; + ar& o_shared_page; } }; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index c824b58a6..c3c5da7d4 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -15,6 +15,7 @@ #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" +#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" @@ -24,31 +25,29 @@ #include "core/hle/kernel/thread.h" #include "core/hle/result.h" #include "core/memory.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Thread) namespace Kernel { template -void Thread::serialize(Archive& ar, const unsigned int file_version) -{ - ar & *context.get(); - ar & thread_id; - ar & status; - ar & entry_point; - ar & stack_top; - ar & nominal_priority; - ar & current_priority; - ar & last_running_ticks; - ar & processor_id; - ar & tls_address; - ar & held_mutexes; - ar & pending_mutexes; - ar & owner_process; - ar & wait_objects; - ar & wait_address; - ar & name; +void Thread::serialize(Archive& ar, const unsigned int file_version) { + ar&* context.get(); + ar& thread_id; + ar& status; + ar& entry_point; + ar& stack_top; + ar& nominal_priority; + ar& current_priority; + ar& last_running_ticks; + ar& processor_id; + ar& tls_address; + ar& held_mutexes; + ar& pending_mutexes; + ar& owner_process; + ar& wait_objects; + ar& wait_address; + ar& name; // TODO: How the hell to do wakeup_callback } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 09341560a..219db9f2d 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -9,10 +9,10 @@ #include #include #include +#include #include #include #include -#include #include "common/common_types.h" #include "common/thread_queue_list.h" #include "core/arm/arm_interface.h" @@ -152,13 +152,12 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & next_thread_id; - ar & current_thread; - ar & ready_queue; - ar & wakeup_callback_table; - ar & thread_list; + void serialize(Archive& ar, const unsigned int file_version) { + ar& next_thread_id; + ar& current_thread; + ar& ready_queue; + ar& wakeup_callback_table; + ar& thread_list; } }; diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index f1a31cdf9..d29b25986 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -8,11 +8,11 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" +#include "core/global.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" -#include "core/global.h" SERIALIZE_EXPORT_IMPL(Kernel::Timer) diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index f61ec1c11..d2c513024 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -37,10 +37,9 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & next_timer_callback_id; - ar & timer_callback_table; + void serialize(Archive& ar, const unsigned int file_version) { + ar& next_timer_callback_id; + ar& timer_callback_table; } }; @@ -115,14 +114,13 @@ private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & reset_type; - ar & initial_delay; - ar & interval_delay; - ar & signaled; - ar & name; - ar & callback_id; + void serialize(Archive& ar, const unsigned int file_version) { + ar& reset_type; + ar& initial_delay; + ar& interval_delay; + ar& signaled; + ar& name; + ar& callback_id; } }; diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index e930fc64a..5fd6d8740 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -86,17 +86,16 @@ struct VirtualMemoryArea { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & base; - ar & size; - ar & type; - ar & permissions; - ar & meminfo_state; + void serialize(Archive& ar, const unsigned int file_version) { + ar& base; + ar& size; + ar& type; + ar& permissions; + ar& meminfo_state; // TODO: backing memory ref // backing memory can be: Physical/FCRAM pointer, config mem, shared page - ar & paddr; - ar & mmio_handler; + ar& paddr; + ar& mmio_handler; } }; @@ -213,27 +212,25 @@ public: private: friend class boost::serialization::access; template - void save(Archive& ar, const unsigned int file_version) const - { - ar & vma_map; + void save(Archive& ar, const unsigned int file_version) const { + ar& vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { ar << memory.GetFCRAMOffset(page_table.pointers[i]); } - ar & page_table.special_regions; - ar & page_table.attributes; + ar& page_table.special_regions; + ar& page_table.attributes; } template - void load(Archive& ar, const unsigned int file_version) - { - ar & vma_map; + void load(Archive& ar, const unsigned int file_version) { + ar& vma_map; for (int i = 0; i < page_table.pointers.size(); i++) { u32 offset{}; ar >> offset; page_table.pointers[i] = memory.GetFCRAMPointer(offset); } - ar & page_table.special_regions; - ar & page_table.attributes; + ar& page_table.special_regions; + ar& page_table.attributes; } BOOST_SERIALIZATION_SPLIT_MEMBER() diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index e08997721..c07290e8a 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h @@ -69,10 +69,9 @@ private: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & waiting_threads; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& waiting_threads; // NB: hle_notifier *not* serialized since it's a callback! // Fortunately it's only used in one place (DSP) so we can reconstruct it there } diff --git a/src/core/hle/service/ac/ac.cpp b/src/core/hle/service/ac/ac.cpp index 356df5a63..d9f1085c8 100644 --- a/src/core/hle/service/ac/ac.cpp +++ b/src/core/hle/service/ac/ac.cpp @@ -3,9 +3,9 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" -#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" @@ -181,12 +181,11 @@ void InstallInterfaces(Core::System& system) { } template -void Module::serialize(Archive& ar, const unsigned int) -{ - ar & ac_connected; - ar & close_event; - ar & connect_event; - ar & disconnect_event; +void Module::serialize(Archive& ar, const unsigned int) { + ar& ac_connected; + ar& close_event; + ar& connect_event; + ar& disconnect_event; // default_config is never written to } diff --git a/src/core/hle/service/ac/ac_i.cpp b/src/core/hle/service/ac/ac_i.cpp index e4cc4c1f1..ff4fb954c 100644 --- a/src/core/hle/service/ac/ac_i.cpp +++ b/src/core/hle/service/ac/ac_i.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/ac/ac_i.h" #include "common/archives.h" +#include "core/hle/service/ac/ac_i.h" namespace Service::AC { diff --git a/src/core/hle/service/ac/ac_u.cpp b/src/core/hle/service/ac/ac_u.cpp index 429942f7d..e88cdd164 100644 --- a/src/core/hle/service/ac/ac_u.cpp +++ b/src/core/hle/service/ac/ac_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/ac/ac_u.h" #include "common/archives.h" +#include "core/hle/service/ac/ac_u.h" namespace Service::AC { diff --git a/src/core/hle/service/act/act.h b/src/core/hle/service/act/act.h index c327cdaef..11812bcfe 100644 --- a/src/core/hle/service/act/act.h +++ b/src/core/hle/service/act/act.h @@ -23,9 +23,10 @@ public: protected: std::shared_ptr act; }; + private: template - inline void serialize(Archive& ar, const unsigned int file_version) { } + inline void serialize(Archive& ar, const unsigned int file_version) {} friend class boost::serialization::access; }; diff --git a/src/core/hle/service/act/act_a.cpp b/src/core/hle/service/act/act_a.cpp index b4bf750f7..b85a17183 100644 --- a/src/core/hle/service/act/act_a.cpp +++ b/src/core/hle/service/act/act_a.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/act/act_a.h" #include "common/archives.h" +#include "core/hle/service/act/act_a.h" namespace Service::ACT { diff --git a/src/core/hle/service/act/act_a.h b/src/core/hle/service/act/act_a.h index 1e37c9bde..1454441d5 100644 --- a/src/core/hle/service/act/act_a.h +++ b/src/core/hle/service/act/act_a.h @@ -11,6 +11,7 @@ namespace Service::ACT { class ACT_A final : public Module::Interface { public: explicit ACT_A(std::shared_ptr act); + private: SERVICE_SERIALIZATION(ACT_A, act, Module) }; diff --git a/src/core/hle/service/act/act_u.cpp b/src/core/hle/service/act/act_u.cpp index 599bec18a..a0058d573 100644 --- a/src/core/hle/service/act/act_u.cpp +++ b/src/core/hle/service/act/act_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/act/act_u.h" #include "common/archives.h" +#include "core/hle/service/act/act_u.h" namespace Service::ACT { diff --git a/src/core/hle/service/act/act_u.h b/src/core/hle/service/act/act_u.h index 820aa862a..bcd2d653e 100644 --- a/src/core/hle/service/act/act_u.h +++ b/src/core/hle/service/act/act_u.h @@ -11,6 +11,7 @@ namespace Service::ACT { class ACT_U final : public Module::Interface { public: explicit ACT_U(std::shared_ptr act); + private: SERVICE_SERIALIZATION(ACT_U, act, Module) }; diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 45ed29e6c..b3bd037ea 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1455,7 +1455,7 @@ Module::Module(Core::System& system) : kernel(system.Kernel()) { system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex"); } -Module::Module(Kernel::KernelSystem& kernel) : kernel(kernel) { } +Module::Module(Kernel::KernelSystem& kernel) : kernel(kernel) {} Module::~Module() = default; diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 771bbfb53..22481179e 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -10,15 +10,15 @@ #include #include #include -#include #include +#include #include "common/common_types.h" #include "core/file_sys/cia_container.h" #include "core/file_sys/file_backend.h" +#include "core/global.h" #include "core/hle/kernel/mutex.h" #include "core/hle/result.h" #include "core/hle/service/service.h" -#include "core/global.h" namespace Core { class System; @@ -585,11 +585,10 @@ private: std::shared_ptr system_updater_mutex; template - void serialize(Archive& ar, const unsigned int) - { - ar & cia_installing; - ar & am_title_list; - ar & system_updater_mutex; + void serialize(Archive& ar, const unsigned int) { + ar& cia_installing; + ar& am_title_list; + ar& system_updater_mutex; } friend class boost::serialization::access; }; @@ -599,9 +598,8 @@ void InstallInterfaces(Core::System& system); } // namespace Service::AM namespace boost::serialization { - template - inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) - { - ::new(t)Service::AM::Module(Core::Global()); - } +template +inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) { + ::new (t) Service::AM::Module(Core::Global()); } +} // namespace boost::serialization diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp index 52d256ca2..788ee090c 100644 --- a/src/core/hle/service/am/am_app.cpp +++ b/src/core/hle/service/am/am_app.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/am/am_app.h" #include "common/archives.h" +#include "core/hle/service/am/am_app.h" namespace Service::AM { diff --git a/src/core/hle/service/am/am_app.h b/src/core/hle/service/am/am_app.h index fae22d96f..b8e858cb4 100644 --- a/src/core/hle/service/am/am_app.h +++ b/src/core/hle/service/am/am_app.h @@ -11,6 +11,7 @@ namespace Service::AM { class AM_APP final : public Module::Interface { public: explicit AM_APP(std::shared_ptr am); + private: SERVICE_SERIALIZATION(AM_APP, am, Module) }; diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index 44c852c19..cd88965af 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/am/am_net.h" #include "common/archives.h" +#include "core/hle/service/am/am_net.h" namespace Service::AM { diff --git a/src/core/hle/service/am/am_net.h b/src/core/hle/service/am/am_net.h index 4a50c6c07..b73610df9 100644 --- a/src/core/hle/service/am/am_net.h +++ b/src/core/hle/service/am/am_net.h @@ -11,6 +11,7 @@ namespace Service::AM { class AM_NET final : public Module::Interface { public: explicit AM_NET(std::shared_ptr am); + private: SERVICE_SERIALIZATION(AM_NET, am, Module) }; diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp index c6817fe87..6c7e99235 100644 --- a/src/core/hle/service/am/am_sys.cpp +++ b/src/core/hle/service/am/am_sys.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/am/am_sys.h" #include "common/archives.h" +#include "core/hle/service/am/am_sys.h" namespace Service::AM { diff --git a/src/core/hle/service/am/am_sys.h b/src/core/hle/service/am/am_sys.h index c67052302..fdee63b13 100644 --- a/src/core/hle/service/am/am_sys.h +++ b/src/core/hle/service/am/am_sys.h @@ -11,6 +11,7 @@ namespace Service::AM { class AM_SYS final : public Module::Interface { public: explicit AM_SYS(std::shared_ptr am); + private: SERVICE_SERIALIZATION(AM_SYS, am, Module) }; diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp index c9b80bf06..cffb88388 100644 --- a/src/core/hle/service/am/am_u.cpp +++ b/src/core/hle/service/am/am_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/am/am_u.h" #include "common/archives.h" +#include "core/hle/service/am/am_u.h" namespace Service::AM { diff --git a/src/core/hle/service/am/am_u.h b/src/core/hle/service/am/am_u.h index c09e27c09..d71bf722c 100644 --- a/src/core/hle/service/am/am_u.h +++ b/src/core/hle/service/am/am_u.h @@ -11,6 +11,7 @@ namespace Service::AM { class AM_U final : public Module::Interface { public: explicit AM_U(std::shared_ptr am); + private: SERVICE_SERIALIZATION(AM_U, am, Module) }; diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 9410b6b54..e799c92d2 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -10,10 +10,10 @@ #include #include #include "common/serialization/optional.h" +#include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" -#include "core/global.h" namespace Core { class System; @@ -90,13 +90,12 @@ struct MessageParameter { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & sender_id; - ar & destination_id; - ar & signal; - ar & object; - ar & buffer; + void serialize(Archive& ar, const unsigned int) { + ar& sender_id; + ar& destination_id; + ar& signal; + ar& object; + ar& buffer; } friend class boost::serialization::access; }; @@ -179,12 +178,11 @@ public: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & next_title_id; - ar & next_media_type; - ar & current_title_id; - ar & current_media_type; + void serialize(Archive& ar, const unsigned int) { + ar& next_title_id; + ar& next_media_type; + ar& current_title_id; + ar& current_media_type; } friend class boost::serialization::access; }; @@ -228,16 +226,15 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & applet_id; - ar & slot; - ar & title_id; - ar & registered; - ar & loaded; - ar & attributes.raw; - ar & notification_event; - ar & parameter_event; + void serialize(Archive& ar, const unsigned int) { + ar& applet_id; + ar& slot; + ar& title_id; + ar& registered; + ar& loaded; + ar& attributes.raw; + ar& notification_event; + ar& parameter_event; } friend class boost::serialization::access; }; @@ -260,12 +257,11 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & next_parameter; - ar & app_jump_parameters; - ar & applet_slots; - ar & library_applet_closing_command; + void serialize(Archive& ar, const unsigned int) { + ar& next_parameter; + ar& app_jump_parameters; + ar& applet_slots; + ar& library_applet_closing_command; } friend class boost::serialization::access; }; @@ -273,9 +269,8 @@ private: } // namespace Service::APT namespace boost::serialization { - template - inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) - { - ::new(t)Service::APT::AppletManager(Core::Global()); - } +template +inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) { + ::new (t) Service::APT::AppletManager(Core::Global()); } +} // namespace boost::serialization diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index d5a7fb001..8780f67e0 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" -#include "common/archives.h" #include "core/core.h" #include "core/file_sys/archive_ncch.h" #include "core/file_sys/file_backend.h" @@ -32,17 +32,16 @@ SERVICE_CONSTRUCT_IMPL(Service::APT::Module) namespace Service::APT { template -void Module::serialize(Archive& ar, const unsigned int) -{ - ar & shared_font_mem; - ar & shared_font_loaded; - ar & shared_font_relocated; - ar & lock; - ar & cpu_percent; - ar & unknown_ns_state_field; - ar & screen_capture_buffer; - ar & screen_capture_post_permission; - ar & applet_manager; +void Module::serialize(Archive& ar, const unsigned int) { + ar& shared_font_mem; + ar& shared_font_loaded; + ar& shared_font_relocated; + ar& lock; + ar& cpu_percent; + ar& unknown_ns_state_field; + ar& screen_capture_buffer; + ar& screen_capture_post_permission; + ar& applet_manager; } SERIALIZE_IMPL(Module) diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 14c07feb3..aa480331c 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -12,10 +12,9 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/service/apt/applet_manager.h" -#include "core/hle/service/service.h" #include "core/global.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/service/service.h" namespace Core { class System; @@ -612,9 +611,8 @@ public: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & application_reset_prepared; + void serialize(Archive& ar, const unsigned int) { + ar& application_reset_prepared; } friend class boost::serialization::access; }; @@ -654,6 +652,6 @@ void InstallInterfaces(Core::System& system); } // namespace Service::APT namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); } diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index db49c57d8..0d6e64d30 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt_a.h" #include "common/archives.h" +#include "core/hle/service/apt/apt_a.h" namespace Service::APT { diff --git a/src/core/hle/service/apt/apt_a.h b/src/core/hle/service/apt/apt_a.h index 1b81022df..e17e2f323 100644 --- a/src/core/hle/service/apt/apt_a.h +++ b/src/core/hle/service/apt/apt_a.h @@ -11,6 +11,7 @@ namespace Service::APT { class APT_A final : public Module::APTInterface { public: explicit APT_A(std::shared_ptr apt); + private: SERVICE_SERIALIZATION(APT_A, apt, Module) }; diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index 4d151fb3d..d0e5f5526 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt_s.h" #include "common/archives.h" +#include "core/hle/service/apt/apt_s.h" namespace Service::APT { diff --git a/src/core/hle/service/apt/apt_s.h b/src/core/hle/service/apt/apt_s.h index ef1c235b0..d1dd27ff1 100644 --- a/src/core/hle/service/apt/apt_s.h +++ b/src/core/hle/service/apt/apt_s.h @@ -18,6 +18,7 @@ namespace Service::APT { class APT_S final : public Module::APTInterface { public: explicit APT_S(std::shared_ptr apt); + private: SERVICE_SERIALIZATION(APT_S, apt, Module) }; diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 7ebaf86e3..05f531a83 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt_u.h" #include "common/archives.h" +#include "core/hle/service/apt/apt_u.h" namespace Service::APT { diff --git a/src/core/hle/service/apt/apt_u.h b/src/core/hle/service/apt/apt_u.h index 79d2df651..b8a8fe205 100644 --- a/src/core/hle/service/apt/apt_u.h +++ b/src/core/hle/service/apt/apt_u.h @@ -18,6 +18,7 @@ namespace Service::APT { class APT_U final : public Module::APTInterface { public: explicit APT_U(std::shared_ptr apt); + private: SERVICE_SERIALIZATION(APT_U, apt, Module) }; diff --git a/src/core/hle/service/apt/ns_s.cpp b/src/core/hle/service/apt/ns_s.cpp index b556845d3..1f86b9a61 100644 --- a/src/core/hle/service/apt/ns_s.cpp +++ b/src/core/hle/service/apt/ns_s.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/ns_s.h" #include "common/archives.h" +#include "core/hle/service/apt/ns_s.h" namespace Service::NS { diff --git a/src/core/hle/service/apt/ns_s.h b/src/core/hle/service/apt/ns_s.h index 8f023e204..eaa0ad9d3 100644 --- a/src/core/hle/service/apt/ns_s.h +++ b/src/core/hle/service/apt/ns_s.h @@ -14,6 +14,7 @@ namespace Service::NS { class NS_S final : public Service::APT::Module::NSInterface { public: explicit NS_S(std::shared_ptr apt); + private: SERVICE_SERIALIZATION(NS_S, apt, Service::APT::Module) }; diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index 7017ce2b6..4dae148f9 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -6,9 +6,9 @@ #include #include +#include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/service/service.h" -#include "core/global.h" namespace Core { class System; @@ -964,12 +964,11 @@ public: u8 output_flag; template - void serialize(Archive& ar, const unsigned int) - { - ar & new_arrival_flag; - ar & ns_data_new_flag; - ar & ns_data_new_flag_privileged; - ar & output_flag; + void serialize(Archive& ar, const unsigned int) { + ar& new_arrival_flag; + ar& ns_data_new_flag; + ar& ns_data_new_flag_privileged; + ar& output_flag; } friend class boost::serialization::access; }; @@ -978,9 +977,8 @@ private: std::shared_ptr task_finish_event; template - void serialize(Archive& ar, const unsigned int) - { - ar & task_finish_event; + void serialize(Archive& ar, const unsigned int) { + ar& task_finish_event; } friend class boost::serialization::access; }; @@ -990,9 +988,8 @@ void InstallInterfaces(Core::System& system); } // namespace Service::BOSS namespace boost::serialization { - template - inline void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) - { - ::new(t)Service::BOSS::Module(Core::Global()); - } +template +inline void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) { + ::new (t) Service::BOSS::Module(Core::Global()); } +} // namespace boost::serialization diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp index 4e48fe8f3..802f2643a 100644 --- a/src/core/hle/service/boss/boss_p.cpp +++ b/src/core/hle/service/boss/boss_p.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/boss/boss_p.h" #include "common/archives.h" +#include "core/hle/service/boss/boss_p.h" namespace Service::BOSS { diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp index f839e9292..68a30510d 100644 --- a/src/core/hle/service/boss/boss_u.cpp +++ b/src/core/hle/service/boss/boss_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/boss/boss_u.h" #include "common/archives.h" +#include "core/hle/service/boss/boss_u.h" namespace Service::BOSS { diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index b7acd307c..6f9a81e75 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -24,11 +24,10 @@ namespace Service::CAM { template -void Module::serialize(Archive& ar, const unsigned int) -{ - ar & cameras; - ar & ports; - ar & is_camera_reload_pending; +void Module::serialize(Archive& ar, const unsigned int) { + ar& cameras; + ar& ports; + ar& is_camera_reload_pending; } SERIALIZE_IMPL(Module) diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 229c882b5..876e2e185 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -10,9 +10,9 @@ #include #include "common/common_types.h" #include "common/swap.h" +#include "core/global.h" #include "core/hle/result.h" #include "core/hle/service/service.h" -#include "core/global.h" namespace Core { class System; @@ -183,14 +183,13 @@ struct Resolution { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & width; - ar & height; - ar & crop_x0; - ar & crop_y0; - ar & crop_x1; - ar & crop_y1; + void serialize(Archive& ar, const unsigned int) { + ar& width; + ar& height; + ar& crop_x0; + ar& crop_y0; + ar& crop_x1; + ar& crop_y1; } friend class boost::serialization::access; }; @@ -755,12 +754,11 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & flip; - ar & effect; - ar & format; - ar & resolution; + void serialize(Archive& ar, const unsigned int) { + ar& flip; + ar& effect; + ar& format; + ar& resolution; } friend class boost::serialization::access; }; @@ -773,12 +771,11 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & impl; - ar & contexts; - ar & current_context; - ar & frame_rate; + void serialize(Archive& ar, const unsigned int) { + ar& impl; + ar& contexts; + ar& current_context; + ar& frame_rate; } friend class boost::serialization::access; }; @@ -818,27 +815,26 @@ private: private: template - void serialize(Archive& ar, const unsigned int) - { - ar & camera_id; - ar & is_active; - ar & is_pending_receiving; - ar & is_busy; - ar & is_receiving; - ar & is_trimming; - ar & x0; - ar & y0; - ar & x1; - ar & y1; - ar & transfer_bytes; - ar & completion_event; - ar & buffer_error_interrupt_event; - ar & vsync_interrupt_event; + void serialize(Archive& ar, const unsigned int) { + ar& camera_id; + ar& is_active; + ar& is_pending_receiving; + ar& is_busy; + ar& is_receiving; + ar& is_trimming; + ar& x0; + ar& y0; + ar& x1; + ar& y1; + ar& transfer_bytes; + ar& completion_event; + ar& buffer_error_interrupt_event; + ar& vsync_interrupt_event; // TODO: Check if this is ever needed: - //ar & capture_result; - ar & dest_process; - ar & dest; - ar & dest_size; + // ar & capture_result; + ar& dest_process; + ar& dest; + ar& dest_size; } friend class boost::serialization::access; }; @@ -864,9 +860,8 @@ void InstallInterfaces(Core::System& system); } // namespace Service::CAM namespace boost::serialization { - template - inline void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) - { - ::new(t)Service::CAM::Module(Core::Global()); - } +template +inline void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) { + ::new (t) Service::CAM::Module(Core::Global()); } +} // namespace boost::serialization diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp index a29e9db3e..e86d33115 100644 --- a/src/core/hle/service/cam/cam_c.cpp +++ b/src/core/hle/service/cam/cam_c.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_c.h" -#include "common/archives.h" namespace Service::CAM { diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp index ac477bf04..6f0c04598 100644 --- a/src/core/hle/service/cam/cam_q.cpp +++ b/src/core/hle/service/cam/cam_q.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/cam/cam_q.h" #include "common/archives.h" +#include "core/hle/service/cam/cam_q.h" namespace Service::CAM { diff --git a/src/core/hle/service/cam/cam_q.h b/src/core/hle/service/cam/cam_q.h index 33943ca21..ab901cf85 100644 --- a/src/core/hle/service/cam/cam_q.h +++ b/src/core/hle/service/cam/cam_q.h @@ -11,11 +11,11 @@ namespace Service::CAM { class CAM_Q : public ServiceFramework { public: CAM_Q(); + private: template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp index 0797ed4e1..8cfd3c1d7 100644 --- a/src/core/hle/service/cam/cam_s.cpp +++ b/src/core/hle/service/cam/cam_s.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_s.h" -#include "common/archives.h" namespace Service::CAM { diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp index 16c652a26..72a62c04e 100644 --- a/src/core/hle/service/cam/cam_u.cpp +++ b/src/core/hle/service/cam/cam_u.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_u.h" -#include "common/archives.h" namespace Service::CAM { diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index 44e4c030c..6ac5d6876 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -38,10 +38,9 @@ struct AdpcmState { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & predictor; - ar & step_index; + void serialize(Archive& ar, const unsigned int) { + ar& predictor; + ar& step_index; } friend class boost::serialization::access; }; @@ -66,24 +65,23 @@ struct Channel { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & block1_address; - ar & block2_address; - ar & block1_size; - ar & block2_size; - ar & block1_adpcm_state; - ar & block2_adpcm_state; - ar & block2_adpcm_reload; - ar & left_channel_volume; - ar & right_channel_volume; - ar & left_capture_volume; - ar & right_capture_volume; - ar & sample_rate; - ar & linear_interpolation; - ar & loop_mode; - ar & encoding; - ar & psg_duty; + void serialize(Archive& ar, const unsigned int) { + ar& block1_address; + ar& block2_address; + ar& block1_size; + ar& block2_size; + ar& block1_adpcm_state; + ar& block2_adpcm_state; + ar& block2_adpcm_reload; + ar& left_channel_volume; + ar& right_channel_volume; + ar& left_capture_volume; + ar& right_capture_volume; + ar& sample_rate; + ar& linear_interpolation; + ar& loop_mode; + ar& encoding; + ar& psg_duty; } friend class boost::serialization::access; }; @@ -258,18 +256,17 @@ private: u32 acquired_channel_mask = 0; template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); - ar & mutex; - ar & shared_memory; - ar & capture_units; - ar & channels; - ar & master_state_offset; - ar & channel_state_offset; - ar & capture_state_offset; - ar & type1_command_offset; - ar & acquired_channel_mask; + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& mutex; + ar& shared_memory; + ar& capture_units; + ar& channels; + ar& master_state_offset; + ar& channel_state_offset; + ar& capture_state_offset; + ar& type1_command_offset; + ar& acquired_channel_mask; } friend class boost::serialization::access; }; @@ -282,6 +279,6 @@ void InstallInterfaces(Core::System& system); BOOST_CLASS_EXPORT_KEY(Service::CSND::CSND_SND) namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int); } diff --git a/src/core/hle/service/dlp/dlp_clnt.cpp b/src/core/hle/service/dlp/dlp_clnt.cpp index df5b755e1..f8b315c00 100644 --- a/src/core/hle/service/dlp/dlp_clnt.cpp +++ b/src/core/hle/service/dlp/dlp_clnt.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/dlp/dlp_clnt.h" -#include "common/archives.h" SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_CLNT) diff --git a/src/core/hle/service/dlp/dlp_clnt.h b/src/core/hle/service/dlp/dlp_clnt.h index 3f9020863..835d01748 100644 --- a/src/core/hle/service/dlp/dlp_clnt.h +++ b/src/core/hle/service/dlp/dlp_clnt.h @@ -12,11 +12,11 @@ class DLP_CLNT final : public ServiceFramework { public: DLP_CLNT(); ~DLP_CLNT() = default; + private: template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/dlp/dlp_fkcl.cpp b/src/core/hle/service/dlp/dlp_fkcl.cpp index 607c211d4..948b25b67 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.cpp +++ b/src/core/hle/service/dlp/dlp_fkcl.cpp @@ -2,9 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/dlp/dlp_fkcl.h" -#include "common/archives.h" SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_FKCL) diff --git a/src/core/hle/service/dlp/dlp_fkcl.h b/src/core/hle/service/dlp/dlp_fkcl.h index ae26b6220..d778ace8b 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.h +++ b/src/core/hle/service/dlp/dlp_fkcl.h @@ -12,11 +12,11 @@ class DLP_FKCL final : public ServiceFramework { public: DLP_FKCL(); ~DLP_FKCL() = default; + private: template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/dlp/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp index 0cff2e2bc..87733b71f 100644 --- a/src/core/hle/service/dlp/dlp_srvr.cpp +++ b/src/core/hle/service/dlp/dlp_srvr.cpp @@ -2,12 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/dlp/dlp_srvr.h" -#include "common/archives.h" SERIALIZE_EXPORT_IMPL(Service::DLP::DLP_SRVR) diff --git a/src/core/hle/service/dlp/dlp_srvr.h b/src/core/hle/service/dlp/dlp_srvr.h index 6af350c8e..1f171f950 100644 --- a/src/core/hle/service/dlp/dlp_srvr.h +++ b/src/core/hle/service/dlp/dlp_srvr.h @@ -17,9 +17,8 @@ private: void IsChild(Kernel::HLERequestContext& ctx); template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h index b4c727091..90dd17f65 100644 --- a/src/core/hle/service/dsp/dsp_dsp.h +++ b/src/core/hle/service/dsp/dsp_dsp.h @@ -266,14 +266,13 @@ private: std::array, AudioCore::num_dsp_pipe> pipes = {{}}; template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); - ar & semaphore_event; - ar & preset_semaphore; - ar & interrupt_zero; - ar & interrupt_one; - ar & pipes; + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& semaphore_event; + ar& preset_semaphore; + ar& interrupt_zero; + ar& interrupt_one; + ar& pipes; } friend class boost::serialization::access; }; @@ -285,6 +284,6 @@ void InstallInterfaces(Core::System& system); BOOST_CLASS_EXPORT_KEY(Service::DSP::DSP_DSP) namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int); } diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 0efc600e8..f88ffef19 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -20,16 +20,15 @@ SERIALIZE_EXPORT_IMPL(Service::ERR::ERR_F) namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int) - { - ::new(t)Service::ERR::ERR_F(Core::Global()); - } - - template - void load_construct_data(iarchive& ar, Service::ERR::ERR_F* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int) { + ::new (t) Service::ERR::ERR_F(Core::Global()); } +template void load_construct_data(iarchive& ar, Service::ERR::ERR_F* t, + const unsigned int); +} // namespace boost::serialization + namespace Service::ERR { enum class FatalErrType : u32 { diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h index a3d0cf11e..de92fed05 100644 --- a/src/core/hle/service/err_f.h +++ b/src/core/hle/service/err_f.h @@ -36,9 +36,8 @@ private: Core::System& system; template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); } friend class boost::serialization::access; }; @@ -50,6 +49,6 @@ void InstallInterfaces(Core::System& system); BOOST_CLASS_EXPORT_KEY(Service::ERR::ERR_F) namespace boost::serialization { - template - void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int); +template +void load_construct_data(Archive& ar, Service::ERR::ERR_F* t, const unsigned int); } diff --git a/src/core/hle/service/frd/frd.h b/src/core/hle/service/frd/frd.h index 46dc96cad..1f34e61fa 100644 --- a/src/core/hle/service/frd/frd.h +++ b/src/core/hle/service/frd/frd.h @@ -21,11 +21,10 @@ struct FriendKey { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & friend_id; - ar & unknown; - ar & friend_code; + void serialize(Archive& ar, const unsigned int) { + ar& friend_id; + ar& unknown; + ar& friend_code; } friend class boost::serialization::access; }; @@ -35,9 +34,8 @@ struct MyPresence { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & unknown; + void serialize(Archive& ar, const unsigned int) { + ar& unknown; } friend class boost::serialization::access; }; @@ -157,10 +155,9 @@ private: MyPresence my_presence = {}; template - void serialize(Archive& ar, const unsigned int) - { - ar & my_friend_key; - ar & my_presence; + void serialize(Archive& ar, const unsigned int) { + ar& my_friend_key; + ar& my_presence; } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp index 6248891af..23a83a55e 100644 --- a/src/core/hle/service/frd/frd_a.cpp +++ b/src/core/hle/service/frd/frd_a.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/frd/frd_a.h" #include "common/archives.h" +#include "core/hle/service/frd/frd_a.h" SERIALIZE_EXPORT_IMPL(Service::FRD::FRD_A) diff --git a/src/core/hle/service/frd/frd_a.h b/src/core/hle/service/frd/frd_a.h index 133d40dc1..0bdd87525 100644 --- a/src/core/hle/service/frd/frd_a.h +++ b/src/core/hle/service/frd/frd_a.h @@ -11,6 +11,7 @@ namespace Service::FRD { class FRD_A final : public Module::Interface { public: explicit FRD_A(std::shared_ptr frd); + private: SERVICE_SERIALIZATION(FRD_A, frd, Module) }; diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp index ba499dd2b..d83c8ac8c 100644 --- a/src/core/hle/service/frd/frd_u.cpp +++ b/src/core/hle/service/frd/frd_u.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/frd/frd_u.h" #include "common/archives.h" +#include "core/hle/service/frd/frd_u.h" SERIALIZE_EXPORT_IMPL(Service::FRD::FRD_U) diff --git a/src/core/hle/service/frd/frd_u.h b/src/core/hle/service/frd/frd_u.h index 281334f51..e6adc37fb 100644 --- a/src/core/hle/service/frd/frd_u.h +++ b/src/core/hle/service/frd/frd_u.h @@ -11,6 +11,7 @@ namespace Service::FRD { class FRD_U final : public Module::Interface { public: explicit FRD_U(std::shared_ptr frd); + private: SERVICE_SERIALIZATION(FRD_U, frd, Module) }; diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 90dfad62f..767faf167 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -13,6 +13,7 @@ #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" +#include "core/core.h" #include "core/file_sys/archive_backend.h" #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_ncch.h" @@ -27,7 +28,6 @@ #include "core/file_sys/file_backend.h" #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" -#include "core/core.h" namespace Service::FS { diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index c001be0c5..29b47a99c 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -25,9 +25,8 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { private: template - void serialize(Archive& ar, const unsigned int) - { - ar & program_id; + void serialize(Archive& ar, const unsigned int) { + ar& program_id; } friend class boost::serialization::access; }; @@ -555,10 +554,9 @@ private: ArchiveManager& archives; template - void serialize(Archive& ar, const unsigned int) - { - ar & boost::serialization::base_object(*this); - ar & priority; + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& priority; } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index b16a4065f..d39e72aca 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include #include "common/common_types.h" #include "common/construct.h" #include "core/hle/kernel/hle_ipc.h" @@ -199,42 +199,37 @@ extern const std::array service_module_map; } // namespace Service -#define SERVICE_SERIALIZATION(T, MFIELD, TMODULE) \ - template \ - void save_construct(Archive& ar, const unsigned int file_version) const \ - { \ - ar << MFIELD; \ - } \ - \ - template \ - static void load_construct(Archive& ar, T* t, const unsigned int file_version) \ - { \ - std::shared_ptr MFIELD; \ - ar >> MFIELD; \ - ::new(t)T(MFIELD); \ - } \ - \ - template \ - void serialize(Archive& ar, const unsigned int) \ - { \ - ar & boost::serialization::base_object(*this); \ - } \ - friend class boost::serialization::access; \ +#define SERVICE_SERIALIZATION(T, MFIELD, TMODULE) \ + template \ + void save_construct(Archive& ar, const unsigned int file_version) const { \ + ar << MFIELD; \ + } \ + \ + template \ + static void load_construct(Archive& ar, T* t, const unsigned int file_version) { \ + std::shared_ptr MFIELD; \ + ar >> MFIELD; \ + ::new (t) T(MFIELD); \ + } \ + \ + template \ + void serialize(Archive& ar, const unsigned int) { \ + ar& boost::serialization::base_object(*this); \ + } \ + friend class boost::serialization::access; \ friend class ::construct_access; -#define SERVICE_CONSTRUCT(T) \ -namespace boost::serialization { \ - template \ - void load_construct_data(Archive& ar, T* t, const unsigned int); \ -} +#define SERVICE_CONSTRUCT(T) \ + namespace boost::serialization { \ + template \ + void load_construct_data(Archive& ar, T* t, const unsigned int); \ + } -#define SERVICE_CONSTRUCT_IMPL(T) \ -namespace boost::serialization { \ - template \ - void load_construct_data(Archive& ar, T* t, const unsigned int) \ - { \ - ::new(t)T(Core::Global()); \ - } \ - template \ - void load_construct_data(iarchive& ar, T* t, const unsigned int); \ -} +#define SERVICE_CONSTRUCT_IMPL(T) \ + namespace boost::serialization { \ + template \ + void load_construct_data(Archive& ar, T* t, const unsigned int) { \ + ::new (t) T(Core::Global()); \ + } \ + template void load_construct_data(iarchive & ar, T* t, const unsigned int); \ + } diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index d91732da9..659e14afb 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -9,9 +9,9 @@ #include #include #include +#include #include #include -#include #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" @@ -86,14 +86,12 @@ private: std::unordered_map registered_services_inverse; template - void save(Archive& ar, const unsigned int file_version) const - { + void save(Archive& ar, const unsigned int file_version) const { ar << registered_services; } template - void load(Archive& ar, const unsigned int file_version) - { + void load(Archive& ar, const unsigned int file_version) { ar >> registered_services; registered_services_inverse.clear(); for (const auto& pair : registered_services) { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 7264e1ec4..6a41ca957 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,9 +4,9 @@ #include #include +#include "audio_core/dsp_interface.h" #include "boost/serialization/array.hpp" #include "boost/serialization/binary_object.hpp" -#include "audio_core/dsp_interface.h" #include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" @@ -58,12 +58,11 @@ private: static_assert(sizeof(bool) == 1); friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & vram; - ar & linear_heap; - ar & new_linear_heap; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& vram; + ar& linear_heap; + ar& new_linear_heap; } }; @@ -82,19 +81,18 @@ public: AudioCore::DspInterface* dsp = nullptr; private: - friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { + template + void serialize(Archive& ar, const unsigned int file_version) { // TODO: Skip n3ds ram when not used? auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); - auto s_extra = boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); - ar & s_fcram; - ar & s_vram; - ar & s_extra; - ar & cache_marker; + auto s_extra = + boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); + ar& s_fcram; + ar& s_vram; + ar& s_extra; + ar& cache_marker; // TODO: How the hell to do page tables.. // ar & page_table_list; // ar & current_page_table; @@ -104,10 +102,9 @@ private: MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; -template -void MemorySystem::serialize(Archive & ar, const unsigned int file_version) -{ - ar & *impl.get(); +template +void MemorySystem::serialize(Archive& ar, const unsigned int file_version) { + ar&* impl.get(); } SERIALIZE_IMPL(MemorySystem) diff --git a/src/core/memory.h b/src/core/memory.h index 9c1455a80..aac57af26 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -54,12 +54,11 @@ struct SpecialRegion { u32 size; MMIORegionPointer handler; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & base; - ar & size; - ar & handler; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& base; + ar& size; + ar& handler; } }; @@ -326,8 +325,8 @@ private: std::unique_ptr impl; friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version); + template + void serialize(Archive& ar, const unsigned int file_version); }; /// Determines if the given VAddr is valid for the specified process. diff --git a/src/core/mmio.h b/src/core/mmio.h index 0a8249c9a..2e6323b49 100644 --- a/src/core/mmio.h +++ b/src/core/mmio.h @@ -36,9 +36,7 @@ public: private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - } + void serialize(Archive& ar, const unsigned int file_version) {} }; using MMIORegionPointer = std::shared_ptr; diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index e405f6729..62cad0e35 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -26,7 +26,8 @@ static std::shared_ptr MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { Core::Timing timing; Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, timing, [] {}, 0); + Kernel::KernelSystem kernel( + memory, timing, [] {}, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); @@ -238,7 +239,8 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Core::Timing timing; Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, timing, [] {}, 0); + Kernel::KernelSystem kernel( + memory, timing, [] {}, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 3a5b35236..1c633cf5c 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -645,8 +645,7 @@ void ProcessCommandList(PAddr list, u32 size) { u32* buffer = (u32*)VideoCore::g_memory->GetPhysicalPointer(list); if (Pica::g_debug_context && Pica::g_debug_context->recorder) { - Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, size, - list); + Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, size, list); } g_state.cmd_list.addr = list; diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp index 44a2fd6da..159f1df0b 100644 --- a/src/video_core/geometry_pipeline.cpp +++ b/src/video_core/geometry_pipeline.cpp @@ -37,9 +37,7 @@ public: private: template - void serialize(Archive& ar, const unsigned int file_version) - { - } + void serialize(Archive& ar, const unsigned int file_version) {} friend class boost::serialization::access; }; @@ -92,16 +90,14 @@ private: unsigned int vs_output_num; template - static void serialize_common(Class* self, Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*self); + static void serialize_common(Class* self, Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*self); ar & self->attribute_buffer; ar & self->vs_output_num; } - template - void save(Archive & ar, const unsigned int version) const - { + template + void save(Archive& ar, const unsigned int version) const { serialize_common(this, ar, version); auto buffer_idx = static_cast(buffer_cur - attribute_buffer.attr); auto buffer_size = static_cast(buffer_end - attribute_buffer.attr); @@ -109,9 +105,8 @@ private: ar << buffer_size; } - template - void load(Archive & ar, const unsigned int version) - { + template + void load(Archive& ar, const unsigned int version) { serialize_common(this, ar, version); u32 buffer_idx, buffer_size; ar >> buffer_idx; @@ -130,8 +125,7 @@ private: // value in the batch. This mode is usually used for subdivision. class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_VariablePrimitive() - : regs(g_state.regs), setup(g_state.gs) { + GeometryPipeline_VariablePrimitive() : regs(g_state.regs), setup(g_state.gs) { ASSERT(regs.pipeline.variable_primitive == 1); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -190,26 +184,23 @@ private: unsigned int vs_output_num; template - static void serialize_common(Class* self, Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*self); + static void serialize_common(Class* self, Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*self); ar & self->need_index; ar & self->main_vertex_num; ar & self->total_vertex_num; ar & self->vs_output_num; } - template - void save(Archive & ar, const unsigned int version) const - { + template + void save(Archive& ar, const unsigned int version) const { serialize_common(this, ar, version); auto buffer_idx = static_cast(buffer_cur - setup.uniforms.f); ar << buffer_idx; } - template - void load(Archive & ar, const unsigned int version) - { + template + void load(Archive& ar, const unsigned int version) { serialize_common(this, ar, version); u32 buffer_idx; ar >> buffer_idx; @@ -226,8 +217,7 @@ private: // particle system. class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_FixedPrimitive() - : regs(g_state.regs), setup(g_state.gs) { + GeometryPipeline_FixedPrimitive() : regs(g_state.regs), setup(g_state.gs) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -267,15 +257,13 @@ private: unsigned int vs_output_num; template - static void serialize_common(Class* self, Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*self); + static void serialize_common(Class* self, Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*self); ar & self->vs_output_num; } - template - void save(Archive & ar, const unsigned int version) const - { + template + void save(Archive& ar, const unsigned int version) const { serialize_common(this, ar, version); auto buffer_offset = static_cast(buffer_begin - setup.uniforms.f); auto buffer_idx = static_cast(buffer_cur - setup.uniforms.f); @@ -285,9 +273,8 @@ private: ar << buffer_size; } - template - void load(Archive & ar, const unsigned int version) - { + template + void load(Archive& ar, const unsigned int version) { serialize_common(this, ar, version); u32 buffer_offset, buffer_idx, buffer_size; ar >> buffer_offset; @@ -385,7 +372,7 @@ void GeometryPipeline::SubmitVertex(const Shader::AttributeBuffer& input) { template void GeometryPipeline::serialize(Archive& ar, const unsigned int version) { // vertex_handler and shader_engine are always set to the same value - ar & backend; + ar& backend; } } // namespace Pica diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp index 0b5aaa682..5e0c2d480 100644 --- a/src/video_core/pica.cpp +++ b/src/video_core/pica.cpp @@ -3,17 +3,19 @@ // Refer to the license.txt file included. #include +#include "core/global.h" #include "video_core/geometry_pipeline.h" #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" -#include "core/global.h" namespace Core { - template <> - Pica::State& Global() { return Pica::g_state; } +template <> +Pica::State& Global() { + return Pica::g_state; } +} // namespace Core namespace Pica { diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 30cef3496..4e5a5f16b 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -9,23 +9,21 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/vector_math.h" -#include "video_core/video_core.h" #include "video_core/geometry_pipeline.h" #include "video_core/primitive_assembly.h" #include "video_core/regs.h" #include "video_core/shader/shader.h" +#include "video_core/video_core.h" // Boost::serialization doesn't like union types for some reason, // so we need to mark arrays of union values with a special serialization method -template -struct UnionArray : public std::array -{ +template +struct UnionArray : public std::array { private: - template - void serialize(Archive& ar, const unsigned int) - { + template + void serialize(Archive& ar, const unsigned int) { static_assert(sizeof(Value) == sizeof(u32)); - ar & *static_cast(static_cast(this->data())); + ar&* static_cast(static_cast(this->data())); } friend class boost::serialization::access; }; @@ -99,14 +97,13 @@ struct State { private: friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & noise_table; - ar & color_map_table; - ar & alpha_map_table; - ar & color_table; - ar & color_diff_table; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& noise_table; + ar& color_map_table; + ar& alpha_map_table; + ar& color_table; + ar& color_diff_table; } } proctex; @@ -131,10 +128,9 @@ struct State { return neg_difference ? -diff : diff; } - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & raw; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& raw; } }; @@ -180,12 +176,11 @@ struct State { private: friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & input_vertex; - ar & current_attribute; - ar & reset_geometry_pipeline; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& input_vertex; + ar& current_attribute; + ar& reset_geometry_pipeline; } } immediate; @@ -210,42 +205,38 @@ struct State { u32 default_attr_write_buffer[3]{}; private: - friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & regs.reg_array; - ar & vs; - ar & gs; - ar & input_default_attributes; - ar & proctex; - ar & lighting.luts; - ar & fog.lut; - ar & cmd_list.addr; - ar & cmd_list.length; - ar & immediate; - ar & gs_unit; - ar & geometry_pipeline; - ar & primitive_assembler; - ar & vs_float_regs_counter; - ar & vs_uniform_write_buffer; - ar & gs_float_regs_counter; - ar & gs_uniform_write_buffer; - ar & default_attr_counter; - ar & default_attr_write_buffer; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& regs.reg_array; + ar& vs; + ar& gs; + ar& input_default_attributes; + ar& proctex; + ar& lighting.luts; + ar& fog.lut; + ar& cmd_list.addr; + ar& cmd_list.length; + ar& immediate; + ar& gs_unit; + ar& geometry_pipeline; + ar& primitive_assembler; + ar& vs_float_regs_counter; + ar& vs_uniform_write_buffer; + ar& gs_float_regs_counter; + ar& gs_uniform_write_buffer; + ar& default_attr_counter; + ar& default_attr_write_buffer; boost::serialization::split_member(ar, *this, file_version); } - template - void save(Archive & ar, const unsigned int file_version) const - { + template + void save(Archive& ar, const unsigned int file_version) const { ar << static_cast(cmd_list.current_ptr - cmd_list.head_ptr); } - template - void load(Archive & ar, const unsigned int file_version) - { + template + void load(Archive& ar, const unsigned int file_version) { u32 offset{}; ar >> offset; cmd_list.head_ptr = (u32*)VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr); diff --git a/src/video_core/pica_types.h b/src/video_core/pica_types.h index bef256e13..33012c259 100644 --- a/src/video_core/pica_types.h +++ b/src/video_core/pica_types.h @@ -143,10 +143,9 @@ private: float value; friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & value; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& value; } }; diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index 1545a6b4c..d6547dddd 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h @@ -6,7 +6,9 @@ #include #include "video_core/regs_pipeline.h" -namespace boost::serialization { class access; } +namespace boost::serialization { +class access; +} namespace Pica { @@ -65,13 +67,12 @@ private: bool winding = false; template - void serialize(Archive& ar, const unsigned int version) - { - ar & topology; - ar & buffer_index; - ar & buffer; - ar & strip_ready; - ar & winding; + void serialize(Archive& ar, const unsigned int version) { + ar& topology; + ar& buffer_index; + ar& buffer; + ar& strip_ready; + ar& winding; } friend class boost::serialization::access; }; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index f20e08d98..a6e42b3bf 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -8,15 +8,15 @@ #include #include #include -#include #include #include +#include #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/hash.h" -#include "common/vector_math.h" #include "common/pod.h" +#include "common/vector_math.h" #include "video_core/pica_types.h" #include "video_core/regs_rasterizer.h" #include "video_core/regs_shader.h" @@ -38,9 +38,8 @@ struct AttributeBuffer { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & attr; + void serialize(Archive& ar, const unsigned int file_version) { + ar& attr; } }; @@ -107,13 +106,12 @@ struct GSEmitter { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & buffer; - ar & vertex_id; - ar & prim_emit; - ar & winding; - ar & output_mask; + void serialize(Archive& ar, const unsigned int file_version) { + ar& buffer; + ar& vertex_id; + ar& prim_emit; + ar& winding; + ar& output_mask; // Handlers are ignored because they're constant } }; @@ -137,11 +135,10 @@ struct UnitState { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & input; - ar & temporary; - ar & output; + void serialize(Archive& ar, const unsigned int file_version) { + ar& input; + ar& temporary; + ar& output; } } registers; static_assert(std::is_pod::value, "Structure is not POD"); @@ -199,11 +196,10 @@ struct UnitState { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & registers; - ar & conditional_code; - ar & address_registers; + void serialize(Archive& ar, const unsigned int file_version) { + ar& registers; + ar& conditional_code; + ar& address_registers; // emitter_ptr is only set by GSUnitState and is serialized there } }; @@ -223,10 +219,9 @@ struct GSUnitState : public UnitState { private: friend class boost::serialization::access; template - void serialize(Archive& ar, const unsigned int file_version) - { - ar & boost::serialization::base_object(*this); - ar & emitter; + void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); + ar& emitter; } }; @@ -252,12 +247,11 @@ struct Uniforms { private: friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & f; - ar & b; - ar & i; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& f; + ar& b; + ar& i; } }; @@ -305,16 +299,15 @@ private: u64 swizzle_data_hash = 0xDEADC0DE; friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int file_version) - { - ar & uniforms; - ar & program_code; - ar & swizzle_data; - ar & program_code_hash_dirty; - ar & swizzle_data_hash_dirty; - ar & program_code_hash; - ar & swizzle_data_hash; + template + void serialize(Archive& ar, const unsigned int file_version) { + ar& uniforms; + ar& program_code; + ar& swizzle_data; + ar& program_code_hash_dirty; + ar& swizzle_data_hash_dirty; + ar& program_code_hash; + ar& swizzle_data_hash; } }; diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 5bc1e8702..a89b41e96 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -87,18 +87,15 @@ u16 GetResolutionScaleFactor() { } } -void Save(std::ostream &stream) -{ +void Save(std::ostream& stream) { oarchive oa{stream}; - oa & Pica::g_state; + oa& Pica::g_state; } -void Load(std::istream &stream) -{ +void Load(std::istream& stream) { iarchive ia{stream}; - ia & Pica::g_state; + ia& Pica::g_state; // TODO: Flush/reset things - } } // namespace VideoCore diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 1ec69f802..10b0d39b6 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include #include #include "core/frontend/emu_window.h" @@ -62,7 +62,7 @@ void RequestScreenshot(void* data, std::function callback, u16 GetResolutionScaleFactor(); -void Save(std::ostream &stream); -void Load(std::istream &stream); +void Save(std::ostream& stream); +void Load(std::istream& stream); } // namespace VideoCore From d6862c2fca114c23be7a1f98b800d5b360d731a8 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 27 Dec 2019 22:45:00 +0000 Subject: [PATCH 034/129] Some CI fixes --- src/core/core.cpp | 4 ++-- src/tests/core/hle/kernel/hle_ipc.cpp | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 6812a9474..5b9b4fca0 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -213,8 +213,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique( - *memory, *timing, [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique(*memory, *timing, + [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 62cad0e35..e405f6729 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -26,8 +26,7 @@ static std::shared_ptr MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { Core::Timing timing; Memory::MemorySystem memory; - Kernel::KernelSystem kernel( - memory, timing, [] {}, 0); + Kernel::KernelSystem kernel(memory, timing, [] {}, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); @@ -239,8 +238,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Core::Timing timing; Memory::MemorySystem memory; - Kernel::KernelSystem kernel( - memory, timing, [] {}, 0); + Kernel::KernelSystem kernel(memory, timing, [] {}, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); From c7106e232f1d042c6ba0a129b68e7e0e563d63ef Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 28 Dec 2019 13:53:12 +0000 Subject: [PATCH 035/129] Fix a bug on mingw --- externals/boost | 2 +- src/core/hle/service/apt/applet_manager.cpp | 2 ++ src/core/hle/service/apt/applet_manager.h | 14 +++++--------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/externals/boost b/externals/boost index 55725b779..1c857c041 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 55725b7796c7faa0a4af869e412d0410bd47612d +Subproject commit 1c857c04195db89c66c347ddfad93a7f3666f2d3 diff --git a/src/core/hle/service/apt/applet_manager.cpp b/src/core/hle/service/apt/applet_manager.cpp index 8a24595ff..6612a720e 100644 --- a/src/core/hle/service/apt/applet_manager.cpp +++ b/src/core/hle/service/apt/applet_manager.cpp @@ -10,6 +10,8 @@ #include "core/hle/service/apt/ns.h" #include "core/hle/service/cfg/cfg.h" +SERVICE_CONSTRUCT_IMPL(Service::APT::AppletManager) + namespace Service::APT { enum class AppletPos { Application = 0, Library = 1, System = 2, SysLibrary = 3, Resident = 4 }; diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index e799c92d2..0f28e57c8 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -6,10 +6,10 @@ #include #include -#include #include #include -#include "common/serialization/optional.h" +#include +#include #include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" @@ -193,7 +193,8 @@ public: private: /// Parameter data to be returned in the next call to Glance/ReceiveParameter. - std::optional next_parameter; + // NOTE: A bug in gcc prevents serializing std::optional + boost::optional next_parameter; static constexpr std::size_t NumAppletSlot = 4; @@ -268,9 +269,4 @@ private: } // namespace Service::APT -namespace boost::serialization { -template -inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) { - ::new (t) Service::APT::AppletManager(Core::Global()); -} -} // namespace boost::serialization +SERVICE_CONSTRUCT(Service::APT::AppletManager) From d041901a3002b80eafc8a4b2ab955f8f6b23ecda Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 28 Dec 2019 23:13:39 +0000 Subject: [PATCH 036/129] Some more CI fixes --- CMakeLists.txt | 4 +- TODO | 3 +- src/CMakeLists.txt | 8 ++- src/common/CMakeLists.txt | 1 - src/common/serialization/optional.h | 76 ----------------------- src/core/hle/service/apt/applet_manager.h | 2 +- 6 files changed, 11 insertions(+), 83 deletions(-) delete mode 100644 src/common/serialization/optional.h diff --git a/CMakeLists.txt b/CMakeLists.txt index df8081f05..ac05c91c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,9 +126,9 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) add_library(boost_libs INTERFACE) -find_package(Boost 1.66.0 QUIET) +find_package(Boost 1.70.0 QUIET EXACT) if (NOT Boost_FOUND) - message(STATUS "Boost 1.66.0 or newer not found, falling back to externals") + message(STATUS "Boost 1.70.0 not found, falling back to externals") set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost") set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") diff --git a/TODO b/TODO index be118365d..45e6ae3b7 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,8 @@ ✔ Memory @done(19-08-13 15:41) ☐ Page tables ☐ Skip N3DS RAM if unused -☐ DSP +✔ DSP @done(19-12-28 16:57) + Memory only ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) ✔ Fix or ignore inverse map @done(19-12-23 12:46) ☐ App loader diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a4c39f17..c13337efe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,7 +33,6 @@ if (MSVC) # /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null add_compile_options( /W3 - /MP /Zi /Zo /permissive- @@ -42,8 +41,13 @@ if (MSVC) /volatile:iso /Zc:externConstexpr /Zc:inline - /Zc:throwingNew ) + if (CMAKE_C_COMPILER_ID MATCHES "MSVC") + add_compile_options( + /MP + /Zc:throwingNew + ) + endif() # /GS- - No stack buffer overflow checks add_compile_options("$<$:/GS->") diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index ac745d868..39ddffbcc 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -96,7 +96,6 @@ add_library(common STATIC serialization/boost_discrete_interval.hpp serialization/boost_flat_set.h serialization/boost_vector.hpp - serialization/optional.h string_util.cpp string_util.h swap.h diff --git a/src/common/serialization/optional.h b/src/common/serialization/optional.h deleted file mode 100644 index 4e794058e..000000000 --- a/src/common/serialization/optional.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -namespace boost { -namespace serialization { - -template -void save(Archive& ar, const std::optional& t, const unsigned int /*version*/ -) { -// It is an inherent limitation to the serialization of optional.hpp -// that the underlying type must be either a pointer or must have a -// default constructor. It's possible that this could change sometime -// in the future, but for now, one will have to work around it. This can -// be done by serialization the optional as optional -#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - BOOST_STATIC_ASSERT(boost::serialization::detail::is_default_constructible::value || - boost::is_pointer::value); -#endif - const bool tflag = t.has_value(); - ar << boost::serialization::make_nvp("initialized", tflag); - if (tflag) { - ar << boost::serialization::make_nvp("value", *t); - } -} - -template -void load(Archive& ar, std::optional& t, const unsigned int version) { - bool tflag; - ar >> boost::serialization::make_nvp("initialized", tflag); - if (!tflag) { - t.reset(); - return; - } - - if (0 == version) { - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version(ar.get_library_version()); - if (boost::archive::library_version_type(3) < library_version) { - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - } - if (!t.has_value()) - t = T(); - ar >> boost::serialization::make_nvp("value", *t); -} - -template -void serialize(Archive& ar, std::optional& t, const unsigned int version) { - boost::serialization::split_free(ar, t, version); -} - -template -struct version> { - BOOST_STATIC_CONSTANT(int, value = 1); -}; - -} // namespace serialization -} // namespace boost diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 0f28e57c8..7260fb2d3 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" From a0ac302a93aad8a537fb31011c2f7abe1b95f052 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 28 Dec 2019 23:36:12 +0000 Subject: [PATCH 037/129] Definitely disable using system boost if version doesn't match --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac05c91c7..163b8e7c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,7 @@ if (NOT Boost_FOUND) set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost") set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") - set(Boost_NO_SYSTEM_PATHS OFF) + set(Boost_NO_SYSTEM_PATHS ON) add_definitions( -DBOOST_ALL_NO_LIB ) find_package(Boost QUIET REQUIRED) From 9877bf7d487ab8b7d1ac1110a2653c91a8e234be Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 00:51:06 +0000 Subject: [PATCH 038/129] Change how the boost target works; disable external warnings in MSVC --- CMakeLists.txt | 35 ++++++++++++++++------------------- externals/CMakeLists.txt | 19 +++++++++++++++++++ src/CMakeLists.txt | 6 +++++- src/core/CMakeLists.txt | 2 +- src/video_core/CMakeLists.txt | 2 +- 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 163b8e7c2..0d42aba93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ # CMake 3.8 required for 17 to be a valid value for CXX_STANDARD cmake_minimum_required(VERSION 3.8) +cmake_policy(SET CMP0092 NEW) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") include(DownloadExternals) @@ -35,6 +36,8 @@ CMAKE_DEPENDENT_OPTION(ENABLE_MF "Use Media Foundation decoder (preferred over F CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ON "MINGW" OFF) +option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF) + if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit) message(STATUS "Copying pre-commit hook") file(COPY hooks/pre-commit @@ -124,25 +127,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) # System imported libraries # ====================== -add_library(boost_libs INTERFACE) - -find_package(Boost 1.70.0 QUIET EXACT) -if (NOT Boost_FOUND) - message(STATUS "Boost 1.70.0 not found, falling back to externals") - - set(BOOST_ROOT "${PROJECT_SOURCE_DIR}/externals/boost") - set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") - set(Boost_NO_SYSTEM_PATHS ON) - add_definitions( -DBOOST_ALL_NO_LIB ) - find_package(Boost QUIET REQUIRED) - - # Boost external libraries - file(GLOB boost_serialization_SRC "externals/boost/libs/serialization/src/*.cpp") - add_library(boost_serialization STATIC ${boost_serialization_SRC}) - target_link_libraries(boost_serialization PUBLIC Boost::boost) - target_link_libraries(boost_libs INTERFACE boost_serialization) -endif() - # Prefer the -pthread flag on Linux. set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) @@ -340,8 +324,21 @@ git_describe(GIT_DESC --always --long --dirty) git_branch_name(GIT_BRANCH) get_timestamp(BUILD_DATE) +if (NOT USE_SYSTEM_BOOST) + add_definitions( -DBOOST_ALL_NO_LIB ) +endif() + enable_testing() add_subdirectory(externals) + +# Boost +if (USE_SYSTEM_BOOST) + find_package(Boost 1.70.0 QUIET REQUIRED) +else() + add_library(Boost::boost ALIAS boost) + add_library(Boost::serialization ALIAS boost_serialization) +endif() + add_subdirectory(src) add_subdirectory(dist/installer) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 63159a52b..47a92794c 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -1,9 +1,28 @@ # Definitions for all external bundled libraries +# Suppress warnings from external libraries +if (CMAKE_C_COMPILER_ID MATCHES "MSVC") + add_compile_options(/W0) +endif() + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules) include(DownloadExternals) include(ExternalProject) +# Boost +set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost") +set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost") +set(Boost_NO_SYSTEM_PATHS ON) +add_library(boost INTERFACE) +target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR}) + +# Boost::serialization +file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp") +add_library(boost_serialization STATIC ${boost_serialization_SRC}) +target_link_libraries(boost_serialization PUBLIC boost) + +# Add additional boost libs here; remember to ALIAS them in the root CMakeLists! + # Catch add_library(catch-single-include INTERFACE) target_include_directories(catch-single-include INTERFACE catch/single_include) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c13337efe..d46641570 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,7 +37,7 @@ if (MSVC) /Zo /permissive- /EHsc - /std:c++latest + /std:c++17 /volatile:iso /Zc:externConstexpr /Zc:inline @@ -46,6 +46,10 @@ if (MSVC) add_compile_options( /MP /Zc:throwingNew + /experimental:external + /external:I "${CMAKE_SOURCE_DIR}/externals" + /external:anglebrackets + /external:W0 ) endif() diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9ed9a856d..c6908c59a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -466,7 +466,7 @@ endif() create_target_directory_groups(core) target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core) -target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives boost_libs) +target_link_libraries(core PUBLIC Boost::boost PRIVATE cryptopp fmt open_source_archives Boost::serialization) if (ENABLE_WEB_SERVICE) target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE) target_link_libraries(core PRIVATE web_service) diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 8dbf5d8e0..17e344aa4 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -94,7 +94,7 @@ endif() create_target_directory_groups(video_core) target_link_libraries(video_core PUBLIC common core) -target_link_libraries(video_core PRIVATE glad nihstro-headers boost_libs) +target_link_libraries(video_core PRIVATE glad nihstro-headers Boost::serialization) if (ARCHITECTURE_x86_64) target_link_libraries(video_core PUBLIC xbyak) From 754f63af1a1f027fbfd213c190b937f66dadf89f Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 10:23:20 +0000 Subject: [PATCH 039/129] Don't require cmake 3.15 --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d42aba93..f986a39af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ # CMake 3.8 required for 17 to be a valid value for CXX_STANDARD cmake_minimum_required(VERSION 3.8) -cmake_policy(SET CMP0092 NEW) +if (${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.15) + cmake_policy(SET CMP0092 NEW) +endif () list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules") include(DownloadExternals) From 30494c06a4c8f4277a6919869975e78b001092fd Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 12:45:22 +0000 Subject: [PATCH 040/129] Serialize GSP service --- TODO | 3 ++- src/core/hle/service/gsp/gsp.cpp | 2 +- src/core/hle/service/gsp/gsp_gpu.cpp | 5 +++++ src/core/hle/service/gsp/gsp_gpu.h | 24 ++++++++++++++++++++++++ src/core/hle/service/gsp/gsp_lcd.cpp | 3 +++ src/core/hle/service/gsp/gsp_lcd.h | 2 ++ 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 45e6ae3b7..fa627b214 100644 --- a/TODO +++ b/TODO @@ -81,7 +81,8 @@ ✔ ERR @done(19-12-26 18:14) ✔ FRD @done(19-12-26 19:09) ✔ FS @done(19-12-27 11:46) - ☐ GSP + ✔ GSP @done(19-12-30 12:45) + ☐ Fix the global weak_ptr to gsp ☐ HID ☐ HTTP ☐ IR diff --git a/src/core/hle/service/gsp/gsp.cpp b/src/core/hle/service/gsp/gsp.cpp index 4291b9971..3d3f497b2 100644 --- a/src/core/hle/service/gsp/gsp.cpp +++ b/src/core/hle/service/gsp/gsp.cpp @@ -10,7 +10,7 @@ namespace Service::GSP { -static std::weak_ptr gsp_gpu; +static std::weak_ptr gsp_gpu; // TODO: Fix this for the love of god void SignalInterrupt(InterruptId interrupt_id) { auto gpu = gsp_gpu.lock(); diff --git a/src/core/hle/service/gsp/gsp_gpu.cpp b/src/core/hle/service/gsp/gsp_gpu.cpp index 33558fe10..78d84499b 100644 --- a/src/core/hle/service/gsp/gsp_gpu.cpp +++ b/src/core/hle/service/gsp/gsp_gpu.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/bit_field.h" #include "common/microprofile.h" #include "common/swap.h" @@ -21,6 +22,10 @@ #include "video_core/debug_utils/debug_utils.h" #include "video_core/gpu_debugger.h" +SERIALIZE_EXPORT_IMPL(Service::GSP::SessionData) +SERIALIZE_EXPORT_IMPL(Service::GSP::GSP_GPU) +SERVICE_CONSTRUCT_IMPL(Service::GSP::GSP_GPU) + // Main graphics debugger object - TODO: Here is probably not the best place for this GraphicsDebugger g_debugger; diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index 8b43b9cea..d1f2c0742 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -199,6 +199,16 @@ public: u32 thread_id; /// Whether RegisterInterruptRelayQueue was called for this session bool registered = false; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& gsp; + ar& interrupt_event; + ar& thread_id; + ar& registered; + } + friend class boost::serialization::access; }; class GSP_GPU final : public ServiceFramework { @@ -431,8 +441,22 @@ private: std::array used_thread_ids = {false, false, false, false}; friend class SessionData; + + template + void serialize(Archive& ar, const unsigned int) { + ar& shared_memory; + ar& active_thread_id; + ar& first_initialization; + ar& used_thread_ids; + } + + friend class boost::serialization::access; }; ResultCode SetBufferSwap(u32 screen_id, const FrameBufferInfo& info); } // namespace Service::GSP + +BOOST_CLASS_EXPORT_KEY(Service::GSP::SessionData) +BOOST_CLASS_EXPORT_KEY(Service::GSP::GSP_GPU) +SERVICE_CONSTRUCT(Service::GSP::GSP_GPU) diff --git a/src/core/hle/service/gsp/gsp_lcd.cpp b/src/core/hle/service/gsp/gsp_lcd.cpp index d795b8716..67a2e7628 100644 --- a/src/core/hle/service/gsp/gsp_lcd.cpp +++ b/src/core/hle/service/gsp/gsp_lcd.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/gsp/gsp_lcd.h" +SERIALIZE_EXPORT_IMPL(Service::GSP::GSP_LCD) + namespace Service::GSP { GSP_LCD::GSP_LCD() : ServiceFramework("gsp::Lcd") { diff --git a/src/core/hle/service/gsp/gsp_lcd.h b/src/core/hle/service/gsp/gsp_lcd.h index 24e57fb42..781d9dba8 100644 --- a/src/core/hle/service/gsp/gsp_lcd.h +++ b/src/core/hle/service/gsp/gsp_lcd.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::GSP + +BOOST_CLASS_EXPORT_KEY(Service::GSP::GSP_LCD) From 74361fa3fbed7ab4669c59e84619fda501180ece Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 14:46:35 +0000 Subject: [PATCH 041/129] Serialize HID service --- TODO | 2 +- src/core/hle/service/hid/hid.cpp | 25 +++++++++++++++++++++++++ src/core/hle/service/hid/hid.h | 9 ++++++++- src/core/hle/service/hid/hid_spvr.cpp | 3 +++ src/core/hle/service/hid/hid_spvr.h | 5 +++++ src/core/hle/service/hid/hid_user.cpp | 3 +++ src/core/hle/service/hid/hid_user.h | 5 +++++ 7 files changed, 50 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index fa627b214..51cbc627c 100644 --- a/TODO +++ b/TODO @@ -83,7 +83,7 @@ ✔ FS @done(19-12-27 11:46) ✔ GSP @done(19-12-30 12:45) ☐ Fix the global weak_ptr to gsp - ☐ HID + ✔ HID @done(19-12-30 14:46) ☐ HTTP ☐ IR ☐ LDR_RO diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ded1809b1..f20cebca7 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/logging/log.h" #include "core/3ds.h" #include "core/core.h" @@ -20,8 +21,32 @@ #include "core/movie.h" #include "video_core/video_core.h" +SERVICE_CONSTRUCT_IMPL(Service::HID::Module) +SERIALIZE_EXPORT_IMPL(Service::HID::Module) + namespace Service::HID { +template +void Module::serialize(Archive& ar, const unsigned int) { + ar& shared_mem; + ar& event_pad_or_touch_1; + ar& event_pad_or_touch_2; + ar& event_accelerometer; + ar& event_gyroscope; + ar& event_debug_pad; + ar& next_pad_index; + ar& next_touch_index; + ar& next_accelerometer_index; + ar& next_gyroscope_index; + ar& enable_accelerometer_count; + ar& enable_gyroscope_count; + ReloadInputDevices(); + // Pad state not needed as it's always updated + // Update events are set in the constructor + // Devices are set from the implementation (and are stateless afaik) +} +SERIALIZE_IMPL(Module) + // Updating period for each HID device. These empirical values are measured from a 11.2 3DS. constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234; constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE_ARM11 / 104; diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 8d217f835..e34c1186a 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -294,7 +294,7 @@ public: */ void GetGyroscopeLowCalibrateParam(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr hid; }; @@ -342,9 +342,16 @@ private: std::unique_ptr circle_pad; std::unique_ptr motion_device; std::unique_ptr touch_device; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; std::shared_ptr GetModule(Core::System& system); void InstallInterfaces(Core::System& system); } // namespace Service::HID + +SERVICE_CONSTRUCT(Service::HID::Module) +BOOST_CLASS_EXPORT_KEY(Service::HID::Module) diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp index 8371a6169..87791f073 100644 --- a/src/core/hle/service/hid/hid_spvr.cpp +++ b/src/core/hle/service/hid/hid_spvr.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/hid/hid_spvr.h" +SERIALIZE_EXPORT_IMPL(Service::HID::Spvr) + namespace Service::HID { Spvr::Spvr(std::shared_ptr hid) : Module::Interface(std::move(hid), "hid:SPVR", 6) { diff --git a/src/core/hle/service/hid/hid_spvr.h b/src/core/hle/service/hid/hid_spvr.h index e2346dda5..a49101dc3 100644 --- a/src/core/hle/service/hid/hid_spvr.h +++ b/src/core/hle/service/hid/hid_spvr.h @@ -11,6 +11,11 @@ namespace Service::HID { class Spvr final : public Module::Interface { public: explicit Spvr(std::shared_ptr hid); +private: + SERVICE_SERIALIZATION(Spvr, hid, Module) }; } // namespace Service::HID + +BOOST_CLASS_EXPORT_KEY(Service::HID::Spvr) +BOOST_SERIALIZATION_CONSTRUCT(Service::HID::Spvr) diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp index 129b3fd02..97ce8f111 100644 --- a/src/core/hle/service/hid/hid_user.cpp +++ b/src/core/hle/service/hid/hid_user.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/hid/hid_user.h" +SERIALIZE_EXPORT_IMPL(Service::HID::User) + namespace Service::HID { User::User(std::shared_ptr hid) : Module::Interface(std::move(hid), "hid:USER", 6) { diff --git a/src/core/hle/service/hid/hid_user.h b/src/core/hle/service/hid/hid_user.h index 813f09504..6fd9803c6 100644 --- a/src/core/hle/service/hid/hid_user.h +++ b/src/core/hle/service/hid/hid_user.h @@ -14,6 +14,11 @@ namespace Service::HID { class User final : public Module::Interface { public: explicit User(std::shared_ptr hid); +private: + SERVICE_SERIALIZATION(User, hid, Module) }; } // namespace Service::HID + +BOOST_CLASS_EXPORT_KEY(Service::HID::User) +BOOST_SERIALIZATION_CONSTRUCT(Service::HID::User) From 8bd3e8cd27363dda33871baad57f204cc348bd43 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 15:20:13 +0000 Subject: [PATCH 042/129] Serialize HTTP service --- TODO | 2 +- externals/boost | 2 +- src/core/hle/service/http_c.cpp | 4 + src/core/hle/service/http_c.h | 128 +++++++++++++++++++++++++++++++- 4 files changed, 130 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 51cbc627c..f72330fd1 100644 --- a/TODO +++ b/TODO @@ -84,7 +84,7 @@ ✔ GSP @done(19-12-30 12:45) ☐ Fix the global weak_ptr to gsp ✔ HID @done(19-12-30 14:46) - ☐ HTTP + ✔ HTTP @done(19-12-30 15:18) ☐ IR ☐ LDR_RO ☐ MIC diff --git a/externals/boost b/externals/boost index 1c857c041..65dc954e9 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 1c857c04195db89c66c347ddfad93a7f3666f2d3 +Subproject commit 65dc954e93b22870b8423701e225147c75e3b31b diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index 221f3cc20..768dd3bd8 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "core/core.h" #include "core/file_sys/archive_ncch.h" #include "core/file_sys/file_backend.h" @@ -14,6 +15,9 @@ #include "core/hle/service/http_c.h" #include "core/hw/aes/key.h" +SERIALIZE_EXPORT_IMPL(Service::HTTP::HTTP_C) +SERIALIZE_EXPORT_IMPL(Service::HTTP::SessionData) + namespace Service::HTTP { namespace ErrCodes { diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h index 91a455820..a3aa62ae0 100644 --- a/src/core/hle/service/http_c.h +++ b/src/core/hle/service/http_c.h @@ -5,10 +5,16 @@ #pragma once #include -#include #include #include #include +#include +#include +#include +#include +#include +#include +#include #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/service.h" @@ -50,6 +56,17 @@ struct ClientCertContext { u8 cert_id; std::vector certificate; std::vector private_key; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& handle; + ar& session_id; + ar& cert_id; + ar& certificate; + ar& private_key; + } + friend class boost::serialization::access; }; /// Represents a root certificate chain, it contains a list of DER-encoded certificates for @@ -61,12 +78,30 @@ struct RootCertChain { Handle handle; u32 session_id; std::vector certificate; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& handle; + ar& session_id; + ar& certificate; + } + friend class boost::serialization::access; }; using Handle = u32; Handle handle; u32 session_id; std::vector certificates; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& handle; + ar& session_id; + ar& certificates; + } + friend class boost::serialization::access; }; /// Represents an HTTP context. @@ -86,30 +121,74 @@ public: std::string username; std::string password; u16 port; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& url; + ar& username; + ar& password; + ar& port; + } + friend class boost::serialization::access; }; struct BasicAuth { std::string username; std::string password; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& username; + ar& password; + } + friend class boost::serialization::access; }; struct RequestHeader { RequestHeader(std::string name, std::string value) : name(name), value(value){}; std::string name; std::string value; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& name; + ar& value; + } + friend class boost::serialization::access; }; struct PostData { // TODO(Subv): Support Binary and Raw POST elements. PostData(std::string name, std::string value) : name(name), value(value){}; + PostData() = default; std::string name; std::string value; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& name; + ar& value; + } + friend class boost::serialization::access; }; struct SSLConfig { u32 options; std::weak_ptr client_cert_ctx; std::weak_ptr root_ca_chain; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& options; + ar& client_cert_ctx; + ar& root_ca_chain; + } + friend class boost::serialization::access; }; Handle handle; @@ -117,18 +196,35 @@ public: std::string url; RequestMethod method; RequestState state = RequestState::NotStarted; - std::optional proxy; - std::optional basic_auth; + boost::optional proxy; + boost::optional basic_auth; SSLConfig ssl_config{}; u32 socket_buffer_size; std::vector headers; std::vector post_data; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& handle; + ar& session_id; + ar& url; + ar& method; + ar& state; + ar& proxy; + ar& basic_auth; + ar& ssl_config; + ar& socket_buffer_size; + ar& headers; + ar& post_data; + } + friend class boost::serialization::access; }; struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { /// The HTTP context that is currently bound to this session, this can be empty if no context /// has been bound. Certain commands can only be called on a session with a bound context. - std::optional current_http_context; + boost::optional current_http_context; u32 session_id; @@ -140,6 +236,17 @@ struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { /// Whether this session has been initialized in some way, be it via Initialize or /// InitializeConnectionSession. bool initialized = false; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& current_http_context; + ar& session_id; + ar& num_http_contexts; + ar& num_client_certs; + ar& initialized; + } + friend class boost::serialization::access; }; class HTTP_C final : public ServiceFramework { @@ -326,8 +433,21 @@ private: std::vector private_key; bool init = false; } ClCertA; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& ClCertA.certificate; + ar& ClCertA.private_key; + ar& ClCertA.init; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::HTTP + +BOOST_CLASS_EXPORT_KEY(Service::HTTP::HTTP_C) +BOOST_CLASS_EXPORT_KEY(Service::HTTP::SessionData) From eb67167b7c9b9262b0c6ce7b5c99732d228a3f8d Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 16:07:03 +0000 Subject: [PATCH 043/129] Serialize IR service --- TODO | 2 +- src/core/hle/service/ir/extra_hid.h | 12 +++++++ src/core/hle/service/ir/ir_user.cpp | 51 ++++++++++++++++++++++++----- src/core/hle/service/ir/ir_user.h | 9 ++++- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index f72330fd1..b679a5168 100644 --- a/TODO +++ b/TODO @@ -85,7 +85,7 @@ ☐ Fix the global weak_ptr to gsp ✔ HID @done(19-12-30 14:46) ✔ HTTP @done(19-12-30 15:18) - ☐ IR + ✔ IR @done(19-12-30 16:06) ☐ LDR_RO ☐ MIC ☐ MVD diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index d21cb393f..7924a1e12 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/bit_field.h" #include "common/swap.h" #include "core/frontend/input.h" @@ -65,6 +67,16 @@ private: std::unique_ptr zr; std::unique_ptr c_stick; std::atomic is_device_reload_pending; + + template + void serialize(Archive& ar, const unsigned int) { + ar& hid_period; + ar& calibration_data; // This isn't writeable for now, but might be in future + RequestInputDevicesReload(); // zl, zr, c_stick are loaded here + } + friend class boost::serialization::access; }; } // namespace Service::IR + +BOOST_CLASS_EXPORT_KEY(Service::IR::ExtraHID) diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index d392c1983..fd6c1b905 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -15,6 +15,19 @@ namespace Service::IR { +template +void IR_USER::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& conn_status_event; + ar& send_event; + ar& receive_event; + ar& shared_memory; + ar& connected_device; + ar& *receive_buffer.get(); + ar& *extra_hid.get(); +} +SERIALIZE_IMPL(IR_USER) + // This is a header that will present in the ir:USER shared memory if it is initialized with // InitializeIrNopShared service function. Otherwise the shared memory doesn't have this header if // it is initialized with InitializeIrNop service function. @@ -139,6 +152,16 @@ private: u32_le end_index; u32_le packet_count; u32_le unknown; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& begin_index; + ar& end_index; + ar& packet_count; + ar& unknown; + } + friend class boost::serialization::access; }; static_assert(sizeof(BufferInfo) == 16, "BufferInfo has wrong size!"); @@ -179,6 +202,18 @@ private: u32 buffer_offset; u32 max_packet_count; u32 max_data_size; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& info; + ar& shared_memory; + ar& info_offset; + ar& buffer_offset; + ar& max_packet_count; + ar& max_data_size; + } + friend class boost::serialization::access; }; /// Wraps the payload into packet and puts it to the receive buffer @@ -270,8 +305,8 @@ void IR_USER::RequireConnection(Kernel::HLERequestContext& ctx) { shared_memory_ptr[offsetof(SharedMemoryHeader, connection_role)] = 2; shared_memory_ptr[offsetof(SharedMemoryHeader, connected)] = 1; - connected_device = extra_hid.get(); - connected_device->OnConnect(); + connected_device = true; + extra_hid->OnConnect(); conn_status_event->Signal(); } else { LOG_WARNING(Service_IR, "unknown device id {}. Won't connect.", device_id); @@ -305,8 +340,8 @@ void IR_USER::GetSendEvent(Kernel::HLERequestContext& ctx) { void IR_USER::Disconnect(Kernel::HLERequestContext& ctx) { if (connected_device) { - connected_device->OnDisconnect(); - connected_device = nullptr; + extra_hid->OnDisconnect(); + connected_device = false; conn_status_event->Signal(); } @@ -331,8 +366,8 @@ void IR_USER::GetConnectionStatusEvent(Kernel::HLERequestContext& ctx) { void IR_USER::FinalizeIrNop(Kernel::HLERequestContext& ctx) { if (connected_device) { - connected_device->OnDisconnect(); - connected_device = nullptr; + extra_hid->OnDisconnect(); + connected_device = false; } shared_memory = nullptr; @@ -352,7 +387,7 @@ void IR_USER::SendIrNop(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); if (connected_device) { - connected_device->OnReceive(buffer); + extra_hid->OnReceive(buffer); send_event->Signal(); rb.Push(RESULT_SUCCESS); } else { @@ -424,7 +459,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) { IR_USER::~IR_USER() { if (connected_device) { - connected_device->OnDisconnect(); + extra_hid->OnDisconnect(); } } diff --git a/src/core/hle/service/ir/ir_user.h b/src/core/hle/service/ir/ir_user.h index 54a4f3e08..75bbeb779 100644 --- a/src/core/hle/service/ir/ir_user.h +++ b/src/core/hle/service/ir/ir_user.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "core/hle/service/service.h" namespace Kernel { @@ -45,6 +46,7 @@ protected: void Send(const std::vector& data); private: + // NOTE: This value is *not* serialized because it's always passed in the constructor const SendFunc send_func; }; @@ -164,9 +166,14 @@ private: std::shared_ptr conn_status_event, send_event, receive_event; std::shared_ptr shared_memory; - IRDevice* connected_device{nullptr}; + bool connected_device; std::unique_ptr receive_buffer; std::unique_ptr extra_hid; + +private: + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::IR From e3c0211b7418a78f43722376305593472c27e574 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 16:15:41 +0000 Subject: [PATCH 044/129] Fix clang format --- src/core/hle/service/hid/hid_spvr.h | 1 + src/core/hle/service/hid/hid_user.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/core/hle/service/hid/hid_spvr.h b/src/core/hle/service/hid/hid_spvr.h index a49101dc3..749bd36b8 100644 --- a/src/core/hle/service/hid/hid_spvr.h +++ b/src/core/hle/service/hid/hid_spvr.h @@ -11,6 +11,7 @@ namespace Service::HID { class Spvr final : public Module::Interface { public: explicit Spvr(std::shared_ptr hid); + private: SERVICE_SERIALIZATION(Spvr, hid, Module) }; diff --git a/src/core/hle/service/hid/hid_user.h b/src/core/hle/service/hid/hid_user.h index 6fd9803c6..8a6763ea6 100644 --- a/src/core/hle/service/hid/hid_user.h +++ b/src/core/hle/service/hid/hid_user.h @@ -14,6 +14,7 @@ namespace Service::HID { class User final : public Module::Interface { public: explicit User(std::shared_ptr hid); + private: SERVICE_SERIALIZATION(User, hid, Module) }; From 01ec2e8a67999afbacacdb00eb5ed507ac9b1b73 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 16:53:57 +0000 Subject: [PATCH 045/129] Serialize MIC service --- TODO | 4 +-- src/core/hle/service/ldr_ro/ldr_ro.cpp | 4 +++ src/core/hle/service/ldr_ro/ldr_ro.h | 18 ++++++++++++ src/core/hle/service/mic_u.cpp | 40 ++++++++++++++++++++++++++ src/core/hle/service/mic_u.h | 7 +++++ 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index b679a5168..2aff6ae68 100644 --- a/TODO +++ b/TODO @@ -86,8 +86,8 @@ ✔ HID @done(19-12-30 14:46) ✔ HTTP @done(19-12-30 15:18) ✔ IR @done(19-12-30 16:06) - ☐ LDR_RO - ☐ MIC + ✔ LDR_RO @done(19-12-30 16:25) + ✔ MIC @done(19-12-30 16:53) ☐ MVD ☐ NDM ☐ NEWS diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp index caa063593..0a61f4c23 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include "common/alignment.h" +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/arm/arm_interface.h" @@ -12,6 +13,9 @@ #include "core/hle/service/ldr_ro/cro_helper.h" #include "core/hle/service/ldr_ro/ldr_ro.h" +SERVICE_CONSTRUCT_IMPL(Service::LDR::RO) +SERIALIZE_EXPORT_IMPL(Service::LDR::RO) + namespace Service::LDR { static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 diff --git a/src/core/hle/service/ldr_ro/ldr_ro.h b/src/core/hle/service/ldr_ro/ldr_ro.h index f90005d13..2b6f79f03 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.h +++ b/src/core/hle/service/ldr_ro/ldr_ro.h @@ -14,6 +14,13 @@ namespace Service::LDR { struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { VAddr loaded_crs = 0; ///< the virtual address of the static module + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& loaded_crs; + } + friend class boost::serialization::access; }; class RO final : public ServiceFramework { @@ -151,8 +158,19 @@ private: void Shutdown(Kernel::HLERequestContext& self); Core::System& system; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::LDR + +SERVICE_CONSTRUCT(Service::LDR::RO) +BOOST_CLASS_EXPORT_KEY(Service::LDR::RO) +BOOST_CLASS_EXPORT_KEY(Service::LDR::ClientSlot) diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index ba3e97807..34b16094a 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -5,6 +5,7 @@ #ifdef HAVE_CUBEB #include "audio_core/cubeb_input.h" #endif +#include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" #include "core/frontend/mic.h" @@ -17,8 +18,17 @@ #include "core/hle/service/mic_u.h" #include "core/settings.h" +SERVICE_CONSTRUCT_IMPL(Service::MIC::MIC_U) +SERIALIZE_EXPORT_IMPL(Service::MIC::MIC_U) + namespace Service::MIC { +template +void MIC_U::serialize(Archive& ar, const unsigned int) { + ar&* impl.get(); +} +SERIALIZE_IMPL(MIC_U) + /// Microphone audio encodings. enum class Encoding : u8 { PCM8 = 0, ///< Unsigned 8-bit PCM. @@ -59,6 +69,7 @@ constexpr u64 GetBufferUpdateRate(SampleRate sample_rate) { // Variables holding the current mic buffer writing state struct State { + std::shared_ptr memory_ref = nullptr; u8* sharedmem_buffer = nullptr; u32 sharedmem_size = 0; std::size_t size = 0; @@ -95,6 +106,20 @@ struct State { std::memcpy(sharedmem_buffer + (sharedmem_size - sizeof(u32)), reinterpret_cast(&off), sizeof(u32)); } + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& sharedmem_size; + ar& size; + ar& offset; + ar& initial_offset; + ar& looped_buffer; + ar& sample_size; + ar& sample_rate; + sharedmem_buffer = memory_ref ? memory_ref->GetPointer() : nullptr; + } + friend class boost::serialization::access; }; struct MIC_U::Impl { @@ -363,6 +388,21 @@ struct MIC_U::Impl { std::unique_ptr mic; Core::Timing& timing; State state{}; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& change_mic_impl_requested; + ar& buffer_full_event; + // buffer_write_event set in constructor + ar& shared_memory; + ar& client_version; + ar& allow_shell_closed; + ar& clamp; + // mic interface set in constructor + ar& state; + } + friend class boost::serialization::access; }; void MIC_U::MapSharedMem(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/mic_u.h b/src/core/hle/service/mic_u.h index 2e40ed404..2ca95e924 100644 --- a/src/core/hle/service/mic_u.h +++ b/src/core/hle/service/mic_u.h @@ -190,6 +190,10 @@ private: struct Impl; std::unique_ptr impl; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; void ReloadMic(Core::System& system); @@ -197,3 +201,6 @@ void ReloadMic(Core::System& system); void InstallInterfaces(Core::System& system); } // namespace Service::MIC + +SERVICE_CONSTRUCT(Service::MIC::MIC_U) +BOOST_CLASS_EXPORT_KEY(Service::MIC::MIC_U) From 3d6e372f96228fca0dfb17dc8b058af9088beefb Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 30 Dec 2019 17:02:44 +0000 Subject: [PATCH 046/129] More clang format fixes. Really need to standardise the version of this --- src/core/hle/service/ir/extra_hid.h | 2 +- src/core/hle/service/ir/ir_user.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index 7924a1e12..1be403167 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -71,7 +71,7 @@ private: template void serialize(Archive& ar, const unsigned int) { ar& hid_period; - ar& calibration_data; // This isn't writeable for now, but might be in future + ar& calibration_data; // This isn't writeable for now, but might be in future RequestInputDevicesReload(); // zl, zr, c_stick are loaded here } friend class boost::serialization::access; diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index fd6c1b905..64a298103 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -23,8 +23,8 @@ void IR_USER::serialize(Archive& ar, const unsigned int) { ar& receive_event; ar& shared_memory; ar& connected_device; - ar& *receive_buffer.get(); - ar& *extra_hid.get(); + ar&* receive_buffer.get(); + ar&* extra_hid.get(); } SERIALIZE_IMPL(IR_USER) From 2409ee39cbafd6631a5ed1f45f8d0f9c2ccd94ee Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Tue, 31 Dec 2019 20:39:38 +0000 Subject: [PATCH 047/129] Serialize IR, MVD, NDM, NEWS, NFC --- TODO | 8 ++++---- src/core/hle/service/ir/ir_rst.cpp | 17 +++++++++++++++++ src/core/hle/service/ir/ir_rst.h | 7 +++++++ src/core/hle/service/ir/ir_u.cpp | 3 +++ src/core/hle/service/ir/ir_u.h | 2 ++ src/core/hle/service/mvd/mvd_std.cpp | 3 +++ src/core/hle/service/mvd/mvd_std.h | 9 +++++++++ src/core/hle/service/ndm/ndm_u.cpp | 3 +++ src/core/hle/service/ndm/ndm_u.h | 15 +++++++++++++++ src/core/hle/service/news/news_s.cpp | 3 +++ src/core/hle/service/news/news_s.h | 2 ++ src/core/hle/service/news/news_u.cpp | 3 +++ src/core/hle/service/news/news_u.h | 2 ++ src/core/hle/service/nfc/nfc.cpp | 13 +++++++++++++ src/core/hle/service/nfc/nfc.h | 9 ++++++++- src/core/hle/service/nfc/nfc_m.cpp | 3 +++ src/core/hle/service/nfc/nfc_m.h | 6 ++++++ src/core/hle/service/nfc/nfc_u.cpp | 3 +++ src/core/hle/service/nfc/nfc_u.h | 6 ++++++ 19 files changed, 112 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 2aff6ae68..f9fffa60d 100644 --- a/TODO +++ b/TODO @@ -88,10 +88,10 @@ ✔ IR @done(19-12-30 16:06) ✔ LDR_RO @done(19-12-30 16:25) ✔ MIC @done(19-12-30 16:53) - ☐ MVD - ☐ NDM - ☐ NEWS - ☐ NFC + ✔ MVD @done(19-12-31 18:26) + ✔ NDM @done(19-12-31 18:26) + ✔ NEWS @done(19-12-31 18:29) + ✔ NFC @done(19-12-31 20:35) ☐ NIM ☐ NS ☐ NWM diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 71d16a1ce..dc9612e62 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" @@ -12,8 +13,24 @@ #include "core/movie.h" #include "core/settings.h" +SERIALIZE_EXPORT_IMPL(Service::IR::IR_RST) +SERVICE_CONSTRUCT_IMPL(Service::IR::IR_RST) + namespace Service::IR { +template +void IR_RST::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& update_event; + ar& shared_memory; + ar& next_pad_index; + ar& raw_c_stick; + ar& update_period; + // update_callback_id and input devices are set separately + ReloadInputDevices(); +} +SERIALIZE_IMPL(IR_RST) + struct PadDataEntry { PadState current_state; PadState delta_additions; diff --git a/src/core/hle/service/ir/ir_rst.h b/src/core/hle/service/ir/ir_rst.h index 84ad70dfc..8e17381ad 100644 --- a/src/core/hle/service/ir/ir_rst.h +++ b/src/core/hle/service/ir/ir_rst.h @@ -87,6 +87,13 @@ private: std::atomic is_device_reload_pending{false}; bool raw_c_stick{false}; int update_period{0}; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::IR + +BOOST_CLASS_EXPORT_KEY(Service::IR::IR_RST) +SERVICE_CONSTRUCT(Service::IR::IR_RST) diff --git a/src/core/hle/service/ir/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp index d76323e91..61618869a 100644 --- a/src/core/hle/service/ir/ir_u.cpp +++ b/src/core/hle/service/ir/ir_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ir/ir_u.h" +SERIALIZE_EXPORT_IMPL(Service::IR::IR_U) + namespace Service::IR { IR_U::IR_U() : ServiceFramework("ir:u", 1) { diff --git a/src/core/hle/service/ir/ir_u.h b/src/core/hle/service/ir/ir_u.h index ea150b082..eaa54c657 100644 --- a/src/core/hle/service/ir/ir_u.h +++ b/src/core/hle/service/ir/ir_u.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::IR + +BOOST_CLASS_EXPORT_KEY(Service::IR::IR_U) diff --git a/src/core/hle/service/mvd/mvd_std.cpp b/src/core/hle/service/mvd/mvd_std.cpp index 2c397f2dd..43dbde584 100644 --- a/src/core/hle/service/mvd/mvd_std.cpp +++ b/src/core/hle/service/mvd/mvd_std.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/mvd/mvd_std.h" +SERIALIZE_EXPORT_IMPL(Service::MVD::MVD_STD) + namespace Service::MVD { MVD_STD::MVD_STD() : ServiceFramework("mvd:std", 1) { diff --git a/src/core/hle/service/mvd/mvd_std.h b/src/core/hle/service/mvd/mvd_std.h index 6764f6ba8..6e8312e59 100644 --- a/src/core/hle/service/mvd/mvd_std.h +++ b/src/core/hle/service/mvd/mvd_std.h @@ -12,6 +12,15 @@ class MVD_STD final : public ServiceFramework { public: MVD_STD(); ~MVD_STD() = default; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace Service::MVD + +BOOST_CLASS_EXPORT_KEY(Service::MVD::MVD_STD) diff --git a/src/core/hle/service/ndm/ndm_u.cpp b/src/core/hle/service/ndm/ndm_u.cpp index 057e68ede..936d53799 100644 --- a/src/core/hle/service/ndm/ndm_u.cpp +++ b/src/core/hle/service/ndm/ndm_u.cpp @@ -2,10 +2,13 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/ndm/ndm_u.h" +SERIALIZE_EXPORT_IMPL(Service::NDM::NDM_U) + namespace Service::NDM { void NDM_U::EnterExclusiveState(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/ndm/ndm_u.h b/src/core/hle/service/ndm/ndm_u.h index 5f48a3182..3339478d1 100644 --- a/src/core/hle/service/ndm/ndm_u.h +++ b/src/core/hle/service/ndm/ndm_u.h @@ -270,8 +270,23 @@ private: u32 scan_interval = DEFAULT_SCAN_INTERVAL; u32 retry_interval = DEFAULT_RETRY_INTERVAL; bool daemon_lock_enabled = false; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& daemon_bit_mask; + ar& default_daemon_bit_mask; + ar& daemon_status; + ar& exclusive_state; + ar& scan_interval; + ar& retry_interval; + ar& daemon_lock_enabled; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::NDM + +BOOST_CLASS_EXPORT_KEY(Service::NDM::NDM_U) diff --git a/src/core/hle/service/news/news_s.cpp b/src/core/hle/service/news/news_s.cpp index 17eaa5ea8..94cf68f4c 100644 --- a/src/core/hle/service/news/news_s.cpp +++ b/src/core/hle/service/news/news_s.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/news/news_s.h" +SERIALIZE_EXPORT_IMPL(Service::NEWS::NEWS_S) + namespace Service::NEWS { void NEWS_S::GetTotalNotifications(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/news/news_s.h b/src/core/hle/service/news/news_s.h index e4673d22c..711a0e99b 100644 --- a/src/core/hle/service/news/news_s.h +++ b/src/core/hle/service/news/news_s.h @@ -27,3 +27,5 @@ private: }; } // namespace Service::NEWS + +BOOST_CLASS_EXPORT_KEY(Service::NEWS::NEWS_S) diff --git a/src/core/hle/service/news/news_u.cpp b/src/core/hle/service/news/news_u.cpp index 3d6e87f91..d91b594b8 100644 --- a/src/core/hle/service/news/news_u.cpp +++ b/src/core/hle/service/news/news_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/news/news_u.h" +SERIALIZE_EXPORT_IMPL(Service::NEWS::NEWS_U) + namespace Service::NEWS { NEWS_U::NEWS_U() : ServiceFramework("news:u", 1) { diff --git a/src/core/hle/service/news/news_u.h b/src/core/hle/service/news/news_u.h index cb06bad39..472dd579c 100644 --- a/src/core/hle/service/news/news_u.h +++ b/src/core/hle/service/news/news_u.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::NEWS + +BOOST_CLASS_EXPORT_KEY(Service::NEWS::NEWS_U) diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index 86eb6daeb..0bd6121a2 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" @@ -10,8 +11,20 @@ #include "core/hle/service/nfc/nfc_m.h" #include "core/hle/service/nfc/nfc_u.h" +SERVICE_CONSTRUCT_IMPL(Service::NFC::Module) +SERIALIZE_EXPORT_IMPL(Service::NFC::Module) + namespace Service::NFC { +template +void Module::serialize(Archive& ar, const unsigned int) { + ar& tag_in_range_event; + ar& tag_out_of_range_event; + ar& nfc_tag_state; + ar& nfc_status; +} +SERIALIZE_IMPL(Module) + struct TagInfo { u16_le id_offset_size; u8 unk1; diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h index 64bd239ac..2d6b26d83 100644 --- a/src/core/hle/service/nfc/nfc.h +++ b/src/core/hle/service/nfc/nfc.h @@ -226,7 +226,7 @@ public: */ void GetIdentificationBlock(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr nfc; }; @@ -241,8 +241,15 @@ private: AmiiboData amiibo_data{}; bool amiibo_in_range = false; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::NFC + +SERVICE_CONSTRUCT(Service::NFC::Module) +BOOST_CLASS_EXPORT_KEY(Service::NFC::Module) diff --git a/src/core/hle/service/nfc/nfc_m.cpp b/src/core/hle/service/nfc/nfc_m.cpp index 310490b8f..cd591b9c1 100644 --- a/src/core/hle/service/nfc/nfc_m.cpp +++ b/src/core/hle/service/nfc/nfc_m.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nfc/nfc_m.h" +SERIALIZE_EXPORT_IMPL(Service::NFC::NFC_M) + namespace Service::NFC { NFC_M::NFC_M(std::shared_ptr nfc) : Module::Interface(std::move(nfc), "nfc:m", 1) { diff --git a/src/core/hle/service/nfc/nfc_m.h b/src/core/hle/service/nfc/nfc_m.h index c9fe9b130..48a9e241b 100644 --- a/src/core/hle/service/nfc/nfc_m.h +++ b/src/core/hle/service/nfc/nfc_m.h @@ -11,6 +11,12 @@ namespace Service::NFC { class NFC_M final : public Module::Interface { public: explicit NFC_M(std::shared_ptr nfc); + +private: + SERVICE_SERIALIZATION(NFC_M, nfc, Module) }; } // namespace Service::NFC + +BOOST_CLASS_EXPORT_KEY(Service::NFC::NFC_M) +BOOST_SERIALIZATION_CONSTRUCT(Service::NFC::NFC_M) diff --git a/src/core/hle/service/nfc/nfc_u.cpp b/src/core/hle/service/nfc/nfc_u.cpp index a6e99ace2..58d1843e4 100644 --- a/src/core/hle/service/nfc/nfc_u.cpp +++ b/src/core/hle/service/nfc/nfc_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nfc/nfc_u.h" +SERIALIZE_EXPORT_IMPL(Service::NFC::NFC_U) + namespace Service::NFC { NFC_U::NFC_U(std::shared_ptr nfc) : Module::Interface(std::move(nfc), "nfc:u", 1) { diff --git a/src/core/hle/service/nfc/nfc_u.h b/src/core/hle/service/nfc/nfc_u.h index aab408269..2ed6030e6 100644 --- a/src/core/hle/service/nfc/nfc_u.h +++ b/src/core/hle/service/nfc/nfc_u.h @@ -11,6 +11,12 @@ namespace Service::NFC { class NFC_U final : public Module::Interface { public: explicit NFC_U(std::shared_ptr nfc); + +private: + SERVICE_SERIALIZATION(NFC_U, nfc, Module) }; } // namespace Service::NFC + +BOOST_CLASS_EXPORT_KEY(Service::NFC::NFC_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::NFC::NFC_U) From 571b1062f0fd2921d2ea8d559d5dbcdb087e9cd0 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 1 Jan 2020 00:58:36 +0000 Subject: [PATCH 048/129] Serialize NIM, PS, PXI, SOC, SSL services --- TODO | 15 +++++++-------- src/core/hle/service/nim/nim_aoc.cpp | 3 +++ src/core/hle/service/nim/nim_aoc.h | 2 ++ src/core/hle/service/nim/nim_s.cpp | 3 +++ src/core/hle/service/nim/nim_s.h | 2 ++ src/core/hle/service/nim/nim_u.cpp | 4 ++++ src/core/hle/service/nim/nim_u.h | 10 ++++++++++ src/core/hle/service/ps/ps_ps.cpp | 3 +++ src/core/hle/service/ps/ps_ps.h | 2 ++ src/core/hle/service/pxi/dev.cpp | 3 +++ src/core/hle/service/pxi/dev.h | 2 ++ src/core/hle/service/soc_u.cpp | 3 +++ src/core/hle/service/soc_u.h | 18 ++++++++++++++++++ src/core/hle/service/ssl_c.cpp | 2 ++ src/core/hle/service/ssl_c.h | 2 ++ 15 files changed, 66 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index f9fffa60d..46ba9b260 100644 --- a/TODO +++ b/TODO @@ -17,7 +17,7 @@ ☐ Telemetry session ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE ☐ Review constructor/initialization code -☐ Fix CI +✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) ✔ LCD regs @done(19-08-13 15:41) @@ -92,15 +92,14 @@ ✔ NDM @done(19-12-31 18:26) ✔ NEWS @done(19-12-31 18:29) ✔ NFC @done(19-12-31 20:35) - ☐ NIM - ☐ NS + ✔ NIM @done(19-12-31 21:08) + ✔ NS @done(20-01-01 00:46) ☐ NWM ☐ PM - ☐ PS + ✔ PS @done(20-01-01 00:54) ☐ PTM - ☐ PXI + ✔ PXI @done(20-01-01 00:53) ☐ QTM - ☐ SM - ☐ SOC - ☐ SSL + ✔ SOC @done(20-01-01 00:51) + ✔ SSL @done(20-01-01 00:48) ☐ Y2R \ No newline at end of file diff --git a/src/core/hle/service/nim/nim_aoc.cpp b/src/core/hle/service/nim/nim_aoc.cpp index ddd8d5e03..f20c96f69 100644 --- a/src/core/hle/service/nim/nim_aoc.cpp +++ b/src/core/hle/service/nim/nim_aoc.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nim/nim_aoc.h" +SERIALIZE_EXPORT_IMPL(Service::NIM::NIM_AOC) + namespace Service::NIM { NIM_AOC::NIM_AOC() : ServiceFramework("nim:aoc", 2) { diff --git a/src/core/hle/service/nim/nim_aoc.h b/src/core/hle/service/nim/nim_aoc.h index 5a1f518ec..2d06a9d1c 100644 --- a/src/core/hle/service/nim/nim_aoc.h +++ b/src/core/hle/service/nim/nim_aoc.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::NIM + +BOOST_CLASS_EXPORT_KEY(Service::NIM::NIM_AOC) diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp index d7236249f..27118e406 100644 --- a/src/core/hle/service/nim/nim_s.cpp +++ b/src/core/hle/service/nim/nim_s.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nim/nim_s.h" +SERIALIZE_EXPORT_IMPL(Service::NIM::NIM_S) + namespace Service::NIM { NIM_S::NIM_S() : ServiceFramework("nim:s", 1) { diff --git a/src/core/hle/service/nim/nim_s.h b/src/core/hle/service/nim/nim_s.h index 6485cde18..6281270f5 100644 --- a/src/core/hle/service/nim/nim_s.h +++ b/src/core/hle/service/nim/nim_s.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::NIM + +BOOST_CLASS_EXPORT_KEY(Service::NIM::NIM_S) diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp index dd0e4d31c..b44ef3539 100644 --- a/src/core/hle/service/nim/nim_u.cpp +++ b/src/core/hle/service/nim/nim_u.cpp @@ -2,11 +2,15 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" #include "core/hle/service/nim/nim_u.h" +SERVICE_CONSTRUCT_IMPL(Service::NIM::NIM_U) +SERIALIZE_EXPORT_IMPL(Service::NIM::NIM_U) + namespace Service::NIM { NIM_U::NIM_U(Core::System& system) : ServiceFramework("nim:u", 2) { diff --git a/src/core/hle/service/nim/nim_u.h b/src/core/hle/service/nim/nim_u.h index 367ee6ea8..98fec69b2 100644 --- a/src/core/hle/service/nim/nim_u.h +++ b/src/core/hle/service/nim/nim_u.h @@ -41,6 +41,16 @@ private: void CheckSysUpdateAvailable(Kernel::HLERequestContext& ctx); std::shared_ptr nim_system_update_event; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& nim_system_update_event; + } + friend class boost::serialization::access; }; } // namespace Service::NIM + +SERVICE_CONSTRUCT(Service::NIM::NIM_U) +BOOST_CLASS_EXPORT_KEY(Service::NIM::NIM_U) diff --git a/src/core/hle/service/ps/ps_ps.cpp b/src/core/hle/service/ps/ps_ps.cpp index a48903348..1ba4d7f4c 100644 --- a/src/core/hle/service/ps/ps_ps.cpp +++ b/src/core/hle/service/ps/ps_ps.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" @@ -11,6 +12,8 @@ #include "core/hw/aes/arithmetic128.h" #include "core/hw/aes/key.h" +SERIALIZE_EXPORT_IMPL(Service::PS::PS_PS) + namespace Service::PS { enum class AlgorithmType : u8 { diff --git a/src/core/hle/service/ps/ps_ps.h b/src/core/hle/service/ps/ps_ps.h index 6e8b3ad0a..39f6d62b2 100644 --- a/src/core/hle/service/ps/ps_ps.h +++ b/src/core/hle/service/ps/ps_ps.h @@ -231,3 +231,5 @@ private: void InstallInterfaces(Core::System& system); } // namespace Service::PS + +BOOST_CLASS_EXPORT_KEY(Service::PS::PS_PS) diff --git a/src/core/hle/service/pxi/dev.cpp b/src/core/hle/service/pxi/dev.cpp index dcea938a6..113551690 100644 --- a/src/core/hle/service/pxi/dev.cpp +++ b/src/core/hle/service/pxi/dev.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/pxi/dev.h" +SERIALIZE_EXPORT_IMPL(Service::PXI::DEV) + namespace Service::PXI { DEV::DEV() : ServiceFramework("pxi:dev", 1) { diff --git a/src/core/hle/service/pxi/dev.h b/src/core/hle/service/pxi/dev.h index 115dc2308..ed17435b6 100644 --- a/src/core/hle/service/pxi/dev.h +++ b/src/core/hle/service/pxi/dev.h @@ -16,3 +16,5 @@ public: }; } // namespace Service::PXI + +BOOST_CLASS_EXPORT_KEY(Service::PXI::DEV) diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 5ebe55356..56b48cd3a 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "common/archives.h" #include "common/assert.h" #include "common/bit_field.h" #include "common/common_types.h" @@ -52,6 +53,8 @@ #define closesocket(x) close(x) #endif +SERIALIZE_EXPORT_IMPL(Service::SOC::SOC_U) + namespace Service::SOC { const s32 SOCKET_ERROR_VALUE = -1; diff --git a/src/core/hle/service/soc_u.h b/src/core/hle/service/soc_u.h index 273aac49c..595a984f2 100644 --- a/src/core/hle/service/soc_u.h +++ b/src/core/hle/service/soc_u.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "core/hle/service/service.h" namespace Core { @@ -17,6 +18,14 @@ namespace Service::SOC { struct SocketHolder { u32 socket_fd; ///< The socket descriptor bool blocking; ///< Whether the socket is blocking or not, it is only read on Windows. + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& socket_fd; + ar& blocking; + } + friend class boost::serialization::access; }; class SOC_U final : public ServiceFramework { @@ -55,8 +64,17 @@ private: /// Holds info about the currently open sockets std::unordered_map open_sockets; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& open_sockets; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::SOC + +BOOST_CLASS_EXPORT_KEY(Service::SOC::SOC_U) diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp index b862c41f1..8e74c1b7c 100644 --- a/src/core/hle/service/ssl_c.cpp +++ b/src/core/hle/service/ssl_c.cpp @@ -2,12 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/common_types.h" #include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/ssl_c.h" +SERIALIZE_EXPORT_IMPL(Service::SSL::SSL_C) namespace Service::SSL { void SSL_C::Initialize(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/ssl_c.h b/src/core/hle/service/ssl_c.h index 807f7c725..3984f7ecc 100644 --- a/src/core/hle/service/ssl_c.h +++ b/src/core/hle/service/ssl_c.h @@ -28,3 +28,5 @@ private: void InstallInterfaces(Core::System& system); } // namespace Service::SSL + +BOOST_CLASS_EXPORT_KEY(Service::SSL::SSL_C) From f5e2f873b003dacaf0b28b92c60beb5d7804e9ee Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 1 Jan 2020 21:31:52 +0000 Subject: [PATCH 049/129] Serialize NWM service --- TODO | 18 ++++++++++++------ externals/boost | 2 +- src/core/hle/service/nwm/nwm_cec.cpp | 3 +++ src/core/hle/service/nwm/nwm_cec.h | 2 ++ src/core/hle/service/nwm/nwm_ext.cpp | 3 +++ src/core/hle/service/nwm/nwm_ext.h | 2 ++ src/core/hle/service/nwm/nwm_inf.cpp | 3 +++ src/core/hle/service/nwm/nwm_inf.h | 2 ++ src/core/hle/service/nwm/nwm_sap.cpp | 3 +++ src/core/hle/service/nwm/nwm_sap.h | 2 ++ src/core/hle/service/nwm/nwm_soc.cpp | 3 +++ src/core/hle/service/nwm/nwm_soc.h | 2 ++ src/core/hle/service/nwm/nwm_tst.cpp | 3 +++ src/core/hle/service/nwm/nwm_tst.h | 2 ++ src/core/hle/service/nwm/nwm_uds.cpp | 12 ++++++++++++ src/core/hle/service/nwm/nwm_uds.h | 14 ++++++++++++++ src/network/CMakeLists.txt | 2 +- src/network/room_member.h | 12 ++++++++++++ 18 files changed, 82 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 46ba9b260..1f29a4693 100644 --- a/TODO +++ b/TODO @@ -10,11 +10,16 @@ ☐ App loader ☐ Archive manager ☐ Custom texture cache -☐ MMIO -☐ Movie -☐ Perf stats -☐ Settings -☐ Telemetry session +✘ MMIO @cancelled(20-01-01 01:06) + Seems that this whole subsystem is only used in tests +✘ Movie @cancelled(20-01-01 01:07) + Doesn't need to be serialized here +✘ Perf stats @cancelled(20-01-01 01:09) + Doesn't need to be serialized here +✘ Settings @cancelled(20-01-01 01:11) + For now, let the settings just be whatever they are +✘ Telemetry session @cancelled(20-01-01 01:12) + Doesn't need to be serialized here ☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE ☐ Review constructor/initialization code ✔ Fix CI @done(19-12-31 21:32) @@ -94,7 +99,8 @@ ✔ NFC @done(19-12-31 20:35) ✔ NIM @done(19-12-31 21:08) ✔ NS @done(20-01-01 00:46) - ☐ NWM + ✔ NWM @done(20-01-01 21:31) + ☐ Fix wifi_packet_received? ☐ PM ✔ PS @done(20-01-01 00:54) ☐ PTM diff --git a/externals/boost b/externals/boost index 65dc954e9..6d7edc593 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 65dc954e93b22870b8423701e225147c75e3b31b +Subproject commit 6d7edc593be8e47c8de7bc5f7d6b32971fad0c24 diff --git a/src/core/hle/service/nwm/nwm_cec.cpp b/src/core/hle/service/nwm/nwm_cec.cpp index 7c47c88c7..ecd4f16e1 100644 --- a/src/core/hle/service/nwm/nwm_cec.cpp +++ b/src/core/hle/service/nwm/nwm_cec.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_cec.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_CEC) + namespace Service::NWM { NWM_CEC::NWM_CEC() : ServiceFramework("nwm::CEC") { diff --git a/src/core/hle/service/nwm/nwm_cec.h b/src/core/hle/service/nwm/nwm_cec.h index afdf98477..4f62f32f1 100644 --- a/src/core/hle/service/nwm/nwm_cec.h +++ b/src/core/hle/service/nwm/nwm_cec.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_CEC) diff --git a/src/core/hle/service/nwm/nwm_ext.cpp b/src/core/hle/service/nwm/nwm_ext.cpp index 4bbac391f..d69da94ff 100644 --- a/src/core/hle/service/nwm/nwm_ext.cpp +++ b/src/core/hle/service/nwm/nwm_ext.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_ext.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_EXT) + namespace Service::NWM { NWM_EXT::NWM_EXT() : ServiceFramework("nwm::EXT") { diff --git a/src/core/hle/service/nwm/nwm_ext.h b/src/core/hle/service/nwm/nwm_ext.h index 1711db65a..a8d43df70 100644 --- a/src/core/hle/service/nwm/nwm_ext.h +++ b/src/core/hle/service/nwm/nwm_ext.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_EXT) diff --git a/src/core/hle/service/nwm/nwm_inf.cpp b/src/core/hle/service/nwm/nwm_inf.cpp index 71cf11891..eaabf6667 100644 --- a/src/core/hle/service/nwm/nwm_inf.cpp +++ b/src/core/hle/service/nwm/nwm_inf.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_inf.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_INF) + namespace Service::NWM { NWM_INF::NWM_INF() : ServiceFramework("nwm::INF") { diff --git a/src/core/hle/service/nwm/nwm_inf.h b/src/core/hle/service/nwm/nwm_inf.h index 2c69cfb1e..f13fd4158 100644 --- a/src/core/hle/service/nwm/nwm_inf.h +++ b/src/core/hle/service/nwm/nwm_inf.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_INF) diff --git a/src/core/hle/service/nwm/nwm_sap.cpp b/src/core/hle/service/nwm/nwm_sap.cpp index 2ef196ab4..2cedf9371 100644 --- a/src/core/hle/service/nwm/nwm_sap.cpp +++ b/src/core/hle/service/nwm/nwm_sap.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_sap.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_SAP) + namespace Service::NWM { NWM_SAP::NWM_SAP() : ServiceFramework("nwm::SAP") { diff --git a/src/core/hle/service/nwm/nwm_sap.h b/src/core/hle/service/nwm/nwm_sap.h index b6700b8ed..1a289542c 100644 --- a/src/core/hle/service/nwm/nwm_sap.h +++ b/src/core/hle/service/nwm/nwm_sap.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_SAP) diff --git a/src/core/hle/service/nwm/nwm_soc.cpp b/src/core/hle/service/nwm/nwm_soc.cpp index 443baaf39..d6ca365ab 100644 --- a/src/core/hle/service/nwm/nwm_soc.cpp +++ b/src/core/hle/service/nwm/nwm_soc.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_soc.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_SOC) + namespace Service::NWM { NWM_SOC::NWM_SOC() : ServiceFramework("nwm::SOC") { diff --git a/src/core/hle/service/nwm/nwm_soc.h b/src/core/hle/service/nwm/nwm_soc.h index 8e1b922bc..883a20854 100644 --- a/src/core/hle/service/nwm/nwm_soc.h +++ b/src/core/hle/service/nwm/nwm_soc.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_SOC) diff --git a/src/core/hle/service/nwm/nwm_tst.cpp b/src/core/hle/service/nwm/nwm_tst.cpp index 3be65200b..65ffabfd9 100644 --- a/src/core/hle/service/nwm/nwm_tst.cpp +++ b/src/core/hle/service/nwm/nwm_tst.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/nwm/nwm_tst.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_TST) + namespace Service::NWM { NWM_TST::NWM_TST() : ServiceFramework("nwm::TST") { diff --git a/src/core/hle/service/nwm/nwm_tst.h b/src/core/hle/service/nwm/nwm_tst.h index 8214e0d1d..e58fa3371 100644 --- a/src/core/hle/service/nwm/nwm_tst.h +++ b/src/core/hle/service/nwm/nwm_tst.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::NWM + +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_TST) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index fe8f7635f..9a3de82fa 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -4,7 +4,10 @@ #include #include +#include +#include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/core.h" @@ -23,6 +26,15 @@ namespace Service::NWM { +template +void NWM_UDS::serialize(Archive& ar, const unsigned int) { + ar& node_map; + ar& connection_event; + ar& received_beacons; + // TODO: Fix wifi_packet_received? +} +SERIALIZE_IMPL(NWM_UDS) + namespace ErrCodes { enum { NotInitialized = 2, diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index 52ca38663..07dd7e9ba 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -521,6 +521,14 @@ private: struct Node { bool connected; u16 node_id; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& connected; + ar& node_id; + } + friend class boost::serialization::access; }; std::map node_map; @@ -543,6 +551,12 @@ private: // List of the last beacons received from the network. std::list received_beacons; + + template + void serialize(Archive& ar, const unsigned int); }; } // namespace Service::NWM + +SERVICE_CONSTRUCT(Service::NWM::NWM_UDS) +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_UDS) diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 24f782653..382a69e2f 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -13,4 +13,4 @@ add_library(network STATIC create_target_directory_groups(network) -target_link_libraries(network PRIVATE common enet) +target_link_libraries(network PRIVATE common enet Boost::boost) diff --git a/src/network/room_member.h b/src/network/room_member.h index ad5d14b44..d582a8552 100644 --- a/src/network/room_member.h +++ b/src/network/room_member.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "common/common_types.h" #include "network/room.h" @@ -30,6 +31,17 @@ struct WifiPacket { MacAddress transmitter_address; ///< Mac address of the transmitter. MacAddress destination_address; ///< Mac address of the receiver. u8 channel; ///< WiFi channel where this frame was transmitted. + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& type; + ar& data; + ar& transmitter_address; + ar& destination_address; + ar& channel; + } + friend class boost::serialization::access; }; /// Represents a chat message. From 92857efca4f958f00ac5ee6eb69a6d0ba94f8a8b Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 1 Jan 2020 22:36:58 +0000 Subject: [PATCH 050/129] Serialize PTM service --- TODO | 4 ++-- src/core/hle/service/pm/pm_app.cpp | 3 +++ src/core/hle/service/pm/pm_app.h | 2 ++ src/core/hle/service/pm/pm_dbg.cpp | 3 +++ src/core/hle/service/pm/pm_dbg.h | 2 ++ src/core/hle/service/ptm/ptm.cpp | 3 +++ src/core/hle/service/ptm/ptm.h | 12 +++++++++++- src/core/hle/service/ptm/ptm_gets.cpp | 3 +++ src/core/hle/service/ptm/ptm_gets.h | 6 ++++++ src/core/hle/service/ptm/ptm_play.cpp | 3 +++ src/core/hle/service/ptm/ptm_play.h | 6 ++++++ src/core/hle/service/ptm/ptm_sets.cpp | 3 +++ src/core/hle/service/ptm/ptm_sets.h | 6 ++++++ src/core/hle/service/ptm/ptm_sysm.cpp | 4 ++++ src/core/hle/service/ptm/ptm_sysm.h | 11 +++++++++++ src/core/hle/service/ptm/ptm_u.cpp | 3 +++ src/core/hle/service/ptm/ptm_u.h | 6 ++++++ 17 files changed, 77 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 1f29a4693..0b7d5dd36 100644 --- a/TODO +++ b/TODO @@ -101,9 +101,9 @@ ✔ NS @done(20-01-01 00:46) ✔ NWM @done(20-01-01 21:31) ☐ Fix wifi_packet_received? - ☐ PM + ✔ PM @done(20-01-01 22:14) ✔ PS @done(20-01-01 00:54) - ☐ PTM + ✔ PTM @done(20-01-01 22:36) ✔ PXI @done(20-01-01 00:53) ☐ QTM ✔ SOC @done(20-01-01 00:51) diff --git a/src/core/hle/service/pm/pm_app.cpp b/src/core/hle/service/pm/pm_app.cpp index 9599dfcfc..fd0858356 100644 --- a/src/core/hle/service/pm/pm_app.cpp +++ b/src/core/hle/service/pm/pm_app.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/pm/pm_app.h" +SERIALIZE_EXPORT_IMPL(Service::PM::PM_APP) + namespace Service::PM { PM_APP::PM_APP() : ServiceFramework("pm:app", 3) { diff --git a/src/core/hle/service/pm/pm_app.h b/src/core/hle/service/pm/pm_app.h index 8c7e375f0..0fb290aba 100644 --- a/src/core/hle/service/pm/pm_app.h +++ b/src/core/hle/service/pm/pm_app.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::PM + +BOOST_CLASS_EXPORT_KEY(Service::PM::PM_APP) diff --git a/src/core/hle/service/pm/pm_dbg.cpp b/src/core/hle/service/pm/pm_dbg.cpp index 63879ff20..33e195a6f 100644 --- a/src/core/hle/service/pm/pm_dbg.cpp +++ b/src/core/hle/service/pm/pm_dbg.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/pm/pm_dbg.h" +SERIALIZE_EXPORT_IMPL(Service::PM::PM_DBG) + namespace Service::PM { PM_DBG::PM_DBG() : ServiceFramework("pm:dbg", 3) { diff --git a/src/core/hle/service/pm/pm_dbg.h b/src/core/hle/service/pm/pm_dbg.h index 77b644969..1cfdea6fe 100644 --- a/src/core/hle/service/pm/pm_dbg.h +++ b/src/core/hle/service/pm/pm_dbg.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::PM + +BOOST_CLASS_EXPORT_KEY(Service::PM::PM_DBG) diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 7d30fcc5b..69b51480b 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -18,6 +19,8 @@ #include "core/hle/service/ptm/ptm_u.h" #include "core/settings.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::Module) + namespace Service::PTM { /// Values for the default gamecoin.dat file diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h index 549e69353..ba23224d7 100644 --- a/src/core/hle/service/ptm/ptm.h +++ b/src/core/hle/service/ptm/ptm.h @@ -137,7 +137,7 @@ public: */ void CheckNew3DS(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr ptm; }; @@ -145,8 +145,18 @@ private: bool shell_open = true; bool battery_is_charging = true; bool pedometer_is_counting = false; + + template + void serialize(Archive& ar, const unsigned int) { + ar& shell_open; + ar& battery_is_charging; + ar& pedometer_is_counting; + } + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::Module) diff --git a/src/core/hle/service/ptm/ptm_gets.cpp b/src/core/hle/service/ptm/ptm_gets.cpp index e083aed6a..6feedbf94 100644 --- a/src/core/hle/service/ptm/ptm_gets.cpp +++ b/src/core/hle/service/ptm/ptm_gets.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_gets.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_Gets) + namespace Service::PTM { PTM_Gets::PTM_Gets(std::shared_ptr ptm) diff --git a/src/core/hle/service/ptm/ptm_gets.h b/src/core/hle/service/ptm/ptm_gets.h index a8d71fdc9..57b8e5f55 100644 --- a/src/core/hle/service/ptm/ptm_gets.h +++ b/src/core/hle/service/ptm/ptm_gets.h @@ -12,6 +12,12 @@ namespace Service::PTM { class PTM_Gets final : public Module::Interface { public: explicit PTM_Gets(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_Gets, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_Gets) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_Gets) diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp index 6ef45780e..00585ccce 100644 --- a/src/core/hle/service/ptm/ptm_play.cpp +++ b/src/core/hle/service/ptm/ptm_play.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_play.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_Play) + namespace Service::PTM { PTM_Play::PTM_Play(std::shared_ptr ptm) diff --git a/src/core/hle/service/ptm/ptm_play.h b/src/core/hle/service/ptm/ptm_play.h index 3a226149d..091e91d30 100644 --- a/src/core/hle/service/ptm/ptm_play.h +++ b/src/core/hle/service/ptm/ptm_play.h @@ -12,6 +12,12 @@ namespace Service::PTM { class PTM_Play final : public Module::Interface { public: explicit PTM_Play(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_Play, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_Play) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_Play) diff --git a/src/core/hle/service/ptm/ptm_sets.cpp b/src/core/hle/service/ptm/ptm_sets.cpp index b925f49c9..e0f436ddc 100644 --- a/src/core/hle/service/ptm/ptm_sets.cpp +++ b/src/core/hle/service/ptm/ptm_sets.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_sets.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_Sets) + namespace Service::PTM { PTM_Sets::PTM_Sets(std::shared_ptr ptm) : Module::Interface(std::move(ptm), "ptm:sets", 1) { diff --git a/src/core/hle/service/ptm/ptm_sets.h b/src/core/hle/service/ptm/ptm_sets.h index 317781faf..573b20dbd 100644 --- a/src/core/hle/service/ptm/ptm_sets.h +++ b/src/core/hle/service/ptm/ptm_sets.h @@ -12,6 +12,12 @@ namespace Service::PTM { class PTM_Sets final : public Module::Interface { public: explicit PTM_Sets(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_Sets, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_Sets) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_Sets) diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp index 45ee1b6fc..48b44104e 100644 --- a/src/core/hle/service/ptm/ptm_sysm.cpp +++ b/src/core/hle/service/ptm/ptm_sysm.cpp @@ -2,8 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_sysm.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_S) +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_Sysm) + namespace Service::PTM { PTM_S_Common::PTM_S_Common(std::shared_ptr ptm, const char* name) diff --git a/src/core/hle/service/ptm/ptm_sysm.h b/src/core/hle/service/ptm/ptm_sysm.h index 8667f2a95..1e01fdb2e 100644 --- a/src/core/hle/service/ptm/ptm_sysm.h +++ b/src/core/hle/service/ptm/ptm_sysm.h @@ -17,11 +17,22 @@ public: class PTM_S final : public PTM_S_Common { public: explicit PTM_S(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_S, ptm, Module) }; class PTM_Sysm final : public PTM_S_Common { public: explicit PTM_Sysm(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_Sysm, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_S) +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_Sysm) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_Sysm) diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp index 647ef5961..4c1820df4 100644 --- a/src/core/hle/service/ptm/ptm_u.cpp +++ b/src/core/hle/service/ptm/ptm_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/ptm/ptm_u.h" +SERIALIZE_EXPORT_IMPL(Service::PTM::PTM_U) + namespace Service::PTM { PTM_U::PTM_U(std::shared_ptr ptm) : Module::Interface(std::move(ptm), "ptm:u", 26) { diff --git a/src/core/hle/service/ptm/ptm_u.h b/src/core/hle/service/ptm/ptm_u.h index 618401cec..213972242 100644 --- a/src/core/hle/service/ptm/ptm_u.h +++ b/src/core/hle/service/ptm/ptm_u.h @@ -12,6 +12,12 @@ namespace Service::PTM { class PTM_U final : public Module::Interface { public: explicit PTM_U(std::shared_ptr ptm); + +private: + SERVICE_SERIALIZATION(PTM_U, ptm, Module) }; } // namespace Service::PTM + +BOOST_CLASS_EXPORT_KEY(Service::PTM::PTM_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::PTM::PTM_U) From ef2e50328133f6553046219eb54027800d88a148 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 1 Jan 2020 22:57:21 +0000 Subject: [PATCH 051/129] Serialize QTM, Y2R services --- TODO | 4 +- src/core/hle/service/qtm/qtm_c.cpp | 3 ++ src/core/hle/service/qtm/qtm_c.h | 2 + src/core/hle/service/qtm/qtm_s.cpp | 3 ++ src/core/hle/service/qtm/qtm_s.h | 2 + src/core/hle/service/qtm/qtm_sp.cpp | 3 ++ src/core/hle/service/qtm/qtm_sp.h | 2 + src/core/hle/service/qtm/qtm_u.cpp | 3 ++ src/core/hle/service/qtm/qtm_u.h | 2 + src/core/hle/service/y2r_u.cpp | 15 ++++++++ src/core/hle/service/y2r_u.h | 60 +++++++++++++++++++++++++++++ 11 files changed, 97 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 0b7d5dd36..30b51a68c 100644 --- a/TODO +++ b/TODO @@ -105,7 +105,7 @@ ✔ PS @done(20-01-01 00:54) ✔ PTM @done(20-01-01 22:36) ✔ PXI @done(20-01-01 00:53) - ☐ QTM + ✔ QTM @done(20-01-01 22:41) ✔ SOC @done(20-01-01 00:51) ✔ SSL @done(20-01-01 00:48) - ☐ Y2R \ No newline at end of file + ✔ Y2R @done(20-01-01 22:56) \ No newline at end of file diff --git a/src/core/hle/service/qtm/qtm_c.cpp b/src/core/hle/service/qtm/qtm_c.cpp index 84baaba3a..2adc896df 100644 --- a/src/core/hle/service/qtm/qtm_c.cpp +++ b/src/core/hle/service/qtm/qtm_c.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/qtm/qtm_c.h" +SERIALIZE_EXPORT_IMPL(Service::QTM::QTM_C) + namespace Service::QTM { QTM_C::QTM_C() : ServiceFramework("qtm:c", 2) { diff --git a/src/core/hle/service/qtm/qtm_c.h b/src/core/hle/service/qtm/qtm_c.h index c9cad0329..8ad05b6e1 100644 --- a/src/core/hle/service/qtm/qtm_c.h +++ b/src/core/hle/service/qtm/qtm_c.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::QTM + +BOOST_CLASS_EXPORT_KEY(Service::QTM::QTM_C) diff --git a/src/core/hle/service/qtm/qtm_s.cpp b/src/core/hle/service/qtm/qtm_s.cpp index 2af7ced7b..6163ef4dc 100644 --- a/src/core/hle/service/qtm/qtm_s.cpp +++ b/src/core/hle/service/qtm/qtm_s.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/qtm/qtm_s.h" +SERIALIZE_EXPORT_IMPL(Service::QTM::QTM_S) + namespace Service::QTM { QTM_S::QTM_S() : ServiceFramework("qtm:s", 2) { diff --git a/src/core/hle/service/qtm/qtm_s.h b/src/core/hle/service/qtm/qtm_s.h index 72b5e058b..51e1a4bc8 100644 --- a/src/core/hle/service/qtm/qtm_s.h +++ b/src/core/hle/service/qtm/qtm_s.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::QTM + +BOOST_CLASS_EXPORT_KEY(Service::QTM::QTM_S) diff --git a/src/core/hle/service/qtm/qtm_sp.cpp b/src/core/hle/service/qtm/qtm_sp.cpp index bd5a71605..fdfc80003 100644 --- a/src/core/hle/service/qtm/qtm_sp.cpp +++ b/src/core/hle/service/qtm/qtm_sp.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/qtm/qtm_sp.h" +SERIALIZE_EXPORT_IMPL(Service::QTM::QTM_SP) + namespace Service::QTM { QTM_SP::QTM_SP() : ServiceFramework("qtm:sp", 2) { diff --git a/src/core/hle/service/qtm/qtm_sp.h b/src/core/hle/service/qtm/qtm_sp.h index c3f1049a1..3c16dea37 100644 --- a/src/core/hle/service/qtm/qtm_sp.h +++ b/src/core/hle/service/qtm/qtm_sp.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::QTM + +BOOST_CLASS_EXPORT_KEY(Service::QTM::QTM_SP) diff --git a/src/core/hle/service/qtm/qtm_u.cpp b/src/core/hle/service/qtm/qtm_u.cpp index 471692189..84415dde9 100644 --- a/src/core/hle/service/qtm/qtm_u.cpp +++ b/src/core/hle/service/qtm/qtm_u.cpp @@ -2,9 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/qtm/qtm_u.h" +SERIALIZE_EXPORT_IMPL(Service::QTM::QTM_U) + namespace Service::QTM { QTM_U::QTM_U() : ServiceFramework("qtm:u", 2) { diff --git a/src/core/hle/service/qtm/qtm_u.h b/src/core/hle/service/qtm/qtm_u.h index 01bb1e6e0..f6b54c8af 100644 --- a/src/core/hle/service/qtm/qtm_u.h +++ b/src/core/hle/service/qtm/qtm_u.h @@ -15,3 +15,5 @@ public: }; } // namespace Service::QTM + +BOOST_CLASS_EXPORT_KEY(Service::QTM::QTM_U) diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 356ebd843..0c981b545 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_funcs.h" #include "common/logging/log.h" #include "core/core.h" @@ -12,8 +13,22 @@ #include "core/hle/service/y2r_u.h" #include "core/hw/y2r.h" +SERVICE_CONSTRUCT_IMPL(Service::Y2R::Y2R_U) +SERIALIZE_EXPORT_IMPL(Service::Y2R::Y2R_U) + namespace Service::Y2R { +template +void Y2R_U::serialize(Archive& ar, const unsigned int) { + ar& completion_event; + ar& conversion; + ar& dithering_weight_params; + ar& temporal_dithering_enabled; + ar& transfer_end_interrupt_enabled; + ar& spacial_dithering_enabled; +} +SERIALIZE_IMPL(Y2R_U) + static const CoefficientSet standard_coefficients[4] = { {{0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B}}, // ITU_Rec601 {{0x100, 0x193, 0x77, 0x2F, 0x1DB, -0x1933, 0xA7C, -0x1D51}}, // ITU_Rec709 diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h index 332d3b240..1ac675f92 100644 --- a/src/core/hle/service/y2r_u.h +++ b/src/core/hle/service/y2r_u.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/hle/result.h" #include "core/hle/service/service.h" @@ -91,6 +92,16 @@ struct ConversionBuffer { u16 transfer_unit; /// Amount of bytes to be skipped between copying each `transfer_unit` bytes. u16 gap; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& address; + ar& image_size; + ar& transfer_unit; + ar& gap; + } + friend class boost::serialization::access; }; struct ConversionConfiguration { @@ -112,6 +123,26 @@ struct ConversionConfiguration { ResultCode SetInputLineWidth(u16 width); ResultCode SetInputLines(u16 lines); ResultCode SetStandardCoefficient(StandardCoefficient standard_coefficient); + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& input_format; + ar& output_format; + ar& rotation; + ar& block_alignment; + ar& input_line_width; + ar& input_lines; + ar& coefficients; + ar& padding; + ar& alpha; + ar& src_Y; + ar& src_U; + ar& src_V; + ar& src_YUYV; + ar& dst; + } + friend class boost::serialization::access; }; struct DitheringWeightParams { @@ -131,6 +162,28 @@ struct DitheringWeightParams { u16 w3_xOdd_yEven; u16 w3_xEven_yOdd; u16 w3_xOdd_yOdd; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& w0_xEven_yEven; + ar& w0_xOdd_yEven; + ar& w0_xEven_yOdd; + ar& w0_xOdd_yOdd; + ar& w1_xEven_yEven; + ar& w1_xOdd_yEven; + ar& w1_xEven_yOdd; + ar& w1_xOdd_yOdd; + ar& w2_xEven_yEven; + ar& w2_xOdd_yEven; + ar& w2_xEven_yOdd; + ar& w2_xOdd_yOdd; + ar& w3_xEven_yEven; + ar& w3_xOdd_yEven; + ar& w3_xEven_yOdd; + ar& w3_xOdd_yOdd; + } + friend class boost::serialization::access; }; struct ConversionParameters { @@ -301,8 +354,15 @@ private: bool temporal_dithering_enabled = false; bool transfer_end_interrupt_enabled = false; bool spacial_dithering_enabled = false; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; void InstallInterfaces(Core::System& system); } // namespace Service::Y2R + +SERVICE_CONSTRUCT(Service::Y2R::Y2R_U) +BOOST_CLASS_EXPORT_KEY(Service::Y2R::Y2R_U) From 2d2c7218ef3a6651606969219a1909c4fa1b4612 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 2 Jan 2020 00:45:58 +0000 Subject: [PATCH 052/129] Serialize CECD, CFG services --- TODO | 23 ++++++++++++++++++----- src/common/construct.h | 1 + src/core/file_sys/archive_backend.h | 11 ++++++++++- src/core/hle/kernel/shared_page.h | 7 ------- src/core/hle/service/cecd/cecd.cpp | 15 ++++++++++++++- src/core/hle/service/cecd/cecd.h | 9 ++++++++- src/core/hle/service/cecd/cecd_ndm.cpp | 3 +++ src/core/hle/service/cecd/cecd_ndm.h | 6 ++++++ src/core/hle/service/cecd/cecd_s.cpp | 3 +++ src/core/hle/service/cecd/cecd_s.h | 6 ++++++ src/core/hle/service/cecd/cecd_u.cpp | 3 +++ src/core/hle/service/cecd/cecd_u.h | 6 ++++++ src/core/hle/service/cfg/cfg.cpp | 11 +++++++++++ src/core/hle/service/cfg/cfg.h | 8 +++++++- src/core/hle/service/cfg/cfg_i.cpp | 3 +++ src/core/hle/service/cfg/cfg_i.h | 6 ++++++ src/core/hle/service/cfg/cfg_nor.cpp | 3 +++ src/core/hle/service/cfg/cfg_nor.h | 2 ++ src/core/hle/service/cfg/cfg_s.cpp | 3 +++ src/core/hle/service/cfg/cfg_s.h | 6 ++++++ src/core/hle/service/cfg/cfg_u.cpp | 3 +++ src/core/hle/service/cfg/cfg_u.h | 6 ++++++ src/core/hle/service/fs/archive.h | 7 +++++++ 23 files changed, 135 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 30b51a68c..5ea46f2e8 100644 --- a/TODO +++ b/TODO @@ -7,8 +7,22 @@ Memory only ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) ✔ Fix or ignore inverse map @done(19-12-23 12:46) -☐ App loader -☐ Archive manager +✘ App loader @cancelled(20-01-01 22:59) + No relevant state +☐ Archive manager @started(20-01-01 23:03) + ☐ NCCH + ☐ Normal + ☐ Self + ☐ SaveData + ☐ Normal + ☐ Ext + ☐ Other + ☐ Source SD + ☐ System + ☐ SDMC + ☐ Normal + ☐ Write-only + ☐ File refs ☐ Custom texture cache ✘ MMIO @cancelled(20-01-01 01:06) Seems that this whole subsystem is only used in tests @@ -76,9 +90,8 @@ ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) ☐ CAM @started(19-12-26 10:37) Need to check capture_result - ☐ CECD - ☐ Archive backend / file handles - ☐ CFG + ✔ CECD @done(20-01-01 23:58) + ✔ CFG @done(20-01-02 00:44) Also needs archive backend.. ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) ✔ DLP @done(19-12-26 18:02) diff --git a/src/common/construct.h b/src/common/construct.h index 6b2b3ceeb..aba4c7e89 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -1,3 +1,4 @@ +#pragma once #include class construct_access { diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 2df4f98c4..05aa877a3 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -168,7 +168,12 @@ public: } protected: - std::unique_ptr delay_generator; + std::unique_ptr delay_generator; // TODO: Replace with virtual GetOpenDelayNs + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; class ArchiveFactory : NonCopyable { @@ -205,6 +210,10 @@ public: * @return Format information about the archive or error code */ virtual ResultVal GetFormatInfo(const Path& path, u64 program_id) const = 0; + + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index b3e1a48b6..45f9cd348 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -105,13 +105,6 @@ private: std::chrono::seconds init_time; SharedPageDef shared_page; - - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int file_version) { - auto o_shared_page = boost::serialization::binary_object(&shared_page, sizeof(shared_page)); - ar& o_shared_page; - } }; } // namespace SharedPage diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 281f48026..42ac76946 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -24,8 +25,19 @@ #include "core/hle/service/cfg/cfg.h" #include "fmt/format.h" +SERVICE_CONSTRUCT_IMPL(Service::CECD::Module) +SERIALIZE_EXPORT_IMPL(Service::CECD::Module) + namespace Service::CECD { +template +void Module::serialize(Archive& ar, const unsigned int) { + ar& cecd_system_save_data_archive; + ar& cecinfo_event; + ar& change_state_event; +} +SERIALIZE_IMPL(Module) + using CecDataPathType = Module::CecDataPathType; using CecOpenMode = Module::CecOpenMode; using CecSystemInfoType = Module::CecSystemInfoType; @@ -1340,7 +1352,8 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ case CecDataPathType::MboxData: case CecDataPathType::MboxIcon: case CecDataPathType::MboxTitle: - default: {} + default: { + } } } diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 004ef33e7..dd7fff7cb 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -584,7 +584,7 @@ public: */ void GetCecInfoEventHandleSys(Kernel::HLERequestContext& ctx); - private: + protected: std::shared_ptr cecd; }; @@ -613,9 +613,16 @@ private: std::shared_ptr change_state_event; Core::System& system; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; /// Initialize CECD service(s) void InstallInterfaces(Core::System& system); } // namespace Service::CECD + +SERVICE_CONSTRUCT(Service::CECD::Module) +BOOST_CLASS_EXPORT_KEY(Service::CECD::Module) diff --git a/src/core/hle/service/cecd/cecd_ndm.cpp b/src/core/hle/service/cecd/cecd_ndm.cpp index e4366e9c6..4b571283d 100644 --- a/src/core/hle/service/cecd/cecd_ndm.cpp +++ b/src/core/hle/service/cecd/cecd_ndm.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cecd/cecd_ndm.h" +SERIALIZE_EXPORT_IMPL(Service::CECD::CECD_NDM) + namespace Service::CECD { CECD_NDM::CECD_NDM(std::shared_ptr cecd) diff --git a/src/core/hle/service/cecd/cecd_ndm.h b/src/core/hle/service/cecd/cecd_ndm.h index a9fabb1a1..9fd282585 100644 --- a/src/core/hle/service/cecd/cecd_ndm.h +++ b/src/core/hle/service/cecd/cecd_ndm.h @@ -11,6 +11,12 @@ namespace Service::CECD { class CECD_NDM final : public Module::Interface { public: explicit CECD_NDM(std::shared_ptr cecd); + +private: + SERVICE_SERIALIZATION(CECD_NDM, cecd, Module) }; } // namespace Service::CECD + +BOOST_CLASS_EXPORT_KEY(Service::CECD::CECD_NDM) +BOOST_SERIALIZATION_CONSTRUCT(Service::CECD::CECD_NDM) diff --git a/src/core/hle/service/cecd/cecd_s.cpp b/src/core/hle/service/cecd/cecd_s.cpp index 3395c405d..fa838d2af 100644 --- a/src/core/hle/service/cecd/cecd_s.cpp +++ b/src/core/hle/service/cecd/cecd_s.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cecd/cecd_s.h" +SERIALIZE_EXPORT_IMPL(Service::CECD::CECD_S) + namespace Service::CECD { CECD_S::CECD_S(std::shared_ptr cecd) diff --git a/src/core/hle/service/cecd/cecd_s.h b/src/core/hle/service/cecd/cecd_s.h index 6c50b13ba..9c6a7afec 100644 --- a/src/core/hle/service/cecd/cecd_s.h +++ b/src/core/hle/service/cecd/cecd_s.h @@ -11,6 +11,12 @@ namespace Service::CECD { class CECD_S final : public Module::Interface { public: explicit CECD_S(std::shared_ptr cecd); + +private: + SERVICE_SERIALIZATION(CECD_S, cecd, Module) }; } // namespace Service::CECD + +BOOST_CLASS_EXPORT_KEY(Service::CECD::CECD_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::CECD::CECD_S) diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp index 81fcd1019..e8cd7d1c9 100644 --- a/src/core/hle/service/cecd/cecd_u.cpp +++ b/src/core/hle/service/cecd/cecd_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cecd/cecd_u.h" +SERIALIZE_EXPORT_IMPL(Service::CECD::CECD_U) + namespace Service::CECD { CECD_U::CECD_U(std::shared_ptr cecd) diff --git a/src/core/hle/service/cecd/cecd_u.h b/src/core/hle/service/cecd/cecd_u.h index 49ddadb69..31e7a2367 100644 --- a/src/core/hle/service/cecd/cecd_u.h +++ b/src/core/hle/service/cecd/cecd_u.h @@ -11,6 +11,12 @@ namespace Service::CECD { class CECD_U final : public Module::Interface { public: explicit CECD_U(std::shared_ptr cecd); + +private: + SERVICE_SERIALIZATION(CECD_U, cecd, Module) }; } // namespace Service::CECD + +BOOST_CLASS_EXPORT_KEY(Service::CECD::CECD_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::CECD::CECD_U) diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index df6fd2e76..655405e77 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -24,8 +25,18 @@ #include "core/hle/service/cfg/cfg_u.h" #include "core/settings.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::Module) + namespace Service::CFG { +template +void Module::serialize(Archive& ar, const unsigned int) { + ar& cfg_config_file_buffer; + ar& cfg_system_save_data_archive; + ar& preferred_region_code; +} +SERIALIZE_IMPL(Module) + /// The maximum number of block entries that can exist in the config file static const u32 CONFIG_FILE_MAX_BLOCK_ENTRIES = 1479; diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index 6886d513b..58e914583 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h @@ -244,7 +244,7 @@ public: (this->*function)(ctx, id); } - private: + protected: std::shared_ptr cfg; }; @@ -426,6 +426,10 @@ private: std::array cfg_config_file_buffer; std::unique_ptr cfg_system_save_data_archive; u32 preferred_region_code = 0; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; std::shared_ptr GetModule(Core::System& system); @@ -436,3 +440,5 @@ void InstallInterfaces(Core::System& system); std::string GetConsoleIdHash(Core::System& system); } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::Module) diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 624299076..4d3d298a2 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cfg/cfg_i.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::CFG_I) + namespace Service::CFG { CFG_I::CFG_I(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "cfg:i", 23) { diff --git a/src/core/hle/service/cfg/cfg_i.h b/src/core/hle/service/cfg/cfg_i.h index 704eb4a71..ac8ffb990 100644 --- a/src/core/hle/service/cfg/cfg_i.h +++ b/src/core/hle/service/cfg/cfg_i.h @@ -11,6 +11,12 @@ namespace Service::CFG { class CFG_I final : public Module::Interface { public: explicit CFG_I(std::shared_ptr cfg); + +private: + SERVICE_SERIALIZATION(CFG_I, cfg, Module) }; } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::CFG_I) +BOOST_SERIALIZATION_CONSTRUCT(Service::CFG::CFG_I) diff --git a/src/core/hle/service/cfg/cfg_nor.cpp b/src/core/hle/service/cfg/cfg_nor.cpp index 413548313..0dd21076d 100644 --- a/src/core/hle/service/cfg/cfg_nor.cpp +++ b/src/core/hle/service/cfg/cfg_nor.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cfg/cfg_nor.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::CFG_NOR) + namespace Service::CFG { CFG_NOR::CFG_NOR() : ServiceFramework("cfg:nor", 23) { diff --git a/src/core/hle/service/cfg/cfg_nor.h b/src/core/hle/service/cfg/cfg_nor.h index 3dace92bd..1eca85a05 100644 --- a/src/core/hle/service/cfg/cfg_nor.h +++ b/src/core/hle/service/cfg/cfg_nor.h @@ -14,3 +14,5 @@ public: }; } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::CFG_NOR) diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index a211dae05..773a412f7 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cfg/cfg_s.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::CFG_S) + namespace Service::CFG { CFG_S::CFG_S(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "cfg:s", 23) { diff --git a/src/core/hle/service/cfg/cfg_s.h b/src/core/hle/service/cfg/cfg_s.h index 7f135b357..d0cbc7a18 100644 --- a/src/core/hle/service/cfg/cfg_s.h +++ b/src/core/hle/service/cfg/cfg_s.h @@ -11,6 +11,12 @@ namespace Service::CFG { class CFG_S final : public Module::Interface { public: explicit CFG_S(std::shared_ptr cfg); + +private: + SERVICE_SERIALIZATION(CFG_S, cfg, Module) }; } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::CFG_S) +BOOST_SERIALIZATION_CONSTRUCT(Service::CFG::CFG_S) diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 6aa862f82..bcc590bf8 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "core/hle/service/cfg/cfg_u.h" +SERIALIZE_EXPORT_IMPL(Service::CFG::CFG_U) + namespace Service::CFG { CFG_U::CFG_U(std::shared_ptr cfg) : Module::Interface(std::move(cfg), "cfg:u", 23) { diff --git a/src/core/hle/service/cfg/cfg_u.h b/src/core/hle/service/cfg/cfg_u.h index 8b48e963e..906377124 100644 --- a/src/core/hle/service/cfg/cfg_u.h +++ b/src/core/hle/service/cfg/cfg_u.h @@ -11,6 +11,12 @@ namespace Service::CFG { class CFG_U final : public Module::Interface { public: explicit CFG_U(std::shared_ptr cfg); + +private: + SERVICE_SERIALIZATION(CFG_U, cfg, Module) }; } // namespace Service::CFG + +BOOST_CLASS_EXPORT_KEY(Service::CFG::CFG_U) +BOOST_SERIALIZATION_CONSTRUCT(Service::CFG::CFG_U) diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 862e74980..29965491b 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -260,6 +260,13 @@ private: */ std::unordered_map> handle_map; ArchiveHandle next_handle = 1; + + template + void serialize(Archive& ar, const unsigned int) { + ar& id_code_map; + ar& handle_map; + ar& next_handle; + } }; } // namespace Service::FS From 2bf5b464609348e786a068074d41e74fb5331a35 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 2 Jan 2020 23:34:26 +0000 Subject: [PATCH 053/129] Basic archive backend serialization --- TODO | 23 +++++++------ src/core/file_sys/archive_extsavedata.cpp | 3 ++ src/core/file_sys/archive_extsavedata.h | 12 +++++++ src/core/file_sys/archive_ncch.cpp | 5 +++ src/core/file_sys/archive_ncch.h | 34 ++++++++++++++++++- src/core/file_sys/archive_other_savedata.cpp | 4 +++ src/core/file_sys/archive_other_savedata.h | 23 +++++++++++-- src/core/file_sys/archive_savedata.cpp | 3 ++ src/core/file_sys/archive_savedata.h | 12 ++++++- src/core/file_sys/archive_sdmc.cpp | 4 +++ src/core/file_sys/archive_sdmc.h | 21 ++++++++++++ src/core/file_sys/archive_sdmcwriteonly.cpp | 4 +++ src/core/file_sys/archive_sdmcwriteonly.h | 18 ++++++++++ .../file_sys/archive_source_sd_savedata.cpp | 3 ++ .../file_sys/archive_source_sd_savedata.h | 11 ++++++ src/core/file_sys/archive_systemsavedata.cpp | 3 ++ src/core/file_sys/archive_systemsavedata.h | 11 ++++++ src/core/file_sys/file_backend.h | 7 +++- 18 files changed, 185 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index 5ea46f2e8..c1f5e49cd 100644 --- a/TODO +++ b/TODO @@ -10,19 +10,20 @@ ✘ App loader @cancelled(20-01-01 22:59) No relevant state ☐ Archive manager @started(20-01-01 23:03) - ☐ NCCH - ☐ Normal + ☐ NCCH @started(20-01-02 22:50) + ✔ Normal @done(20-01-02 22:50) ☐ Self - ☐ SaveData - ☐ Normal - ☐ Ext - ☐ Other - ☐ Source SD - ☐ System - ☐ SDMC - ☐ Normal - ☐ Write-only + ✔ SaveData @started(20-01-02 23:03) @done(20-01-02 23:27) @lasted(25m) + ✔ Normal @done(20-01-02 23:03) + ✔ Ext @done(20-01-02 23:26) + ✔ Other @done(20-01-02 23:21) + ✔ Source SD @done(20-01-02 23:03) + ✔ System @done(20-01-02 23:13) + ✔ SDMC @done(20-01-02 23:34) + ✔ Normal @done(20-01-02 23:34) + ✔ Write-only @done(20-01-02 23:34) ☐ File refs + ☐ Replace delay generator with virtual fns ☐ Custom texture cache ✘ MMIO @cancelled(20-01-01 01:06) Seems that this whole subsystem is only used in tests diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index efcdb2d7f..22084b690 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -19,6 +20,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_ExtSaveData) + namespace FileSys { /** diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index 7dc345c84..b00e1633d 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -54,6 +56,14 @@ private: /// Returns a path with the correct SaveIdHigh value for Shared extdata paths. Path GetCorrectedPath(const Path& path); + + ArchiveFactory_ExtSaveData() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& shared; + ar& mount_point; + } + friend class boost::serialization::access; }; /** @@ -94,3 +104,5 @@ std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low); } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_ExtSaveData) diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index 06fe69622..789547f0e 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp @@ -8,6 +8,7 @@ #include #include #include "bad_word_list.app.romfs.h" +#include "common/archives.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -28,6 +29,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::NCCHArchive) +SERIALIZE_EXPORT_IMPL(FileSys::NCCHFile) +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_NCCH) + namespace FileSys { struct NCCHArchivePath { diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 28d9ff044..52ae827c3 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include "core/file_sys/archive_backend.h" #include "core/file_sys/file_backend.h" #include "core/hle/result.h" @@ -63,6 +66,17 @@ public: protected: u64 title_id; Service::FS::MediaType media_type; + +private: + NCCHArchive() = default; // NOTE: If the public ctor has behaviour, need to replace this with + // *_construct_data + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& title_id; + ar& media_type; + } + friend class boost::serialization::access; }; // File backend for NCCH files @@ -81,7 +95,16 @@ public: void Flush() const override {} private: - std::vector file_buffer; + NCCHFile() = default; // NOTE: If the public ctor has behaviour, need to replace this with + // *_construct_data + std::vector file_buffer; // TODO: Replace with file ref for serialization + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& file_buffer; + } + friend class boost::serialization::access; }; /// File system interface to the NCCH archive @@ -97,6 +120,15 @@ public: ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, u64 program_id) override; ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::NCCHArchive) +BOOST_CLASS_EXPORT_KEY(FileSys::NCCHFile) +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_NCCH) diff --git a/src/core/file_sys/archive_other_savedata.cpp b/src/core/file_sys/archive_other_savedata.cpp index 1c3b071ba..d4f8debc4 100644 --- a/src/core/file_sys/archive_other_savedata.cpp +++ b/src/core/file_sys/archive_other_savedata.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "core/file_sys/archive_other_savedata.h" #include "core/file_sys/errors.h" #include "core/hle/kernel/process.h" @@ -12,6 +13,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_OtherSaveDataPermitted) +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_OtherSaveDataGeneral) + namespace FileSys { // TODO(wwylele): The storage info in exheader should be checked before accessing these archives diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index e3e8f83c3..a9deae95a 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -4,6 +4,8 @@ #pragma once +#include +#include #include "core/file_sys/archive_source_sd_savedata.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -27,8 +29,15 @@ public: ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; + std::string mount_point; // TODO: Remove, unused? std::shared_ptr sd_savedata_source; + + ArchiveFactory_OtherSaveDataPermitted() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sd_savedata_source; + } + friend class boost::serialization::access; }; /// File system interface to the OtherSaveDataGeneral archive @@ -47,8 +56,18 @@ public: ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; + std::string mount_point; // TODO: Remove, unused? std::shared_ptr sd_savedata_source; + + ArchiveFactory_OtherSaveDataGeneral() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sd_savedata_source; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_OtherSaveDataPermitted) +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_OtherSaveDataGeneral) diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index c1046e2f5..fc4bd34fa 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "core/core.h" #include "core/file_sys/archive_savedata.h" #include "core/hle/kernel/process.h" @@ -10,6 +11,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SaveData) + namespace FileSys { ArchiveFactory_SaveData::ArchiveFactory_SaveData( diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 591a3b900..3ebe94a63 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -4,6 +4,7 @@ #pragma once +#include #include "core/file_sys/archive_source_sd_savedata.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -27,8 +28,17 @@ public: ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; + std::string mount_point; // TODO: Remove this? seems unused std::shared_ptr sd_savedata_source; + + ArchiveFactory_SaveData() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sd_savedata_source; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SaveData) diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index d2269fe7c..1c5118320 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/archive_sdmc.h" @@ -15,6 +16,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::SDMCArchive) +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SDMC) + namespace FileSys { class SDMCDelayGenerator : public DelayGenerator { diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 41d7b7c59..2e0abf44b 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -6,6 +6,9 @@ #include #include +#include +#include +#include #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -42,6 +45,14 @@ public: protected: ResultVal> OpenFileBase(const Path& path, const Mode& mode) const; std::string mount_point; + + SDMCArchive() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& mount_point; + } + friend class boost::serialization::access; }; /// File system interface to the SDMC archive @@ -66,6 +77,16 @@ public: private: std::string sdmc_directory; + + ArchiveFactory_SDMC() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sdmc_directory; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::SDMCArchive) +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMC) diff --git a/src/core/file_sys/archive_sdmcwriteonly.cpp b/src/core/file_sys/archive_sdmcwriteonly.cpp index 74552d751..ea64dc864 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.cpp +++ b/src/core/file_sys/archive_sdmcwriteonly.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/file_util.h" #include "core/file_sys/archive_sdmcwriteonly.h" #include "core/file_sys/directory_backend.h" @@ -13,6 +14,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::SDMCWriteOnlyArchive) +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SDMCWriteOnly) + namespace FileSys { class SDMCWriteOnlyDelayGenerator : public DelayGenerator { diff --git a/src/core/file_sys/archive_sdmcwriteonly.h b/src/core/file_sys/archive_sdmcwriteonly.h index 8191f053f..2ba504aa7 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.h +++ b/src/core/file_sys/archive_sdmcwriteonly.h @@ -31,6 +31,14 @@ public: const Mode& mode) const override; ResultVal> OpenDirectory(const Path& path) const override; + +private: + SDMCWriteOnlyArchive() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; /// File system interface to the SDMC write-only archive @@ -55,6 +63,16 @@ public: private: std::string sdmc_directory; + + ArchiveFactory_SDMCWriteOnly() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& sdmc_directory; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::SDMCWriteOnlyArchive) +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMCWriteOnly) diff --git a/src/core/file_sys/archive_source_sd_savedata.cpp b/src/core/file_sys/archive_source_sd_savedata.cpp index 0b8072b96..9afbfd73c 100644 --- a/src/core/file_sys/archive_source_sd_savedata.cpp +++ b/src/core/file_sys/archive_source_sd_savedata.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/file_util.h" #include "common/logging/log.h" #include "core/file_sys/archive_source_sd_savedata.h" @@ -13,6 +14,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveSource_SDSaveData) + namespace FileSys { namespace { diff --git a/src/core/file_sys/archive_source_sd_savedata.h b/src/core/file_sys/archive_source_sd_savedata.h index b5fe43cc1..4ac028a3d 100644 --- a/src/core/file_sys/archive_source_sd_savedata.h +++ b/src/core/file_sys/archive_source_sd_savedata.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -27,6 +29,15 @@ public: private: std::string mount_point; + + ArchiveSource_SDSaveData() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& mount_point; + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveSource_SDSaveData) diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp index cef42e561..ecfb34219 100644 --- a/src/core/file_sys/archive_systemsavedata.cpp +++ b/src/core/file_sys/archive_systemsavedata.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/file_util.h" #include "core/file_sys/archive_systemsavedata.h" @@ -17,6 +18,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SystemSaveData) + namespace FileSys { std::string GetSystemSaveDataPath(const std::string& mount_point, const Path& path) { diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index e72ecce3a..cf18cab89 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -31,6 +33,13 @@ public: private: std::string base_path; + + ArchiveFactory_SystemSaveData() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& base_path; + } + friend class boost::serialization::access; }; /** @@ -60,3 +69,5 @@ std::string GetSystemSaveDataContainerPath(const std::string& mount_point); Path ConstructSystemSaveDataBinaryPath(u32 high, u32 low); } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SystemSaveData) diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index c865c98e8..03dff156d 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -89,7 +89,12 @@ public: virtual void Flush() const = 0; protected: - std::unique_ptr delay_generator; + std::unique_ptr delay_generator; // TODO: replace with virtual Get*DelayNs + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys From 558e710e170030e1e9bc8f0105f571b44a43bb79 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 3 Jan 2020 14:00:10 +0000 Subject: [PATCH 054/129] Finished archives; remove pod.h --- TODO | 17 +++++++++++------ src/common/pod.h | 17 ----------------- src/core/file_sys/archive_backend.h | 4 +++- src/core/file_sys/archive_ncch.cpp | 1 - src/core/file_sys/archive_ncch.h | 8 -------- src/core/file_sys/archive_selfncch.cpp | 3 +++ src/core/file_sys/archive_selfncch.h | 6 +++++- src/core/file_sys/delay_generator.cpp | 3 +++ src/core/file_sys/delay_generator.h | 8 ++++++++ src/core/file_sys/file_backend.h | 7 +------ src/core/hle/result.h | 9 +++++++-- src/core/hw/gpu.h | 10 ++++++++-- src/core/hw/lcd.h | 12 ++++++++++-- src/video_core/shader/shader.h | 15 +++++++++++++-- 14 files changed, 72 insertions(+), 48 deletions(-) delete mode 100644 src/common/pod.h diff --git a/TODO b/TODO index c1f5e49cd..bc4003d44 100644 --- a/TODO +++ b/TODO @@ -9,10 +9,11 @@ ✔ Fix or ignore inverse map @done(19-12-23 12:46) ✘ App loader @cancelled(20-01-01 22:59) No relevant state -☐ Archive manager @started(20-01-01 23:03) - ☐ NCCH @started(20-01-02 22:50) +✔ Archive manager @started(20-01-01 23:03) @done(20-01-03 13:23) @lasted(1d14h20m40s) + NB that 'FileBackend' classes are not persistent + ✔ NCCH @started(20-01-02 22:50) @done(20-01-03 12:35) @lasted(13h45m50s) ✔ Normal @done(20-01-02 22:50) - ☐ Self + ✔ Self @done(20-01-03 12:35) ✔ SaveData @started(20-01-02 23:03) @done(20-01-02 23:27) @lasted(25m) ✔ Normal @done(20-01-02 23:03) ✔ Ext @done(20-01-02 23:26) @@ -22,8 +23,12 @@ ✔ SDMC @done(20-01-02 23:34) ✔ Normal @done(20-01-02 23:34) ✔ Write-only @done(20-01-02 23:34) - ☐ File refs - ☐ Replace delay generator with virtual fns + ✘ IVFC @cancelled(20-01-03 13:22) + Seems IVFCArchive is never used.. which is good because it has a file reference! + ✘ File refs @cancelled(20-01-03 13:22) + Not needed as nothing serializes file buffers + ✘ Replace delay generator with virtual fns @cancelled(20-01-03 13:16) + While they have no state, the extra refactoring here is unneeded ☐ Custom texture cache ✘ MMIO @cancelled(20-01-01 01:06) Seems that this whole subsystem is only used in tests @@ -35,7 +40,7 @@ For now, let the settings just be whatever they are ✘ Telemetry session @cancelled(20-01-01 01:12) Doesn't need to be serialized here -☐ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE +✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) ☐ Review constructor/initialization code ✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) diff --git a/src/common/pod.h b/src/common/pod.h deleted file mode 100644 index bb7095417..000000000 --- a/src/common/pod.h +++ /dev/null @@ -1,17 +0,0 @@ -#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/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 05aa877a3..756613a30 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -172,7 +172,9 @@ protected: private: template - void serialize(Archive& ar, const unsigned int) {} + void serialize(Archive& ar, const unsigned int) { + ar& delay_generator; + } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index 789547f0e..636bb81ed 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp @@ -30,7 +30,6 @@ // FileSys namespace SERIALIZE_EXPORT_IMPL(FileSys::NCCHArchive) -SERIALIZE_EXPORT_IMPL(FileSys::NCCHFile) SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_NCCH) namespace FileSys { diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 52ae827c3..0a3f95b5c 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -98,13 +98,6 @@ private: NCCHFile() = default; // NOTE: If the public ctor has behaviour, need to replace this with // *_construct_data std::vector file_buffer; // TODO: Replace with file ref for serialization - - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - ar& file_buffer; - } - friend class boost::serialization::access; }; /// File system interface to the NCCH archive @@ -130,5 +123,4 @@ private: } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::NCCHArchive) -BOOST_CLASS_EXPORT_KEY(FileSys::NCCHFile) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_NCCH) diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index 0f8dd8065..214ad7c08 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/swap.h" @@ -16,6 +17,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_SelfNCCH) + namespace FileSys { enum class SelfNCCHFilePathType : u32 { diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index 779e7e75a..de7fd75e0 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -44,7 +45,10 @@ public: private: /// Mapping of ProgramId -> NCCHData - std::unordered_map ncch_data; + std::unordered_map + ncch_data; // TODO: Remove this, or actually set the values here }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SelfNCCH) diff --git a/src/core/file_sys/delay_generator.cpp b/src/core/file_sys/delay_generator.cpp index 04f877f83..137e63d69 100644 --- a/src/core/file_sys/delay_generator.cpp +++ b/src/core/file_sys/delay_generator.cpp @@ -3,8 +3,11 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "core/file_sys/delay_generator.h" +SERIALIZE_EXPORT_IMPL(FileSys::DefaultDelayGenerator) + namespace FileSys { DelayGenerator::~DelayGenerator() = default; diff --git a/src/core/file_sys/delay_generator.h b/src/core/file_sys/delay_generator.h index d530f2ee2..8fa92ac41 100644 --- a/src/core/file_sys/delay_generator.h +++ b/src/core/file_sys/delay_generator.h @@ -5,6 +5,8 @@ #pragma once #include +#include +#include #include "common/common_types.h" namespace FileSys { @@ -16,6 +18,10 @@ public: virtual u64 GetOpenDelayNs() = 0; // TODO (B3N30): Add getter for all other file/directory io operations +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; class DefaultDelayGenerator : public DelayGenerator { @@ -25,3 +31,5 @@ public: }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::DefaultDelayGenerator); diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index 03dff156d..c865c98e8 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -89,12 +89,7 @@ public: virtual void Flush() const = 0; protected: - std::unique_ptr delay_generator; // TODO: replace with virtual Get*DelayNs - -private: - template - void serialize(Archive& ar, const unsigned int) {} - friend class boost::serialization::access; + std::unique_ptr delay_generator; }; } // namespace FileSys diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 4168ce36c..40a71e369 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -6,11 +6,11 @@ #include #include +#include #include "common/assert.h" #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 @@ -227,7 +227,12 @@ union ResultCode { return is_error.ExtractValue(raw) == 1; } - SERIALIZE_AS_POD +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& raw; + } + friend class boost::serialization::access; }; constexpr bool operator==(const ResultCode& a, const ResultCode& b) { diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 980b48cd7..fcf7a3137 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -6,11 +6,12 @@ #include #include +#include +#include #include "common/assert.h" #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/pod.h" namespace Memory { class MemorySystem; @@ -298,7 +299,12 @@ private: return register_value * 8; } - SERIALIZE_AS_POD + template + void serialize(Archive& ar, const unsigned int) { + auto obj = boost::serialization::binary_object(this, sizeof(Regs)); + ar& obj; + } + friend class boost::serialization::access; }; 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 ecc9ecea4..9667c7c4c 100644 --- a/src/core/hw/lcd.h +++ b/src/core/hw/lcd.h @@ -6,10 +6,10 @@ #include #include +#include #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)) @@ -52,7 +52,15 @@ struct Regs { return content[index]; } - SERIALIZE_AS_POD +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& color_fill_top.raw; + ar& backlight_top; + ar& color_fill_bottom.raw; + ar& backlight_bottom; + } + friend class boost::serialization::access; }; static_assert(std::is_standard_layout::value, "Structure does not use standard layout"); diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index a6e42b3bf..6a5a33419 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -15,7 +16,6 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/hash.h" -#include "common/pod.h" #include "common/vector_math.h" #include "video_core/pica_types.h" #include "video_core/regs_rasterizer.h" @@ -65,7 +65,18 @@ struct OutputVertex { static OutputVertex FromAttributeBuffer(const RasterizerRegs& regs, const AttributeBuffer& output); - SERIALIZE_AS_POD +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& pos; + ar& quat; + ar& tc0; + ar& tc1; + ar& tc0_w; + ar& view; + ar& tc2; + } + friend class boost::serialization::access; }; #define ASSERT_POS(var, pos) \ static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong " \ From 26e90a99cd25685ee96184a8e21ff010913d8895 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 3 Jan 2020 17:19:59 +0000 Subject: [PATCH 055/129] Added basic UI; misc memory fixes --- TODO | 13 +++++++++---- src/citra_qt/main.cpp | 24 ++++++++++++++++++++++++ src/citra_qt/main.h | 2 ++ src/citra_qt/main.ui | 18 ++++++++++++++++++ src/common/CMakeLists.txt | 1 - src/core/hle/kernel/config_mem.h | 3 +-- src/core/hle/kernel/ipc.cpp | 12 ++++++------ src/core/hle/kernel/ipc.h | 12 +++++------- src/core/hle/kernel/process.cpp | 2 +- src/core/hle/kernel/process.h | 2 +- src/core/hw/gpu.h | 3 +-- src/core/memory.cpp | 19 ++++++++----------- src/core/memory.h | 15 ++++++++++++++- 13 files changed, 90 insertions(+), 36 deletions(-) diff --git a/TODO b/TODO index bc4003d44..ad64a0084 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,11 @@ ☐ Save/load UI + ✔ Basic version @done(20-01-03 15:27) + ☐ Multiple slots etc. ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ☐ Page tables - ☐ Skip N3DS RAM if unused + ✘ Skip N3DS RAM if unused @cancelled(20-01-03 15:26) + Since no n3ds support, leave this for now ✔ DSP @done(19-12-28 16:57) Memory only ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) @@ -67,14 +70,16 @@ ✔ Mutex @done(19-08-13 16:43) ✔ Object @done(19-08-13 15:41) ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) - ☐ Code set @started(19-12-22 18:41) + ✔ Code set @started(19-12-22 18:41) @done(20-01-03 15:15) @lasted(1w4d20h34m2s) Needs a way to reference loaded images (so we don't serialize the entire ROM as well) + ☐ Serialize codeset with an apploader reference instead ✔ Resource limit @done(19-08-13 16:43) ✔ Semaphore @done(19-08-13 16:44) ✔ Server port @done(19-08-13 16:44) ✔ Server session @done(19-08-13 16:44) - ☐ Mapped buffer context - This may not be needed! + ✔ Mapped buffer context @done(20-01-03 15:25) + This is needed because IPC can take as long as it takes + Changed the unique_ptr to vector ✔ Session @done(19-08-13 16:44) ☐ Shared memory @started(19-12-22 21:20) Need to figure out backing memory (a u8*) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index daccbb083..08e3cac02 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include @@ -606,6 +607,8 @@ void GMainWindow::ConnectMenuEvents() { &GMainWindow::OnMenuReportCompatibility); connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); connect(ui.action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats); + connect(ui.action_Save, &QAction::triggered, this, &GMainWindow::OnSave); + connect(ui.action_Load, &QAction::triggered, this, &GMainWindow::OnLoad); // View connect(ui.action_Single_Window_Mode, &QAction::triggered, this, @@ -1033,6 +1036,8 @@ void GMainWindow::ShutdownGame() { ui.action_Stop->setEnabled(false); ui.action_Restart->setEnabled(false); ui.action_Cheats->setEnabled(false); + ui.action_Save->setEnabled(false); + ui.action_Load->setEnabled(false); ui.action_Load_Amiibo->setEnabled(false); ui.action_Remove_Amiibo->setEnabled(false); ui.action_Report_Compatibility->setEnabled(false); @@ -1343,6 +1348,8 @@ void GMainWindow::OnStartGame() { ui.action_Stop->setEnabled(true); ui.action_Restart->setEnabled(true); ui.action_Cheats->setEnabled(true); + ui.action_Save->setEnabled(true); + ui.action_Load->setEnabled(true); ui.action_Load_Amiibo->setEnabled(true); ui.action_Report_Compatibility->setEnabled(true); ui.action_Enable_Frame_Advancing->setEnabled(true); @@ -1496,6 +1503,23 @@ void GMainWindow::OnCheats() { cheat_dialog.exec(); } +void GMainWindow::OnSave() { + Core::System& system{Core::System::GetInstance()}; + auto fs = std::ofstream("save0.citrasave"); + emu_thread->SetRunning(false); + Core::System::GetInstance().Save(fs); + emu_thread->SetRunning(true); +} + +void GMainWindow::OnLoad() { + if (QFileInfo("save0.citrasave").exists()) { + auto fs = std::ifstream("save0.citrasave"); + emu_thread->SetRunning(false); + Core::System::GetInstance().Load(fs); + emu_thread->SetRunning(true); + } +} + void GMainWindow::OnConfigure() { ConfigureDialog configureDialog(this, hotkey_registry, !multiplayer_state->IsHostingPublicRoom()); diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 91d7eed1b..1858d5988 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -163,6 +163,8 @@ private slots: void OnStartGame(); void OnPauseGame(); void OnStopGame(); + void OnSave(); + void OnLoad(); void OnMenuReportCompatibility(); /// Called whenever a user selects a game in the game list widget. void OnGameListLoadFile(QString game_path); diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index 6011b0e7f..c0c38e4c8 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -88,6 +88,8 @@ + + @@ -217,6 +219,22 @@ &Stop + + + false + + + Save + + + + + false + + + Load + + FAQ diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 39ddffbcc..c6294c464 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -86,7 +86,6 @@ 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/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index e4e895516..ef1c889a0 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -61,8 +61,7 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { - auto o_config_mem = boost::serialization::binary_object(&config_mem, sizeof(config_mem)); - ar& o_config_mem; + ar& boost::serialization::make_binary_object(&config_mem, sizeof(config_mem)); } }; diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index 3dacb9831..e45b87e49 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -193,19 +193,19 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy // TODO(Subv): Perform permission checks. // Reserve a page of memory before the mapped buffer - auto reserve_buffer = std::make_unique(Memory::PAGE_SIZE); + auto reserve_buffer = std::vector(Memory::PAGE_SIZE); dst_process->vm_manager.MapBackingMemoryToBase( - Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.get(), + Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); - auto buffer = std::make_unique(num_pages * Memory::PAGE_SIZE); - memory.ReadBlock(*src_process, source_address, buffer.get() + page_offset, size); + auto buffer = std::vector(num_pages * Memory::PAGE_SIZE); + memory.ReadBlock(*src_process, source_address, buffer.data() + page_offset, size); // Map the page(s) into the target process' address space. target_address = dst_process->vm_manager .MapBackingMemoryToBase(Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, - buffer.get(), num_pages * Memory::PAGE_SIZE, + buffer.data(), num_pages * Memory::PAGE_SIZE, Kernel::MemoryState::Shared) .Unwrap(); @@ -213,7 +213,7 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy // Reserve a page of memory after the mapped buffer dst_process->vm_manager.MapBackingMemoryToBase( - Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.get(), + Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); mapped_buffer_context.push_back({permissions, size, source_address, diff --git a/src/core/hle/kernel/ipc.h b/src/core/hle/kernel/ipc.h index 2c69617d4..f9fd1a00e 100644 --- a/src/core/hle/kernel/ipc.h +++ b/src/core/hle/kernel/ipc.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include "common/common_types.h" #include "core/hle/ipc.h" #include "core/hle/kernel/thread.h" @@ -25,8 +25,8 @@ struct MappedBufferContext { VAddr source_address; VAddr target_address; - std::unique_ptr buffer; - std::unique_ptr reserve_buffer; + std::vector buffer; + std::vector reserve_buffer; private: template @@ -35,10 +35,8 @@ private: ar& size; ar& source_address; ar& target_address; - // TODO: Check whether we need these. If we do, add a field for the size and/or change to a - // 'vector' - // ar & buffer; - // ar & reserve_buffer; + ar& buffer; + ar& reserve_buffer; } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 78b695e97..18de2cd91 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -29,7 +29,7 @@ template void Process::serialize(Archive& ar, const unsigned int file_version) { ar& boost::serialization::base_object(*this); ar& handle_table; - ar& codeset; + ar& codeset; // TODO: Replace with apploader reference ar& resource_limit; ar& svc_access_mask; ar& handle_table_size; diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index f9aa76c67..576cf7e15 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -133,7 +133,7 @@ private: template void serialize(Archive& ar, const unsigned int file_version) { ar& boost::serialization::base_object(*this); - // TODO: memory reference + ar& memory; ar& segments; ar& entrypoint; ar& name; diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index fcf7a3137..9169bf9ae 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -301,8 +301,7 @@ private: template void serialize(Archive& ar, const unsigned int) { - auto obj = boost::serialization::binary_object(this, sizeof(Regs)); - ar& obj; + ar& boost::serialization::make_binary_object(this, sizeof(Regs)); } friend class boost::serialization::access; }; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 6a41ca957..92bce0b69 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -84,18 +84,15 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { - // TODO: Skip n3ds ram when not used? - auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); - auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); - auto s_extra = - boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); - ar& s_fcram; - ar& s_vram; - ar& s_extra; + ar& boost::serialization::make_binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); + ar& boost::serialization::make_binary_object(vram.get(), Memory::VRAM_SIZE); + // TODO: When n3ds support is added, put this back in + // ar& boost::serialization::make_binary_object(n3ds_extra_ram.get(), + // Memory::N3DS_EXTRA_RAM_SIZE); + ar& current_page_table; ar& cache_marker; - // TODO: How the hell to do page tables.. - // ar & page_table_list; - // ar & current_page_table; + ar& page_table_list; + // dsp is set from Core::System at startup } }; diff --git a/src/core/memory.h b/src/core/memory.h index aac57af26..564191d89 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -9,7 +9,9 @@ #include #include #include -#include "boost/serialization/access.hpp" +#include +#include +#include #include "common/common_types.h" #include "core/mmio.h" @@ -54,12 +56,14 @@ struct SpecialRegion { u32 size; MMIORegionPointer handler; +private: template void serialize(Archive& ar, const unsigned int file_version) { ar& base; ar& size; ar& handler; } + friend class boost::serialization::access; }; /** @@ -86,6 +90,15 @@ struct PageTable { * the corresponding entry in `pointers` MUST be set to null. */ std::array attributes; + +private: + template + void serialize(Archive& ar, const unsigned int) { + // TODO: Pointers; same as VMA backing regions we need to serialize the u8* + ar& special_regions; + ar& attributes; + } + friend class boost::serialization::access; }; /// Physical memory regions as seen from the ARM11 From cf985631e04bd1363b483f28ac020c2d5b4c8883 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 4 Jan 2020 00:40:32 +0000 Subject: [PATCH 056/129] Minor tidying up --- TODO | 8 ++++---- src/core/core.cpp | 8 ++++++-- src/core/hle/service/cam/cam.h | 3 +-- src/core/hle/service/gsp/gsp.cpp | 6 +++++- src/core/hle/service/gsp/gsp.h | 2 ++ src/core/hle/service/gsp/gsp_gpu.h | 1 + src/core/memory.cpp | 13 ++++++++----- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index ad64a0084..d72a79712 100644 --- a/TODO +++ b/TODO @@ -4,8 +4,7 @@ ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ☐ Page tables - ✘ Skip N3DS RAM if unused @cancelled(20-01-03 15:26) - Since no n3ds support, leave this for now + ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) ✔ DSP @done(19-12-28 16:57) Memory only ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) @@ -99,7 +98,7 @@ ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) ✔ APT @done(19-12-25 21:41) ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) - ☐ CAM @started(19-12-26 10:37) + ✔ CAM @started(19-12-26 10:37) @done(20-01-03 23:38) @lasted(1w1d13h1m50s) Need to check capture_result ✔ CECD @done(20-01-01 23:58) ✔ CFG @done(20-01-02 00:44) @@ -111,7 +110,8 @@ ✔ FRD @done(19-12-26 19:09) ✔ FS @done(19-12-27 11:46) ✔ GSP @done(19-12-30 12:45) - ☐ Fix the global weak_ptr to gsp + ✔ Fix the global weak_ptr to gsp @done(20-01-04 00:29) + Didn't quite 'fix' it but worked around it ✔ HID @done(19-12-30 14:46) ✔ HTTP @done(19-12-30 15:18) ✔ IR @done(19-12-30 16:06) diff --git a/src/core/core.cpp b/src/core/core.cpp index 5b9b4fca0..a05e2a636 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -31,6 +31,7 @@ #include "core/hle/kernel/process.h" #include "core/hle/kernel/thread.h" #include "core/hle/service/fs/archive.h" +#include "core/hle/service/gsp/gsp.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" #include "core/hw/gpu.h" @@ -213,8 +214,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique(*memory, *timing, - [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique( + *memory, *timing, [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -413,6 +414,9 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar & dsp_core->GetDspMemory(); ar&* memory.get(); ar&* kernel.get(); + + // This needs to be set from somewhere - might as well be here! + Service::GSP::SetGlobalModule(*this); } void System::Save(std::ostream& stream) const { diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 876e2e185..9c56407a3 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -830,8 +830,7 @@ private: ar& completion_event; ar& buffer_error_interrupt_event; ar& vsync_interrupt_event; - // TODO: Check if this is ever needed: - // ar & capture_result; + // Ignore capture_result. In-progress captures might be affected but this is OK. ar& dest_process; ar& dest; ar& dest_size; diff --git a/src/core/hle/service/gsp/gsp.cpp b/src/core/hle/service/gsp/gsp.cpp index 3d3f497b2..c360d895c 100644 --- a/src/core/hle/service/gsp/gsp.cpp +++ b/src/core/hle/service/gsp/gsp.cpp @@ -10,7 +10,7 @@ namespace Service::GSP { -static std::weak_ptr gsp_gpu; // TODO: Fix this for the love of god +static std::weak_ptr gsp_gpu; void SignalInterrupt(InterruptId interrupt_id) { auto gpu = gsp_gpu.lock(); @@ -27,4 +27,8 @@ void InstallInterfaces(Core::System& system) { std::make_shared()->InstallAsService(service_manager); } +void SetGlobalModule(Core::System& system) { + gsp_gpu = system.ServiceManager().GetService("gsp::Gpu"); +} + } // namespace Service::GSP diff --git a/src/core/hle/service/gsp/gsp.h b/src/core/hle/service/gsp/gsp.h index 4cde19e93..a4dd84f27 100644 --- a/src/core/hle/service/gsp/gsp.h +++ b/src/core/hle/service/gsp/gsp.h @@ -23,4 +23,6 @@ namespace Service::GSP { void SignalInterrupt(InterruptId interrupt_id); void InstallInterfaces(Core::System& system); + +void SetGlobalModule(Core::System& system); } // namespace Service::GSP diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index d1f2c0742..6194f0446 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -444,6 +444,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& shared_memory; ar& active_thread_id; ar& first_initialization; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 92bce0b69..cba5867eb 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -18,6 +18,7 @@ #include "core/hle/kernel/process.h" #include "core/hle/lock.h" #include "core/memory.h" +#include "core/settings.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" @@ -84,15 +85,17 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::make_binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); + bool save_n3ds_ram = Settings::values.is_new_3ds; + ar& save_n3ds_ram; ar& boost::serialization::make_binary_object(vram.get(), Memory::VRAM_SIZE); - // TODO: When n3ds support is added, put this back in - // ar& boost::serialization::make_binary_object(n3ds_extra_ram.get(), - // Memory::N3DS_EXTRA_RAM_SIZE); - ar& current_page_table; + ar& boost::serialization::make_binary_object( + fcram.get(), save_n3ds_ram ? Memory::FCRAM_N3DS_SIZE : Memory::FCRAM_SIZE); + ar& boost::serialization::make_binary_object( + n3ds_extra_ram.get(), save_n3ds_ram ? Memory::N3DS_EXTRA_RAM_SIZE : 0); ar& cache_marker; ar& page_table_list; // dsp is set from Core::System at startup + // current page table set from current process? } }; From 65d96bf6c158b9e8a864947a9c60608fc097e078 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 4 Jan 2020 22:39:54 +0000 Subject: [PATCH 057/129] Changed u8* to MemoryRef --- TODO | 11 ++- src/common/CMakeLists.txt | 4 +- src/common/memory_ref.cpp | 4 + src/common/memory_ref.h | 112 +++++++++++++++++++++++ src/core/arm/dynarmic/arm_dynarmic.cpp | 2 +- src/core/hle/kernel/config_mem.h | 11 ++- src/core/hle/kernel/ipc.cpp | 18 ++-- src/core/hle/kernel/ipc.h | 6 +- src/core/hle/kernel/kernel.cpp | 4 +- src/core/hle/kernel/kernel.h | 4 +- src/core/hle/kernel/memory.cpp | 26 +++--- src/core/hle/kernel/process.cpp | 8 +- src/core/hle/kernel/shared_memory.cpp | 4 +- src/core/hle/kernel/shared_memory.h | 5 +- src/core/hle/kernel/shared_page.cpp | 12 +++ src/core/hle/kernel/shared_page.h | 24 ++++- src/core/hle/kernel/thread.cpp | 2 +- src/core/hle/kernel/vm_manager.cpp | 22 ++--- src/core/hle/kernel/vm_manager.h | 46 +++------- src/core/memory.cpp | 122 +++++++++++++++++++++---- src/core/memory.h | 79 ++++++++++++++-- src/tests/core/arm/arm_test_common.cpp | 3 +- src/tests/core/hle/kernel/hle_ipc.cpp | 97 +++++++++++--------- src/tests/core/memory/vm_manager.cpp | 37 ++++---- 24 files changed, 486 insertions(+), 177 deletions(-) create mode 100644 src/common/memory_ref.cpp create mode 100644 src/common/memory_ref.h diff --git a/TODO b/TODO index d72a79712..4bb80f8d5 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,7 @@ ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ☐ Page tables + Need to change uses to shared_ptr ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) ✔ DSP @done(19-12-28 16:57) Memory only @@ -44,6 +45,7 @@ Doesn't need to be serialized here ✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) ☐ Review constructor/initialization code +☐ Review core timing events ✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) @@ -60,7 +62,7 @@ ✔ Address arbiter @done(19-08-13 16:40) ✔ Client port @done(19-08-13 16:40) ✔ Client session @done(19-08-13 16:40) - ✔ Config mem @done(19-08-13 16:40) + ✔ Config mem @done(20-01-04 21:09) ✔ Event @done(19-12-22 18:44) ✔ Handle table @done(19-08-13 16:42) ✔ HLE IPC @done(19-12-23 00:36) @@ -80,16 +82,15 @@ This is needed because IPC can take as long as it takes Changed the unique_ptr to vector ✔ Session @done(19-08-13 16:44) - ☐ Shared memory @started(19-12-22 21:20) + ✔ Shared memory @started(19-12-22 21:20) @done(20-01-04 21:09) @lasted(1w5d23h49m26s) Need to figure out backing memory (a u8*) - ✘ Shared page @started(19-08-13 16:44) @cancelled(19-12-22 11:19) - Not needed right now as shared_page is read-only and derived from other data + ✔ Shared page @done(20-01-04 21:09) ✔ SVC @done(19-12-22 21:32) Nothing to do - all data is constant ☐ Thread @started(19-08-13 16:45) This requires refactoring wakeup_callback to be an object ref ✔ Timer @done(19-08-13 16:45) - ☐ VM Manager @started(19-08-13 16:46) + ✔ VM Manager @started(19-08-13 16:46) @done(20-01-04 21:09) @lasted(20w4d5h23m42s) Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) ☐ Service @started(19-12-23 12:49) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index c6294c464..ea117d440 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -80,6 +80,8 @@ add_library(common STATIC logging/text_formatter.cpp logging/text_formatter.h math_util.h + memory_ref.h + memory_ref.cpp microprofile.cpp microprofile.h microprofileui.h @@ -127,7 +129,7 @@ endif() create_target_directory_groups(common) -target_link_libraries(common PUBLIC fmt microprofile) +target_link_libraries(common PUBLIC fmt microprofile Boost::boost Boost::serialization) target_link_libraries(common PRIVATE libzstd_static) if (ARCHITECTURE_x86_64) target_link_libraries(common PRIVATE xbyak) diff --git a/src/common/memory_ref.cpp b/src/common/memory_ref.cpp new file mode 100644 index 000000000..170784ff8 --- /dev/null +++ b/src/common/memory_ref.cpp @@ -0,0 +1,4 @@ +#include "common/archives.h" +#include "common/memory_ref.h" + +SERIALIZE_EXPORT_IMPL(BufferMem) diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h new file mode 100644 index 000000000..5aaaef468 --- /dev/null +++ b/src/common/memory_ref.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "common/assert.h" +#include "common/common_types.h" + +/// Abstract host-side memory - for example a static buffer, or local vector +class BackingMem { +public: + virtual ~BackingMem() = default; + virtual u8* GetPtr() = 0; + virtual u32 GetSize() const = 0; +}; + +/// Backing memory implemented by a local buffer +class BufferMem : public BackingMem { +public: + BufferMem() = default; + BufferMem(u32 size) : data(std::vector(size)) {} + + virtual u8* GetPtr() { + return data.data(); + } + + virtual u32 GetSize() const { + return static_cast(data.size()); + } + + std::vector& Vector() { + return data; + } + +private: + std::vector data; + + template + void serialize(Archive& ar, const unsigned int) { + ar& data; + } + friend class boost::serialization::access; +}; + +BOOST_CLASS_EXPORT_KEY(BufferMem); + +/// A managed reference to host-side memory. Fast enough to be used everywhere instead of u8* +/// Supports serialization. +class MemoryRef { +public: + MemoryRef() = default; + MemoryRef(std::nullptr_t) {} + MemoryRef(std::shared_ptr backing_mem_) + : backing_mem(std::move(backing_mem_)), offset(0) { + Init(); + } + MemoryRef(std::shared_ptr backing_mem_, u32 offset_) + : backing_mem(std::move(backing_mem_)), offset(offset_) { + ASSERT(offset < backing_mem->GetSize()); + Init(); + } + inline operator u8*() { + return cptr; + } + inline u8* GetPtr() { + return cptr; + } + inline operator bool() const { + return cptr != nullptr; + } + inline const u8* GetPtr() const { + return cptr; + } + inline u32 GetSize() const { + return csize; + } + inline void operator+=(u32 offset_by) { + ASSERT(offset_by < csize); + offset += offset_by; + Init(); + } + inline MemoryRef operator+(u32 offset_by) const { + ASSERT(offset_by < csize); + return MemoryRef(backing_mem, offset + offset_by); + } + inline u8* operator+(std::size_t offset_by) const { + ASSERT(offset_by < csize); + return cptr + offset_by; + } + +private: + std::shared_ptr backing_mem; + u32 offset; + // Cached values for speed + u8* cptr; + u32 csize; + + void Init() { + cptr = backing_mem->GetPtr() + offset; + csize = static_cast(backing_mem->GetSize() - offset); + } + + template + void serialize(Archive& ar, const unsigned int) { + ar& backing_mem; + ar& offset; + Init(); + } + friend class boost::serialization::access; +}; diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index a422db6af..eb3295956 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -298,7 +298,7 @@ void ARM_Dynarmic::PageTableChanged() { std::unique_ptr ARM_Dynarmic::MakeJit() { Dynarmic::A32::UserConfig config; config.callbacks = cb.get(); - config.page_table = ¤t_page_table->pointers; + config.page_table = ¤t_page_table->GetPointerArray(); config.coprocessors[15] = std::make_shared(interpreter_state); config.define_unpredictable_behaviour = true; return std::make_unique(config); diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index ef1c889a0..0ec67fb5e 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -12,6 +12,7 @@ #include #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/memory_ref.h" #include "common/swap.h" #include "core/memory.h" @@ -50,11 +51,19 @@ struct ConfigMemDef { static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, "Config Memory structure size is wrong"); -class Handler { +class Handler : public BackingMem { public: Handler(); ConfigMemDef& GetConfigMem(); + virtual u8* GetPtr() { + return static_cast(static_cast(&config_mem)); + } + + virtual u32 GetSize() const { + return sizeof(config_mem); + } + private: ConfigMemDef config_mem; diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index e45b87e49..e39732c14 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -4,6 +4,7 @@ #include #include "common/alignment.h" +#include "common/memory_ref.h" #include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/kernel/handle_table.h" @@ -193,28 +194,29 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy // TODO(Subv): Perform permission checks. // Reserve a page of memory before the mapped buffer - auto reserve_buffer = std::vector(Memory::PAGE_SIZE); + std::shared_ptr reserve_buffer = + std::make_shared(Memory::PAGE_SIZE); dst_process->vm_manager.MapBackingMemoryToBase( - Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), + Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer, Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); - auto buffer = std::vector(num_pages * Memory::PAGE_SIZE); - memory.ReadBlock(*src_process, source_address, buffer.data() + page_offset, size); + std::shared_ptr buffer = + std::make_shared(num_pages * Memory::PAGE_SIZE); + memory.ReadBlock(*src_process, source_address, buffer->GetPtr() + page_offset, size); // Map the page(s) into the target process' address space. target_address = dst_process->vm_manager .MapBackingMemoryToBase(Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, - buffer.data(), num_pages * Memory::PAGE_SIZE, - Kernel::MemoryState::Shared) + buffer, buffer->GetSize(), Kernel::MemoryState::Shared) .Unwrap(); cmd_buf[i++] = target_address + page_offset; // Reserve a page of memory after the mapped buffer dst_process->vm_manager.MapBackingMemoryToBase( - Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), - Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); + Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer, + reserve_buffer->GetSize(), Kernel::MemoryState::Reserved); mapped_buffer_context.push_back({permissions, size, source_address, target_address + page_offset, std::move(buffer), diff --git a/src/core/hle/kernel/ipc.h b/src/core/hle/kernel/ipc.h index f9fd1a00e..2a5fcb4b2 100644 --- a/src/core/hle/kernel/ipc.h +++ b/src/core/hle/kernel/ipc.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include "common/common_types.h" #include "core/hle/ipc.h" #include "core/hle/kernel/thread.h" @@ -25,8 +25,8 @@ struct MappedBufferContext { VAddr source_address; VAddr target_address; - std::vector buffer; - std::vector reserve_buffer; + std::shared_ptr buffer; + std::shared_ptr reserve_buffer; private: template diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 7edef2505..6fef2d4de 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -116,8 +116,8 @@ void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { ar& process_list; ar& current_process; ar&* thread_manager.get(); - ar&* config_mem_handler.get(); - // Shared page data is read-only at the moment, so doesn't need serializing + ar& config_mem_handler; + ar& shared_page_handler; // Deliberately don't include debugger info to allow debugging through loads } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 6ca3267fb..0a527d8b4 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -282,8 +282,8 @@ private: std::unique_ptr thread_manager; - std::unique_ptr config_mem_handler; - std::unique_ptr shared_page_handler; + std::shared_ptr config_mem_handler; + std::shared_ptr shared_page_handler; std::unique_ptr ipc_recorder; diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp index e4aae5d13..04d09fa46 100644 --- a/src/core/hle/kernel/memory.cpp +++ b/src/core/hle/kernel/memory.cpp @@ -57,7 +57,7 @@ void KernelSystem::MemoryInit(u32 mem_type) { // We must've allocated the entire FCRAM by the end ASSERT(base == Memory::FCRAM_SIZE); - config_mem_handler = std::make_unique(); + config_mem_handler = std::make_shared(); auto& config_mem = config_mem_handler->GetConfigMem(); config_mem.app_mem_type = mem_type; // app_mem_malloc does not always match the configured size for memory_region[0]: in case the @@ -66,7 +66,7 @@ void KernelSystem::MemoryInit(u32 mem_type) { config_mem.sys_mem_alloc = memory_regions[1].size; config_mem.base_mem_alloc = memory_regions[2].size; - shared_page_handler = std::make_unique(timing); + shared_page_handler = std::make_shared(timing); } MemoryRegionInfo* KernelSystem::GetMemoryRegion(MemoryRegion region) { @@ -127,7 +127,7 @@ void KernelSystem::HandleSpecialMapping(VMManager& address_space, const AddressM return; } - u8* target_pointer = memory.GetPhysicalPointer(area->paddr_base + offset_into_region); + auto target_pointer = memory.GetPhysicalRef(area->paddr_base + offset_into_region); // TODO(yuriks): This flag seems to have some other effect, but it's unknown what MemoryState memory_state = mapping.unk_flag ? MemoryState::Static : MemoryState::IO; @@ -140,20 +140,16 @@ void KernelSystem::HandleSpecialMapping(VMManager& address_space, const AddressM } void KernelSystem::MapSharedPages(VMManager& address_space) { - auto cfg_mem_vma = - address_space - .MapBackingMemory(Memory::CONFIG_MEMORY_VADDR, - reinterpret_cast(&config_mem_handler->GetConfigMem()), - Memory::CONFIG_MEMORY_SIZE, MemoryState::Shared) - .Unwrap(); + auto cfg_mem_vma = address_space + .MapBackingMemory(Memory::CONFIG_MEMORY_VADDR, {config_mem_handler}, + Memory::CONFIG_MEMORY_SIZE, MemoryState::Shared) + .Unwrap(); address_space.Reprotect(cfg_mem_vma, VMAPermission::Read); - auto shared_page_vma = - address_space - .MapBackingMemory(Memory::SHARED_PAGE_VADDR, - reinterpret_cast(&shared_page_handler->GetSharedPage()), - Memory::SHARED_PAGE_SIZE, MemoryState::Shared) - .Unwrap(); + auto shared_page_vma = address_space + .MapBackingMemory(Memory::SHARED_PAGE_VADDR, {shared_page_handler}, + Memory::SHARED_PAGE_SIZE, MemoryState::Shared) + .Unwrap(); address_space.Reprotect(shared_page_vma, VMAPermission::Read); } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 18de2cd91..c181bd01a 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -223,7 +223,7 @@ ResultVal Process::HeapAllocate(VAddr target, u32 size, VMAPermission per std::fill(kernel.memory.GetFCRAMPointer(interval.lower()), kernel.memory.GetFCRAMPointer(interval.upper()), 0); auto vma = vm_manager.MapBackingMemory(interval_target, - kernel.memory.GetFCRAMPointer(interval.lower()), + kernel.memory.GetFCRAMRef(interval.lower()), interval_size, memory_state); ASSERT(vma.Succeeded()); vm_manager.Reprotect(vma.Unwrap(), perms); @@ -251,7 +251,7 @@ ResultCode Process::HeapFree(VAddr target, u32 size) { // Free heaps block by block CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(target, size)); for (const auto [backing_memory, block_size] : backing_blocks) { - memory_region->Free(kernel.memory.GetFCRAMOffset(backing_memory), block_size); + memory_region->Free(kernel.memory.GetFCRAMOffset(backing_memory.GetPtr()), block_size); } ResultCode result = vm_manager.UnmapRange(target, size); @@ -295,9 +295,9 @@ ResultVal Process::LinearAllocate(VAddr target, u32 size, VMAPermission p } } - u8* backing_memory = kernel.memory.GetFCRAMPointer(physical_offset); + auto backing_memory = kernel.memory.GetFCRAMRef(physical_offset); - std::fill(backing_memory, backing_memory + size, 0); + std::fill(backing_memory.GetPtr(), backing_memory.GetPtr() + size, 0); auto vma = vm_manager.MapBackingMemory(target, backing_memory, size, MemoryState::Continuous); ASSERT(vma.Succeeded()); vm_manager.Reprotect(vma.Unwrap(), perms); diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 55c374dc5..23f67f733 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -48,7 +48,7 @@ ResultVal> KernelSystem::CreateSharedMemory( ASSERT_MSG(offset, "Not enough space in region to allocate shared memory!"); std::fill(memory.GetFCRAMPointer(*offset), memory.GetFCRAMPointer(*offset + size), 0); - shared_memory->backing_blocks = {{memory.GetFCRAMPointer(*offset), size}}; + shared_memory->backing_blocks = {{memory.GetFCRAMRef(*offset), size}}; shared_memory->holding_memory += MemoryRegionInfo::Interval(*offset, *offset + size); shared_memory->linear_heap_phys_offset = *offset; @@ -90,7 +90,7 @@ std::shared_ptr KernelSystem::CreateSharedMemoryForApplet( shared_memory->other_permissions = other_permissions; for (const auto& interval : backing_blocks) { shared_memory->backing_blocks.push_back( - {memory.GetFCRAMPointer(interval.lower()), interval.upper() - interval.lower()}); + {memory.GetFCRAMRef(interval.lower()), interval.upper() - interval.lower()}); std::fill(memory.GetFCRAMPointer(interval.lower()), memory.GetFCRAMPointer(interval.upper()), 0); } diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index f2fa1a728..aa2be05a6 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -8,6 +8,7 @@ #include #include #include "common/common_types.h" +#include "common/memory_ref.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/result.h" @@ -87,7 +88,7 @@ private: /// during creation. PAddr linear_heap_phys_offset = 0; /// Backing memory for this shared memory block. - std::vector> backing_blocks; + std::vector> backing_blocks; /// Size of the memory block. Page-aligned. u32 size = 0; /// Permission restrictions applied to the process which created the block. @@ -109,7 +110,7 @@ private: template void serialize(Archive& ar, const unsigned int file_version) { ar& linear_heap_phys_offset; - // TODO: backing blocks u8* (this is always FCRAM I think) + ar& backing_blocks; ar& size; ar& permissions; ar& other_permissions; diff --git a/src/core/hle/kernel/shared_page.cpp b/src/core/hle/kernel/shared_page.cpp index 7067aace8..f7b02993f 100644 --- a/src/core/hle/kernel/shared_page.cpp +++ b/src/core/hle/kernel/shared_page.cpp @@ -4,6 +4,7 @@ #include #include +#include "common/archives.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/kernel/shared_page.h" @@ -13,6 +14,17 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// +namespace boost::serialization { + +template +void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int) { + ::new (t) SharedPage::Handler(Core::System::GetInstance().CoreTiming()); +} +template void load_construct_data(iarchive& ar, SharedPage::Handler* t, + const unsigned int); + +} // namespace boost::serialization + namespace SharedPage { static std::chrono::seconds GetInitTime() { diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index 45f9cd348..7b1f7ed16 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -17,6 +17,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/memory_ref.h" #include "common/swap.h" #include "core/memory.h" @@ -83,7 +84,7 @@ struct SharedPageDef { static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, "Shared page structure size is wrong"); -class Handler { +class Handler : public BackingMem { public: Handler(Core::Timing& timing); @@ -97,6 +98,14 @@ public: SharedPageDef& GetSharedPage(); + virtual u8* GetPtr() { + return static_cast(static_cast(&shared_page)); + } + + virtual u32 GetSize() const { + return sizeof(shared_page); + } + private: u64 GetSystemTime() const; void UpdateTimeCallback(u64 userdata, int cycles_late); @@ -105,6 +114,19 @@ private: std::chrono::seconds init_time; SharedPageDef shared_page; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::make_binary_object(&shared_page, sizeof(shared_page)); + } + friend class boost::serialization::access; }; } // namespace SharedPage + +namespace boost::serialization { + +template +void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int); + +} // namespace boost::serialization diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index c3c5da7d4..1af2d4f4d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -382,7 +382,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, // Map the page to the current process' address space. vm_manager.MapBackingMemory(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, - memory.GetFCRAMPointer(*offset), Memory::PAGE_SIZE, + memory.GetFCRAMRef(*offset), Memory::PAGE_SIZE, MemoryState::Locked); } diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 3280f99e9..1b9875ee2 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -27,7 +27,8 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { type != next.type) { return false; } - if (type == VMAType::BackingMemory && backing_memory + size != next.backing_memory) { + if (type == VMAType::BackingMemory && + backing_memory.GetPtr() + size != next.backing_memory.GetPtr()) { return false; } if (type == VMAType::MMIO && paddr + size != next.paddr) { @@ -50,8 +51,7 @@ void VMManager::Reset() { initial_vma.size = MAX_ADDRESS; vma_map.emplace(initial_vma.base, initial_vma); - page_table.pointers.fill(nullptr); - page_table.attributes.fill(Memory::PageType::Unmapped); + page_table.Clear(); UpdatePageTableForVMA(initial_vma); } @@ -64,7 +64,7 @@ VMManager::VMAHandle VMManager::FindVMA(VAddr target) const { } } -ResultVal VMManager::MapBackingMemoryToBase(VAddr base, u32 region_size, u8* memory, +ResultVal VMManager::MapBackingMemoryToBase(VAddr base, u32 region_size, MemoryRef memory, u32 size, MemoryState state) { // Find the first Free VMA. @@ -93,9 +93,9 @@ ResultVal VMManager::MapBackingMemoryToBase(VAddr base, u32 region_size, return MakeResult(target); } -ResultVal VMManager::MapBackingMemory(VAddr target, u8* memory, u32 size, - MemoryState state) { - ASSERT(memory != nullptr); +ResultVal VMManager::MapBackingMemory(VAddr target, MemoryRef memory, + u32 size, MemoryState state) { + ASSERT(memory.GetPtr() != nullptr); // This is the appropriately sized VMA that will turn into our allocation. CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size)); @@ -359,9 +359,9 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { } } -ResultVal>> VMManager::GetBackingBlocksForRange(VAddr address, - u32 size) { - std::vector> backing_blocks; +ResultVal>> VMManager::GetBackingBlocksForRange(VAddr address, + u32 size) { + std::vector> backing_blocks; VAddr interval_target = address; while (interval_target != address + size) { auto vma = FindVMA(interval_target); @@ -372,7 +372,7 @@ ResultVal>> VMManager::GetBackingBlocksForRange( VAddr interval_end = std::min(address + size, vma->second.base + vma->second.size); u32 interval_size = interval_end - interval_target; - u8* backing_memory = vma->second.backing_memory + (interval_target - vma->second.base); + auto backing_memory = vma->second.backing_memory + (interval_target - vma->second.base); backing_blocks.push_back({backing_memory, interval_size}); interval_target += interval_size; diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 5fd6d8740..880d9ec81 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -11,6 +11,7 @@ #include #include #include "common/common_types.h" +#include "common/memory_ref.h" #include "core/hle/result.h" #include "core/memory.h" #include "core/mmio.h" @@ -73,7 +74,7 @@ struct VirtualMemoryArea { // Settings for type = BackingMemory /// Pointer backing this VMA. It will not be destroyed or freed when the VMA is removed. - u8* backing_memory = nullptr; + MemoryRef backing_memory{}; // Settings for type = MMIO /// Physical address of the register area this VMA maps to. @@ -92,8 +93,7 @@ private: ar& type; ar& permissions; ar& meminfo_state; - // TODO: backing memory ref - // backing memory can be: Physical/FCRAM pointer, config mem, shared page + ar& backing_memory; ar& paddr; ar& mmio_handler; } @@ -151,7 +151,7 @@ public: * @param state MemoryState tag to attach to the VMA. * @returns The address at which the memory was mapped. */ - ResultVal MapBackingMemoryToBase(VAddr base, u32 region_size, u8* memory, u32 size, + ResultVal MapBackingMemoryToBase(VAddr base, u32 region_size, MemoryRef memory, u32 size, MemoryState state); /** * Maps an unmanaged host memory pointer at a given address. @@ -161,7 +161,8 @@ public: * @param size Size of the mapping. * @param state MemoryState tag to attach to the VMA. */ - ResultVal MapBackingMemory(VAddr target, u8* memory, u32 size, MemoryState state); + ResultVal MapBackingMemory(VAddr target, MemoryRef memory, u32 size, + MemoryState state); /** * Maps a memory-mapped IO region at a given address. @@ -203,38 +204,14 @@ public: void LogLayout(Log::Level log_level) const; /// Gets a list of backing memory blocks for the specified range - ResultVal>> GetBackingBlocksForRange(VAddr address, u32 size); + ResultVal>> GetBackingBlocksForRange(VAddr address, + u32 size); /// Each VMManager has its own page table, which is set as the main one when the owning process /// is scheduled. Memory::PageTable page_table; private: - friend class boost::serialization::access; - template - void save(Archive& ar, const unsigned int file_version) const { - ar& vma_map; - for (int i = 0; i < page_table.pointers.size(); i++) { - ar << memory.GetFCRAMOffset(page_table.pointers[i]); - } - ar& page_table.special_regions; - ar& page_table.attributes; - } - - template - void load(Archive& ar, const unsigned int file_version) { - ar& vma_map; - for (int i = 0; i < page_table.pointers.size(); i++) { - u32 offset{}; - ar >> offset; - page_table.pointers[i] = memory.GetFCRAMPointer(offset); - } - ar& page_table.special_regions; - ar& page_table.attributes; - } - - BOOST_SERIALIZATION_SPLIT_MEMBER() - using VMAIter = decltype(vma_map)::iterator; /// Converts a VMAHandle to a mutable VMAIter. @@ -271,5 +248,12 @@ private: void UpdatePageTableForVMA(const VirtualMemoryArea& vma); Memory::MemorySystem& memory; + + template + void serialize(Archive& ar, const unsigned int) { + ar& vma_map; + ar& page_table; + } + friend class boost::serialization::access; }; } // namespace Kernel diff --git a/src/core/memory.cpp b/src/core/memory.cpp index cba5867eb..9762619f0 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -14,6 +14,7 @@ #include "common/swap.h" #include "core/arm/arm_interface.h" #include "core/core.h" +#include "core/global.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" #include "core/hle/lock.h" @@ -22,8 +23,19 @@ #include "video_core/renderer_base.h" #include "video_core/video_core.h" +SERIALIZE_EXPORT_IMPL(Memory::MemorySystem::BackingMemImpl) +SERIALIZE_EXPORT_IMPL(Memory::MemorySystem::BackingMemImpl) +SERIALIZE_EXPORT_IMPL(Memory::MemorySystem::BackingMemImpl) +SERIALIZE_EXPORT_IMPL(Memory::MemorySystem::BackingMemImpl) + namespace Memory { +void PageTable::Clear() { + pointers.raw.fill(nullptr); + pointers.refs.fill(MemoryRef()); + attributes.fill(PageType::Unmapped); +} + class RasterizerCacheMarker { public: void Mark(VAddr addr, bool cached) { @@ -81,6 +93,43 @@ public: AudioCore::DspInterface* dsp = nullptr; + std::shared_ptr fcram_mem; + std::shared_ptr vram_mem; + std::shared_ptr n3ds_extra_ram_mem; + std::shared_ptr dsp_mem; + + MemorySystem::Impl(); + + virtual u8* GetPtr(Region r) { + switch (r) { + case Region::VRAM: + return vram.get(); + case Region::DSP: + return dsp->GetDspMemory().data(); + case Region::FCRAM: + return fcram.get(); + case Region::N3DS: + return n3ds_extra_ram.get(); + default: + UNREACHABLE(); + } + } + + virtual u32 GetSize(Region r) const { + switch (r) { + case Region::VRAM: + return VRAM_SIZE; + case Region::DSP: + return DSP_RAM_SIZE; + case Region::FCRAM: + return FCRAM_N3DS_SIZE; + case Region::N3DS: + return N3DS_EXTRA_RAM_SIZE; + default: + UNREACHABLE(); + } + } + private: friend class boost::serialization::access; template @@ -95,10 +144,41 @@ private: ar& cache_marker; ar& page_table_list; // dsp is set from Core::System at startup - // current page table set from current process? + // TODO: current_page_table + ar& fcram_mem; + ar& vram_mem; + ar& n3ds_extra_ram_mem; + ar& dsp_mem; } }; +// We use this rather than BufferMem because we don't want new objects to be allocated when +// deserializing. This avoids unnecessary memory thrashing. +template +class MemorySystem::BackingMemImpl : public BackingMem { +public: + BackingMemImpl() : system(Core::Global().Memory()) {} + virtual u8* GetPtr() { + return system.impl->GetPtr(R); + } + virtual u32 GetSize() const { + return system.impl->GetSize(R); + } + +private: + MemorySystem& system; + + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; +}; + +MemorySystem::Impl::Impl() + : fcram_mem(std::make_shared>()), + vram_mem(std::make_shared>()), + n3ds_extra_ram_mem(std::make_shared>()), + dsp_mem(std::make_shared>()) {} + MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; @@ -117,8 +197,9 @@ PageTable* MemorySystem::GetCurrentPageTable() const { return impl->current_page_table; } -void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, u8* memory, PageType type) { - LOG_DEBUG(HW_Memory, "Mapping {} onto {:08X}-{:08X}", (void*)memory, base * PAGE_SIZE, +void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef memory, + PageType type) { + LOG_DEBUG(HW_Memory, "Mapping {} onto {:08X}-{:08X}", (void*)memory.GetPtr(), base * PAGE_SIZE, (base + size) * PAGE_SIZE); RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, @@ -143,7 +224,7 @@ void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, u8* memor } } -void MemorySystem::MapMemoryRegion(PageTable& page_table, VAddr base, u32 size, u8* target) { +void MemorySystem::MapMemoryRegion(PageTable& page_table, VAddr base, u32 size, MemoryRef target) { ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:08X}", size); ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:08X}", base); MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, PageType::Memory); @@ -164,15 +245,15 @@ void MemorySystem::UnmapRegion(PageTable& page_table, VAddr base, u32 size) { MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Unmapped); } -u8* MemorySystem::GetPointerForRasterizerCache(VAddr addr) { +MemoryRef MemorySystem::GetPointerForRasterizerCache(VAddr addr) { if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) { - return impl->fcram.get() + (addr - LINEAR_HEAP_VADDR); + return {impl->fcram_mem, addr - LINEAR_HEAP_VADDR}; } if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) { - return impl->fcram.get() + (addr - NEW_LINEAR_HEAP_VADDR); + return {impl->fcram_mem, addr - NEW_LINEAR_HEAP_VADDR}; } if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) { - return impl->vram.get() + (addr - VRAM_VADDR); + return {impl->vram_mem, addr - VRAM_VADDR}; } UNREACHABLE(); } @@ -271,7 +352,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) { bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) { auto& page_table = process.vm_manager.page_table; - const u8* page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; + auto page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; if (page_pointer) return true; @@ -323,6 +404,10 @@ std::string MemorySystem::ReadCString(VAddr vaddr, std::size_t max_length) { } u8* MemorySystem::GetPhysicalPointer(PAddr address) { + return GetPhysicalRef(address); +} + +MemoryRef MemorySystem::GetPhysicalRef(PAddr address) { struct MemoryArea { PAddr paddr_base; u32 size; @@ -349,25 +434,25 @@ u8* MemorySystem::GetPhysicalPointer(PAddr address) { u32 offset_into_region = address - area->paddr_base; - u8* target_pointer = nullptr; + std::shared_ptr target_mem = nullptr; switch (area->paddr_base) { case VRAM_PADDR: - target_pointer = impl->vram.get() + offset_into_region; + target_mem = impl->vram_mem; break; case DSP_RAM_PADDR: - target_pointer = impl->dsp->GetDspMemory().data() + offset_into_region; + target_mem = impl->dsp_mem; break; case FCRAM_PADDR: - target_pointer = impl->fcram.get() + offset_into_region; + target_mem = impl->fcram_mem; break; case N3DS_EXTRA_RAM_PADDR: - target_pointer = impl->n3ds_extra_ram.get() + offset_into_region; + target_mem = impl->n3ds_extra_ram_mem; break; default: UNREACHABLE(); } - return target_pointer; + return {target_mem, offset_into_region}; } /// For a rasterizer-accessible PAddr, gets a list of all possible VAddr @@ -781,7 +866,7 @@ void WriteMMIO(MMIORegionPointer mmio_handler, VAddr addr, const u64 data) mmio_handler->Write64(addr, data); } -u32 MemorySystem::GetFCRAMOffset(u8* pointer) { +u32 MemorySystem::GetFCRAMOffset(const u8* pointer) { ASSERT(pointer >= impl->fcram.get() && pointer <= impl->fcram.get() + Memory::FCRAM_N3DS_SIZE); return pointer - impl->fcram.get(); } @@ -791,6 +876,11 @@ u8* MemorySystem::GetFCRAMPointer(u32 offset) { return impl->fcram.get() + offset; } +MemoryRef MemorySystem::GetFCRAMRef(u32 offset) { + ASSERT(offset <= Memory::FCRAM_N3DS_SIZE); + return MemoryRef(impl->fcram_mem, offset); +} + void MemorySystem::SetDSP(AudioCore::DspInterface& dsp) { impl->dsp = &dsp; } diff --git a/src/core/memory.h b/src/core/memory.h index 564191d89..0dc98a428 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -13,6 +13,7 @@ #include #include #include "common/common_types.h" +#include "common/memory_ref.h" #include "core/mmio.h" class ARM_Interface; @@ -77,7 +78,48 @@ struct PageTable { * Array of memory pointers backing each page. An entry can only be non-null if the * corresponding entry in the `attributes` array is of type `Memory`. */ - std::array pointers; + + // The reason for this rigmarole is to keep the 'raw' and 'refs' arrays in sync. + // We need 'raw' for dynarmic and 'refs' for serialization + struct Pointers { + + struct Entry { + Entry(Pointers& pointers_, VAddr idx_) : pointers(pointers_), idx(idx_) {} + + inline void operator=(MemoryRef value) { + pointers.refs[idx] = value; + pointers.raw[idx] = value.GetPtr(); + } + + inline operator u8*() { + return pointers.raw[idx]; + } + + private: + Pointers& pointers; + VAddr idx; + }; + + inline Entry operator[](VAddr idx) { + return Entry(*this, idx); + } + + inline u8* operator[](VAddr idx) const { + return raw[idx]; + } + + inline Entry operator[](std::size_t idx) { + return Entry(*this, static_cast(idx)); + } + + private: + std::array raw; + + std::array refs; + + friend struct PageTable; + }; + Pointers pointers; /** * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of @@ -91,12 +133,21 @@ struct PageTable { */ std::array attributes; + inline std::array& GetPointerArray() { + return pointers.raw; + } + + void Clear(); + private: template void serialize(Archive& ar, const unsigned int) { - // TODO: Pointers; same as VMA backing regions we need to serialize the u8* + ar& pointers.refs; ar& special_regions; ar& attributes; + for (auto i = 0; i < PAGE_TABLE_NUM_ENTRIES; i++) { + pointers.raw[i] = pointers.refs[i].GetPtr(); + } } friend class boost::serialization::access; }; @@ -142,6 +193,8 @@ enum : PAddr { FCRAM_N3DS_PADDR_END = FCRAM_PADDR + FCRAM_N3DS_SIZE, }; +enum class Region { FCRAM, VRAM, DSP, N3DS }; + /// Virtual user-space memory regions enum : VAddr { /// Where the application text, data and bss reside. @@ -249,7 +302,7 @@ public: * @param size The amount of bytes to map. Must be page-aligned. * @param target Buffer with the memory backing the mapping. Must be of length at least `size`. */ - void MapMemoryRegion(PageTable& page_table, VAddr base, u32 size, u8* target); + void MapMemoryRegion(PageTable& page_table, VAddr base, u32 size, MemoryRef target); /** * Maps a region of the emulated process address space as a IO region. @@ -293,16 +346,21 @@ public: */ u8* GetPhysicalPointer(PAddr address); + MemoryRef GetPhysicalRef(PAddr address); + u8* GetPointer(VAddr vaddr); bool IsValidPhysicalAddress(PAddr paddr); /// Gets offset in FCRAM from a pointer inside FCRAM range - u32 GetFCRAMOffset(u8* pointer); + u32 GetFCRAMOffset(const u8* pointer); /// Gets pointer in FCRAM with given offset u8* GetFCRAMPointer(u32 offset); + /// Gets a serializable ref to FCRAM with the given offset + MemoryRef GetFCRAMRef(u32 offset); + /** * Mark each page touching the region as cached. */ @@ -329,9 +387,9 @@ private: * Since the cache only happens on linear heap or VRAM, we know the exact physical address and * pointer of such virtual address */ - u8* GetPointerForRasterizerCache(VAddr addr); + MemoryRef GetPointerForRasterizerCache(VAddr addr); - void MapPages(PageTable& page_table, u32 base, u32 size, u8* memory, PageType type); + void MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef memory, PageType type); class Impl; @@ -340,9 +398,18 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version); + +public: + template + class BackingMemImpl; }; /// Determines if the given VAddr is valid for the specified process. bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); } // namespace Memory + +BOOST_CLASS_EXPORT_KEY(Memory::MemorySystem::BackingMemImpl) +BOOST_CLASS_EXPORT_KEY(Memory::MemorySystem::BackingMemImpl) +BOOST_CLASS_EXPORT_KEY(Memory::MemorySystem::BackingMemImpl) +BOOST_CLASS_EXPORT_KEY(Memory::MemorySystem::BackingMemImpl) diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index dbbc21c8c..3f90482ec 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -22,8 +22,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0))); page_table = &kernel->GetCurrentProcess()->vm_manager.page_table; - page_table->pointers.fill(nullptr); - page_table->attributes.fill(Memory::PageType::Unmapped); + page_table->Clear(); memory->MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory); memory->MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory); diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index e405f6729..414d64021 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -138,67 +138,70 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel } SECTION("translates StaticBuffer descriptors") { - auto buffer = std::make_shared>(Memory::PAGE_SIZE); - std::fill(buffer->begin(), buffer->end(), 0xAB); + auto mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef buffer{mem}; + std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xAB); VAddr target_address = 0x10000000; - auto result = process->vm_manager.MapBackingMemory(target_address, buffer->data(), - buffer->size(), MemoryState::Private); + auto result = process->vm_manager.MapBackingMemory(target_address, buffer, buffer.GetSize(), + MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), - IPC::StaticBufferDesc(buffer->size(), 0), + IPC::StaticBufferDesc(buffer.GetSize(), 0), target_address, }; context.PopulateFromIncomingCommandBuffer(input, *process); - CHECK(context.GetStaticBuffer(0) == *buffer); + CHECK(context.GetStaticBuffer(0) == mem->Vector()); - REQUIRE(process->vm_manager.UnmapRange(target_address, buffer->size()) == RESULT_SUCCESS); + REQUIRE(process->vm_manager.UnmapRange(target_address, buffer.GetSize()) == RESULT_SUCCESS); } SECTION("translates MappedBuffer descriptors") { - auto buffer = std::make_shared>(Memory::PAGE_SIZE); - std::fill(buffer->begin(), buffer->end(), 0xCD); + auto mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef buffer{mem}; + std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xCD); VAddr target_address = 0x10000000; - auto result = process->vm_manager.MapBackingMemory(target_address, buffer->data(), - buffer->size(), MemoryState::Private); + auto result = process->vm_manager.MapBackingMemory(target_address, buffer, buffer.GetSize(), + MemoryState::Private); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), - IPC::MappedBufferDesc(buffer->size(), IPC::R), + IPC::MappedBufferDesc(buffer.GetSize(), IPC::R), target_address, }; context.PopulateFromIncomingCommandBuffer(input, *process); - std::vector other_buffer(buffer->size()); - context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer->size()); + std::vector other_buffer(buffer.GetSize()); + context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer.GetSize()); - CHECK(other_buffer == *buffer); + CHECK(other_buffer == mem->Vector()); - REQUIRE(process->vm_manager.UnmapRange(target_address, buffer->size()) == RESULT_SUCCESS); + REQUIRE(process->vm_manager.UnmapRange(target_address, buffer.GetSize()) == RESULT_SUCCESS); } SECTION("translates mixed params") { - auto buffer_static = std::make_shared>(Memory::PAGE_SIZE); - std::fill(buffer_static->begin(), buffer_static->end(), 0xCE); + auto mem_static = std::make_shared(Memory::PAGE_SIZE); + MemoryRef buffer_static{mem_static}; + std::fill(buffer_static.GetPtr(), buffer_static.GetPtr() + buffer_static.GetSize(), 0xCE); - auto buffer_mapped = std::make_shared>(Memory::PAGE_SIZE); - std::fill(buffer_mapped->begin(), buffer_mapped->end(), 0xDF); + auto mem_mapped = std::make_shared(Memory::PAGE_SIZE); + MemoryRef buffer_mapped{mem_mapped}; + std::fill(buffer_mapped.GetPtr(), buffer_mapped.GetPtr() + buffer_mapped.GetSize(), 0xDF); VAddr target_address_static = 0x10000000; - auto result = - process->vm_manager.MapBackingMemory(target_address_static, buffer_static->data(), - buffer_static->size(), MemoryState::Private); + auto result = process->vm_manager.MapBackingMemory( + target_address_static, buffer_static, buffer_static.GetSize(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); VAddr target_address_mapped = 0x20000000; - result = process->vm_manager.MapBackingMemory(target_address_mapped, buffer_mapped->data(), - buffer_mapped->size(), MemoryState::Private); + result = process->vm_manager.MapBackingMemory( + target_address_mapped, buffer_mapped, buffer_mapped.GetSize(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); auto a = MakeObject(kernel); @@ -210,9 +213,9 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel process->handle_table.Create(a).Unwrap(), IPC::CallingPidDesc(), 0, - IPC::StaticBufferDesc(buffer_static->size(), 0), + IPC::StaticBufferDesc(buffer_static.GetSize(), 0), target_address_static, - IPC::MappedBufferDesc(buffer_mapped->size(), IPC::R), + IPC::MappedBufferDesc(buffer_mapped.GetSize(), IPC::R), target_address_mapped, }; @@ -223,14 +226,14 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel CHECK(output[2] == 0xABCDEF00); CHECK(context.GetIncomingHandle(output[4]) == a); CHECK(output[6] == process->process_id); - CHECK(context.GetStaticBuffer(0) == *buffer_static); - std::vector other_buffer(buffer_mapped->size()); - context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped->size()); - CHECK(other_buffer == *buffer_mapped); + CHECK(context.GetStaticBuffer(0) == mem_static->Vector()); + std::vector other_buffer(buffer_mapped.GetSize()); + context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped.GetSize()); + CHECK(other_buffer == mem_mapped->Vector()); - REQUIRE(process->vm_manager.UnmapRange(target_address_static, buffer_static->size()) == + REQUIRE(process->vm_manager.UnmapRange(target_address_static, buffer_static.GetSize()) == RESULT_SUCCESS); - REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped->size()) == + REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped.GetSize()) == RESULT_SUCCESS); } } @@ -317,10 +320,12 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { context.AddStaticBuffer(0, input_buffer); - auto output_buffer = std::make_shared>(Memory::PAGE_SIZE); + auto output_mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef output_buffer{output_mem}; + VAddr target_address = 0x10000000; auto result = process->vm_manager.MapBackingMemory( - target_address, output_buffer->data(), output_buffer->size(), MemoryState::Private); + target_address, output_buffer, output_buffer.GetSize(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); input[0] = IPC::MakeHeader(0, 0, 2); @@ -332,13 +337,13 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { std::array output_cmdbuff; // Set up the output StaticBuffer output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH] = - IPC::StaticBufferDesc(output_buffer->size(), 0); + IPC::StaticBufferDesc(output_buffer.GetSize(), 0); output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address; context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process); - CHECK(*output_buffer == input_buffer); - REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) == + CHECK(output_mem->Vector() == input_buffer); + REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer.GetSize()) == RESULT_SUCCESS); } @@ -346,15 +351,17 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { std::vector input_buffer(Memory::PAGE_SIZE); std::fill(input_buffer.begin(), input_buffer.end(), 0xAB); - auto output_buffer = std::make_shared>(Memory::PAGE_SIZE); + auto output_mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef output_buffer{output_mem}; + VAddr target_address = 0x10000000; auto result = process->vm_manager.MapBackingMemory( - target_address, output_buffer->data(), output_buffer->size(), MemoryState::Private); + target_address, output_buffer, output_buffer.GetSize(), MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); const u32_le input_cmdbuff[]{ IPC::MakeHeader(0, 0, 2), - IPC::MappedBufferDesc(output_buffer->size(), IPC::W), + IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W), target_address, }; @@ -363,15 +370,15 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size()); input[0] = IPC::MakeHeader(0, 0, 2); - input[1] = IPC::MappedBufferDesc(output_buffer->size(), IPC::W); + input[1] = IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W); input[2] = 0; context.WriteToOutgoingCommandBuffer(output, *process); - CHECK(output[1] == IPC::MappedBufferDesc(output_buffer->size(), IPC::W)); + CHECK(output[1] == IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W)); CHECK(output[2] == target_address); - CHECK(*output_buffer == input_buffer); - REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) == + CHECK(output_mem->Vector() == input_buffer); + REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer.GetSize()) == RESULT_SUCCESS); } } diff --git a/src/tests/core/memory/vm_manager.cpp b/src/tests/core/memory/vm_manager.cpp index bd510864a..5a8e8b788 100644 --- a/src/tests/core/memory/vm_manager.cpp +++ b/src/tests/core/memory/vm_manager.cpp @@ -10,47 +10,48 @@ #include "core/memory.h" TEST_CASE("Memory Basics", "[kernel][memory]") { - auto block = std::make_shared>(Memory::PAGE_SIZE); + auto mem = std::make_shared(Memory::PAGE_SIZE); + MemoryRef block{mem}; Memory::MemorySystem memory; SECTION("mapping memory") { // Because of the PageTable, Kernel::VMManager is too big to be created on the stack. auto manager = std::make_unique(memory); - auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(), + auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(), Kernel::MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); auto vma = manager->FindVMA(Memory::HEAP_VADDR); CHECK(vma != manager->vma_map.end()); - CHECK(vma->second.size == block->size()); + CHECK(vma->second.size == block.GetSize()); CHECK(vma->second.type == Kernel::VMAType::BackingMemory); - CHECK(vma->second.backing_memory == block->data()); + CHECK(vma->second.backing_memory.GetPtr() == block.GetPtr()); CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private); } SECTION("unmapping memory") { // Because of the PageTable, Kernel::VMManager is too big to be created on the stack. auto manager = std::make_unique(memory); - auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(), + auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(), Kernel::MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); - ResultCode code = manager->UnmapRange(Memory::HEAP_VADDR, block->size()); + ResultCode code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize()); REQUIRE(code == RESULT_SUCCESS); auto vma = manager->FindVMA(Memory::HEAP_VADDR); CHECK(vma != manager->vma_map.end()); CHECK(vma->second.type == Kernel::VMAType::Free); - CHECK(vma->second.backing_memory == nullptr); + CHECK(vma->second.backing_memory.GetPtr() == nullptr); } SECTION("changing memory permissions") { // Because of the PageTable, Kernel::VMManager is too big to be created on the stack. auto manager = std::make_unique(memory); - auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(), + auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(), Kernel::MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); - ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block->size(), + ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block.GetSize(), Kernel::VMAPermission::Execute); CHECK(code == RESULT_SUCCESS); @@ -58,24 +59,24 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { CHECK(vma != manager->vma_map.end()); CHECK(vma->second.permissions == Kernel::VMAPermission::Execute); - code = manager->UnmapRange(Memory::HEAP_VADDR, block->size()); + code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize()); REQUIRE(code == RESULT_SUCCESS); } SECTION("changing memory state") { // Because of the PageTable, Kernel::VMManager is too big to be created on the stack. auto manager = std::make_unique(memory); - auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(), + auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(), Kernel::MemoryState::Private); REQUIRE(result.Code() == RESULT_SUCCESS); - ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block->size(), + ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block.GetSize(), Kernel::VMAPermission::ReadWrite); REQUIRE(code == RESULT_SUCCESS); SECTION("with invalid address") { ResultCode code = manager->ChangeMemoryState( - 0xFFFFFFFF, block->size(), Kernel::MemoryState::Locked, + 0xFFFFFFFF, block.GetSize(), Kernel::MemoryState::Locked, Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, Kernel::VMAPermission::Execute); CHECK(code == Kernel::ERR_INVALID_ADDRESS); @@ -83,7 +84,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { SECTION("ignoring the original permissions") { ResultCode code = manager->ChangeMemoryState( - Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private, + Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private, Kernel::VMAPermission::None, Kernel::MemoryState::Locked, Kernel::VMAPermission::Write); CHECK(code == RESULT_SUCCESS); @@ -96,7 +97,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { SECTION("enforcing the original permissions with correct expectations") { ResultCode code = manager->ChangeMemoryState( - Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private, + Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private, Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, Kernel::VMAPermission::Execute); CHECK(code == RESULT_SUCCESS); @@ -109,7 +110,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { SECTION("with incorrect permission expectations") { ResultCode code = manager->ChangeMemoryState( - Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private, + Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private, Kernel::VMAPermission::Execute, Kernel::MemoryState::Aliased, Kernel::VMAPermission::Execute); CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE); @@ -122,7 +123,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { SECTION("with incorrect state expectations") { ResultCode code = manager->ChangeMemoryState( - Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Locked, + Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Locked, Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, Kernel::VMAPermission::Execute); CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE); @@ -133,7 +134,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private); } - code = manager->UnmapRange(Memory::HEAP_VADDR, block->size()); + code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize()); REQUIRE(code == RESULT_SUCCESS); } } From e4afa8e5124a61c17f171406b2011a1ea8b163ea Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 5 Jan 2020 13:26:16 +0000 Subject: [PATCH 058/129] Make the tests pass --- src/common/memory_ref.h | 17 +++++++++++------ src/core/core.cpp | 4 ++-- src/core/hle/service/cecd/cecd.cpp | 3 +-- src/core/memory.cpp | 21 +++++++++++---------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index 5aaaef468..05b1c7901 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -91,15 +91,20 @@ public: } private: - std::shared_ptr backing_mem; - u32 offset; + std::shared_ptr backing_mem = nullptr; + u32 offset = 0; // Cached values for speed - u8* cptr; - u32 csize; + u8* cptr = nullptr; + u32 csize = 0; void Init() { - cptr = backing_mem->GetPtr() + offset; - csize = static_cast(backing_mem->GetSize() - offset); + if (backing_mem) { + cptr = backing_mem->GetPtr() + offset; + csize = static_cast(backing_mem->GetSize() - offset); + } else { + cptr = nullptr; + csize = 0; + } } template diff --git a/src/core/core.cpp b/src/core/core.cpp index a05e2a636..bada80b55 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -214,8 +214,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique( - *memory, *timing, [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique(*memory, *timing, + [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 42ac76946..f13df6926 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -1352,8 +1352,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ case CecDataPathType::MboxData: case CecDataPathType::MboxIcon: case CecDataPathType::MboxTitle: - default: { - } + default: {} } } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 9762619f0..dd3a07804 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -98,7 +98,7 @@ public: std::shared_ptr n3ds_extra_ram_mem; std::shared_ptr dsp_mem; - MemorySystem::Impl(); + Impl(); virtual u8* GetPtr(Region r) { switch (r) { @@ -157,16 +157,17 @@ private: template class MemorySystem::BackingMemImpl : public BackingMem { public: - BackingMemImpl() : system(Core::Global().Memory()) {} + BackingMemImpl() : impl(*Core::Global().Memory().impl) {} + BackingMemImpl(MemorySystem::Impl& impl_) : impl(impl_) {} virtual u8* GetPtr() { - return system.impl->GetPtr(R); + return impl.GetPtr(R); } virtual u32 GetSize() const { - return system.impl->GetSize(R); + return impl.GetSize(R); } private: - MemorySystem& system; + MemorySystem::Impl& impl; template void serialize(Archive& ar, const unsigned int) {} @@ -174,10 +175,10 @@ private: }; MemorySystem::Impl::Impl() - : fcram_mem(std::make_shared>()), - vram_mem(std::make_shared>()), - n3ds_extra_ram_mem(std::make_shared>()), - dsp_mem(std::make_shared>()) {} + : fcram_mem(std::make_shared>(*this)), + vram_mem(std::make_shared>(*this)), + n3ds_extra_ram_mem(std::make_shared>(*this)), + dsp_mem(std::make_shared>(*this)) {} MemorySystem::MemorySystem() : impl(std::make_unique()) {} MemorySystem::~MemorySystem() = default; @@ -219,7 +220,7 @@ void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef } base += 1; - if (memory != nullptr) + if (memory != nullptr && memory.GetSize() > PAGE_SIZE) memory += PAGE_SIZE; } } From 96432589bdeff1ac53ca1e2b7601d9eea1def435 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 5 Jan 2020 16:35:01 +0000 Subject: [PATCH 059/129] Use shared_ptr for PageTable --- TODO | 2 +- src/core/arm/dynarmic/arm_dynarmic.h | 4 ++-- src/core/hle/kernel/kernel.cpp | 4 ++-- src/core/hle/kernel/kernel.h | 2 +- src/core/hle/kernel/process.cpp | 4 ++-- src/core/hle/kernel/vm_manager.cpp | 11 ++++++----- src/core/hle/kernel/vm_manager.h | 2 +- src/core/memory.cpp | 26 +++++++++++++------------- src/core/memory.h | 8 ++++---- src/tests/core/arm/arm_test_common.cpp | 4 ++-- 10 files changed, 34 insertions(+), 33 deletions(-) diff --git a/TODO b/TODO index 4bb80f8d5..9c77cec5b 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,7 @@ ☐ Multiple slots etc. ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) - ☐ Page tables + ✔ Page tables @done(20-01-05 16:33) Need to change uses to shared_ptr ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) ✔ DSP @done(19-12-28 16:57) diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index ff9a104b5..690c1aa2e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -61,7 +61,7 @@ private: std::unique_ptr MakeJit(); Dynarmic::A32::Jit* jit = nullptr; - Memory::PageTable* current_page_table = nullptr; - std::map> jits; + std::shared_ptr current_page_table = nullptr; + std::map, std::unique_ptr> jits; std::shared_ptr interpreter_state; }; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 6fef2d4de..968e905ac 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -52,10 +52,10 @@ std::shared_ptr KernelSystem::GetCurrentProcess() const { void KernelSystem::SetCurrentProcess(std::shared_ptr process) { current_process = process; - SetCurrentMemoryPageTable(&process->vm_manager.page_table); + SetCurrentMemoryPageTable(process->vm_manager.page_table); } -void KernelSystem::SetCurrentMemoryPageTable(Memory::PageTable* page_table) { +void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr page_table) { memory.SetCurrentPageTable(page_table); if (current_cpu != nullptr) { current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 0a527d8b4..c07bfdbca 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -214,7 +214,7 @@ public: std::shared_ptr GetCurrentProcess() const; void SetCurrentProcess(std::shared_ptr process); - void SetCurrentMemoryPageTable(Memory::PageTable* page_table); + void SetCurrentMemoryPageTable(std::shared_ptr page_table); void SetCPU(std::shared_ptr cpu); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c181bd01a..ea3449c21 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -435,7 +435,7 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe Kernel::Process::Process(KernelSystem& kernel) : Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) { - kernel.memory.RegisterPageTable(&vm_manager.page_table); + kernel.memory.RegisterPageTable(vm_manager.page_table); } Kernel::Process::~Process() { // Release all objects this process owns first so that their potential destructor can do clean @@ -444,7 +444,7 @@ Kernel::Process::~Process() { // memory etc.) even if they are still referenced by other processes. handle_table.Clear(); - kernel.memory.UnregisterPageTable(&vm_manager.page_table); + kernel.memory.UnregisterPageTable(vm_manager.page_table); } std::shared_ptr KernelSystem::GetProcessById(u32 process_id) const { diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 1b9875ee2..f1408235b 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -37,7 +37,8 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { return true; } -VMManager::VMManager(Memory::MemorySystem& memory) : memory(memory) { +VMManager::VMManager(Memory::MemorySystem& memory) + : memory(memory), page_table(std::make_shared()) { Reset(); } @@ -51,7 +52,7 @@ void VMManager::Reset() { initial_vma.size = MAX_ADDRESS; vma_map.emplace(initial_vma.base, initial_vma); - page_table.Clear(); + page_table->Clear(); UpdatePageTableForVMA(initial_vma); } @@ -348,13 +349,13 @@ VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) { void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { switch (vma.type) { case VMAType::Free: - memory.UnmapRegion(page_table, vma.base, vma.size); + memory.UnmapRegion(*page_table, vma.base, vma.size); break; case VMAType::BackingMemory: - memory.MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory); + memory.MapMemoryRegion(*page_table, vma.base, vma.size, vma.backing_memory); break; case VMAType::MMIO: - memory.MapIoRegion(page_table, vma.base, vma.size, vma.mmio_handler); + memory.MapIoRegion(*page_table, vma.base, vma.size, vma.mmio_handler); break; } } diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 880d9ec81..3ca46d069 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -209,7 +209,7 @@ public: /// Each VMManager has its own page table, which is set as the main one when the owning process /// is scheduled. - Memory::PageTable page_table; + std::shared_ptr page_table; private: using VMAIter = decltype(vma_map)::iterator; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index dd3a07804..ceb6aad4e 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -87,9 +87,9 @@ public: std::unique_ptr vram = std::make_unique(Memory::VRAM_SIZE); std::unique_ptr n3ds_extra_ram = std::make_unique(Memory::N3DS_EXTRA_RAM_SIZE); - PageTable* current_page_table = nullptr; + std::shared_ptr current_page_table = nullptr; RasterizerCacheMarker cache_marker; - std::vector page_table_list; + std::vector> page_table_list; AudioCore::DspInterface* dsp = nullptr; @@ -144,7 +144,7 @@ private: ar& cache_marker; ar& page_table_list; // dsp is set from Core::System at startup - // TODO: current_page_table + ar& current_page_table; ar& fcram_mem; ar& vram_mem; ar& n3ds_extra_ram_mem; @@ -190,11 +190,11 @@ void MemorySystem::serialize(Archive& ar, const unsigned int file_version) { SERIALIZE_IMPL(MemorySystem) -void MemorySystem::SetCurrentPageTable(PageTable* page_table) { +void MemorySystem::SetCurrentPageTable(std::shared_ptr page_table) { impl->current_page_table = page_table; } -PageTable* MemorySystem::GetCurrentPageTable() const { +std::shared_ptr MemorySystem::GetCurrentPageTable() const { return impl->current_page_table; } @@ -259,11 +259,11 @@ MemoryRef MemorySystem::GetPointerForRasterizerCache(VAddr addr) { UNREACHABLE(); } -void MemorySystem::RegisterPageTable(PageTable* page_table) { +void MemorySystem::RegisterPageTable(std::shared_ptr page_table) { impl->page_table_list.push_back(page_table); } -void MemorySystem::UnregisterPageTable(PageTable* page_table) { +void MemorySystem::UnregisterPageTable(std::shared_ptr page_table) { impl->page_table_list.erase( std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table)); } @@ -351,7 +351,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) { } bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) { - auto& page_table = process.vm_manager.page_table; + auto& page_table = *process.vm_manager.page_table; auto page_pointer = page_table.pointers[vaddr >> PAGE_BITS]; if (page_pointer) @@ -486,7 +486,7 @@ void MemorySystem::RasterizerMarkRegionCached(PAddr start, u32 size, bool cached for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { for (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) { impl->cache_marker.Mark(vaddr, cached); - for (PageTable* page_table : impl->page_table_list) { + for (auto page_table : impl->page_table_list) { PageType& page_type = page_table->attributes[vaddr >> PAGE_BITS]; if (cached) { @@ -608,7 +608,7 @@ u64 MemorySystem::Read64(const VAddr addr) { void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { - auto& page_table = process.vm_manager.page_table; + auto& page_table = *process.vm_manager.page_table; std::size_t remaining_size = size; std::size_t page_index = src_addr >> PAGE_BITS; @@ -674,7 +674,7 @@ void MemorySystem::Write64(const VAddr addr, const u64 data) { void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, const std::size_t size) { - auto& page_table = process.vm_manager.page_table; + auto& page_table = *process.vm_manager.page_table; std::size_t remaining_size = size; std::size_t page_index = dest_addr >> PAGE_BITS; std::size_t page_offset = dest_addr & PAGE_MASK; @@ -722,7 +722,7 @@ void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_a void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) { - auto& page_table = process.vm_manager.page_table; + auto& page_table = *process.vm_manager.page_table; std::size_t remaining_size = size; std::size_t page_index = dest_addr >> PAGE_BITS; std::size_t page_offset = dest_addr & PAGE_MASK; @@ -777,7 +777,7 @@ void MemorySystem::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VA void MemorySystem::CopyBlock(const Kernel::Process& dest_process, const Kernel::Process& src_process, VAddr dest_addr, VAddr src_addr, std::size_t size) { - auto& page_table = src_process.vm_manager.page_table; + auto& page_table = *src_process.vm_manager.page_table; std::size_t remaining_size = size; std::size_t page_index = src_addr >> PAGE_BITS; std::size_t page_offset = src_addr & PAGE_MASK; diff --git a/src/core/memory.h b/src/core/memory.h index 0dc98a428..348fee3c9 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -316,8 +316,8 @@ public: void UnmapRegion(PageTable& page_table, VAddr base, u32 size); /// Currently active page table - void SetCurrentPageTable(PageTable* page_table); - PageTable* GetCurrentPageTable() const; + void SetCurrentPageTable(std::shared_ptr page_table); + std::shared_ptr GetCurrentPageTable() const; u8 Read8(VAddr addr); u16 Read16(VAddr addr); @@ -367,10 +367,10 @@ public: void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached); /// Registers page table for rasterizer cache marking - void RegisterPageTable(PageTable* page_table); + void RegisterPageTable(std::shared_ptr page_table); /// Unregisters page table for rasterizer cache marking - void UnregisterPageTable(PageTable* page_table); + void UnregisterPageTable(std::shared_ptr page_table); void SetDSP(AudioCore::DspInterface& dsp); diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index 3f90482ec..cf2ecf0d4 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -10,7 +10,7 @@ namespace ArmTests { -static Memory::PageTable* page_table = nullptr; +static std::shared_ptr page_table = nullptr; TestEnvironment::TestEnvironment(bool mutable_memory_) : mutable_memory(mutable_memory_), test_memory(std::make_shared(this)) { @@ -20,7 +20,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) kernel = std::make_unique(*memory, *timing, [] {}, 0); kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0))); - page_table = &kernel->GetCurrentProcess()->vm_manager.page_table; + page_table = kernel->GetCurrentProcess()->vm_manager.page_table; page_table->Clear(); From 7019561fd51919ddc21fbc17220d8b2f4bc10461 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 5 Jan 2020 16:42:04 +0000 Subject: [PATCH 060/129] Bind NWM_UDS service in the constructor --- TODO | 4 ++-- src/core/hle/service/nwm/nwm_uds.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index 9c77cec5b..c4f46e312 100644 --- a/TODO +++ b/TODO @@ -93,7 +93,7 @@ ✔ VM Manager @started(19-08-13 16:46) @done(20-01-04 21:09) @lasted(20w4d5h23m42s) Just need to figure out backing_mem (a u8*) ✔ Wait object @done(19-08-13 16:46) - ☐ Service @started(19-12-23 12:49) + ✔ Service @started(19-12-23 12:49) @done(20-01-05 16:41) @lasted(1w6d3h52m17s) ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) ✔ ACT @done(19-12-24 23:17) ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) @@ -125,7 +125,7 @@ ✔ NIM @done(19-12-31 21:08) ✔ NS @done(20-01-01 00:46) ✔ NWM @done(20-01-01 21:31) - ☐ Fix wifi_packet_received? + ✔ Fix wifi_packet_received @done(20-01-05 16:41) ✔ PM @done(20-01-01 22:14) ✔ PS @done(20-01-01 00:54) ✔ PTM @done(20-01-01 22:36) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 9a3de82fa..dddf55333 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -31,7 +31,7 @@ void NWM_UDS::serialize(Archive& ar, const unsigned int) { ar& node_map; ar& connection_event; ar& received_beacons; - // TODO: Fix wifi_packet_received? + // wifi_packet_received set in constructor } SERIALIZE_IMPL(NWM_UDS) @@ -637,13 +637,6 @@ ResultVal> NWM_UDS::Initialize( recv_buffer_memory = std::move(sharedmem); ASSERT_MSG(recv_buffer_memory->GetSize() == sharedmem_size, "Invalid shared memory size."); - if (auto room_member = Network::GetRoomMember().lock()) { - wifi_packet_received = room_member->BindOnWifiPacketReceived( - [this](const Network::WifiPacket& packet) { OnWifiPacketReceived(packet); }); - } else { - LOG_ERROR(Service_NWM, "Network isn't initalized"); - } - { std::lock_guard lock(connection_status_mutex); @@ -1408,6 +1401,13 @@ NWM_UDS::NWM_UDS(Core::System& system) : ServiceFramework("nwm::UDS"), system(sy system.Kernel().GetSharedPageHandler().SetMacAddress(mac); system.Kernel().GetSharedPageHandler().SetWifiLinkLevel(SharedPage::WifiLinkLevel::BEST); + + if (auto room_member = Network::GetRoomMember().lock()) { + wifi_packet_received = room_member->BindOnWifiPacketReceived( + [this](const Network::WifiPacket& packet) { OnWifiPacketReceived(packet); }); + } else { + LOG_ERROR(Service_NWM, "Network isn't initalized"); + } } NWM_UDS::~NWM_UDS() { From 116d22d562b294e95f3e924c00ecc40bbcc28117 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 6 Jan 2020 20:03:40 +0000 Subject: [PATCH 061/129] Refactor out the wakeup_callback function pointer --- TODO | 3 +- src/common/CMakeLists.txt | 1 + .../serialization/boost_small_vector.hpp | 144 +++++++++++++++++ src/common/serialization/boost_vector.hpp | 148 +++++++----------- src/core/hle/kernel/address_arbiter.cpp | 16 +- src/core/hle/kernel/address_arbiter.h | 6 +- src/core/hle/kernel/hle_ipc.cpp | 95 +++++++---- src/core/hle/kernel/hle_ipc.h | 55 +++++-- src/core/hle/kernel/ipc.cpp | 2 +- src/core/hle/kernel/ipc_debugger/recorder.cpp | 4 +- src/core/hle/kernel/kernel.h | 2 +- src/core/hle/kernel/server_session.cpp | 6 +- src/core/hle/kernel/svc.cpp | 139 ++++++++-------- src/core/hle/kernel/svc.h | 7 + src/core/hle/kernel/thread.cpp | 29 ++-- src/core/hle/kernel/thread.h | 15 +- src/core/hle/kernel/wait_object.cpp | 2 +- src/core/hle/service/fs/file.cpp | 7 +- src/core/hle/service/fs/fs_user.cpp | 14 +- src/core/hle/service/nwm/nwm_uds.cpp | 36 +++-- src/core/hle/service/nwm/nwm_uds.h | 4 + src/core/hle/service/sm/srv.cpp | 66 +++++--- src/core/hle/service/sm/srv.h | 5 + src/tests/core/hle/kernel/hle_ipc.cpp | 22 +-- 24 files changed, 533 insertions(+), 295 deletions(-) create mode 100644 src/common/serialization/boost_small_vector.hpp diff --git a/TODO b/TODO index c4f46e312..097c310a7 100644 --- a/TODO +++ b/TODO @@ -46,6 +46,7 @@ ✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) ☐ Review constructor/initialization code ☐ Review core timing events +☐ Review base class serialization everywhere ✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) @@ -87,7 +88,7 @@ ✔ Shared page @done(20-01-04 21:09) ✔ SVC @done(19-12-22 21:32) Nothing to do - all data is constant - ☐ Thread @started(19-08-13 16:45) + ✔ Thread @started(19-08-13 16:45) @done(20-01-06 20:01) @lasted(20w6d4h16m22s) This requires refactoring wakeup_callback to be an object ref ✔ Timer @done(19-08-13 16:45) ✔ VM Manager @started(19-08-13 16:46) @done(20-01-04 21:09) @lasted(20w4d5h23m42s) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index ea117d440..7ab54242d 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -96,6 +96,7 @@ add_library(common STATIC serialization/atomic.h serialization/boost_discrete_interval.hpp serialization/boost_flat_set.h + serialization/boost_small_vector.hpp serialization/boost_vector.hpp string_util.cpp string_util.h diff --git a/src/common/serialization/boost_small_vector.hpp b/src/common/serialization/boost_small_vector.hpp new file mode 100644 index 000000000..b4e07a896 --- /dev/null +++ b/src/common/serialization/boost_small_vector.hpp @@ -0,0 +1,144 @@ +#ifndef BOOST_SERIALIZATION_BOOST_SMALL_VECTOR_HPP +#define BOOST_SERIALIZATION_BOOST_SMALL_VECTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +#pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// boost_vector.hpp: serialization for boost vector templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// fast array serialization (C) Copyright 2005 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// default is being compatible with version 1.34.1 files, not 1.35 files +#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V == 4 || V == 5) +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector< T > + +// the default versions + +template +inline void save(Archive& ar, const boost::container::small_vector& t, + const unsigned int /* file_version */, mpl::false_) { + boost::serialization::stl::save_collection>(ar, + t); +} + +template +inline void load(Archive& ar, boost::container::small_vector& t, + const unsigned int /* file_version */, mpl::false_) { + const boost::archive::library_version_type library_version(ar.get_library_version()); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if (boost::archive::library_version_type(3) < library_version) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + t.reserve(count); + stl::collection_load_impl(ar, t, count, item_version); +} + +// the optimized versions + +template +inline void save(Archive& ar, const boost::container::small_vector& t, + const unsigned int /* file_version */, mpl::true_) { + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array(static_cast(&t[0]), + count); +} + +template +inline void load(Archive& ar, boost::container::small_vector& t, + const unsigned int /* file_version */, mpl::true_) { + collection_size_type count(t.size()); + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + unsigned int item_version = 0; + if (BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array(static_cast(&t[0]), count); +} + +// dispatch to either default or optimized versions + +template +inline void save(Archive& ar, const boost::container::small_vector& t, + const unsigned int file_version) { + typedef typename boost::serialization::use_array_optimization::template apply< + typename remove_const::type>::type use_optimized; + save(ar, t, file_version, use_optimized()); +} + +template +inline void load(Archive& ar, boost::container::small_vector& t, + const unsigned int file_version) { +#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP + if (ar.get_library_version() == boost::archive::library_version_type(5)) { + load(ar, t, file_version, boost::is_arithmetic()); + return; + } +#endif + typedef typename boost::serialization::use_array_optimization::template apply< + typename remove_const::type>::type use_optimized; + load(ar, t, file_version, use_optimized()); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize(Archive& ar, boost::container::small_vector& t, + const unsigned int file_version) { + boost::serialization::split_free(ar, t, file_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize(Archive& ar, boost::container::small_vector& t, + const unsigned int file_version) { + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_BOOST_SMALL_VECTOR_HPP diff --git a/src/common/serialization/boost_vector.hpp b/src/common/serialization/boost_vector.hpp index d97ebd208..55a5b9eae 100644 --- a/src/common/serialization/boost_vector.hpp +++ b/src/common/serialization/boost_vector.hpp @@ -1,9 +1,9 @@ -#ifndef BOOST_SERIALIZATION_BOOST_VECTOR_HPP +#ifndef BOOST_SERIALIZATION_BOOST_VECTOR_HPP #define BOOST_SERIALIZATION_BOOST_VECTOR_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) -# pragma once +#pragma once #endif /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 @@ -24,20 +24,20 @@ #include #include -#include #include #include +#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include // default is being compatible with version 1.34.1 files, not 1.35 files #ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED -#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V == 4 || V == 5) #endif namespace boost { @@ -48,33 +48,23 @@ namespace serialization { // the default versions -template -inline void save( - Archive & ar, - const boost::container::vector &t, - const unsigned int /* file_version */, - mpl::false_ -){ - boost::serialization::stl::save_collection >( - ar, t - ); +template +inline void save(Archive& ar, const boost::container::vector& t, + const unsigned int /* file_version */, mpl::false_) { + boost::serialization::stl::save_collection>(ar, + t); } -template -inline void load( - Archive & ar, - boost::container::vector &t, - const unsigned int /* file_version */, - mpl::false_ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); +template +inline void load(Archive& ar, boost::container::vector& t, + const unsigned int /* file_version */, mpl::false_) { + const boost::archive::library_version_type library_version(ar.get_library_version()); // retrieve number of elements item_version_type item_version(0); collection_size_type count; ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ + if (boost::archive::library_version_type(3) < library_version) { ar >> BOOST_SERIALIZATION_NVP(item_version); } t.reserve(count); @@ -83,107 +73,77 @@ inline void load( // the optimized versions -template -inline void save( - Archive & ar, - const boost::container::vector &t, - const unsigned int /* file_version */, - mpl::true_ -){ +template +inline void save(Archive& ar, const boost::container::vector& t, + const unsigned int /* file_version */, mpl::true_) { const collection_size_type count(t.size()); ar << BOOST_SERIALIZATION_NVP(count); if (!t.empty()) // explict template arguments to pass intel C++ compiler - ar << serialization::make_array( - static_cast(&t[0]), - count - ); + ar << serialization::make_array(static_cast(&t[0]), + count); } -template -inline void load( - Archive & ar, - boost::container::vector &t, - const unsigned int /* file_version */, - mpl::true_ -){ +template +inline void load(Archive& ar, boost::container::vector& t, + const unsigned int /* file_version */, mpl::true_) { collection_size_type count(t.size()); ar >> BOOST_SERIALIZATION_NVP(count); t.resize(count); - unsigned int item_version=0; - if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + unsigned int item_version = 0; + if (BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { ar >> BOOST_SERIALIZATION_NVP(item_version); } if (!t.empty()) // explict template arguments to pass intel C++ compiler - ar >> serialization::make_array( - static_cast(&t[0]), - count - ); - } + ar >> serialization::make_array(static_cast(&t[0]), count); +} // dispatch to either default or optimized versions -template -inline void save( - Archive & ar, - const boost::container::vector &t, - const unsigned int file_version -){ - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const::type - >::type use_optimized; - save(ar,t,file_version, use_optimized()); +template +inline void save(Archive& ar, const boost::container::vector& t, + const unsigned int file_version) { + typedef typename boost::serialization::use_array_optimization::template apply< + typename remove_const::type>::type use_optimized; + save(ar, t, file_version, use_optimized()); } -template -inline void load( - Archive & ar, - boost::container::vector &t, - const unsigned int file_version -){ +template +inline void load(Archive& ar, boost::container::vector& t, + const unsigned int file_version) { #ifdef BOOST_SERIALIZATION_VECTOR_135_HPP - if (ar.get_library_version()==boost::archive::library_version_type(5)) - { - load(ar,t,file_version, boost::is_arithmetic()); - return; + if (ar.get_library_version() == boost::archive::library_version_type(5)) { + load(ar, t, file_version, boost::is_arithmetic()); + return; } #endif - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const::type - >::type use_optimized; - load(ar,t,file_version, use_optimized()); + typedef typename boost::serialization::use_array_optimization::template apply< + typename remove_const::type>::type use_optimized; + load(ar, t, file_version, use_optimized()); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - boost::container::vector & t, - const unsigned int file_version -){ +template +inline void serialize(Archive& ar, boost::container::vector& t, + const unsigned int file_version) { boost::serialization::split_free(ar, t, file_version); } // split non-intrusive serialization function member into separate // non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - boost::container::vector & t, - const unsigned int file_version -){ +template +inline void serialize(Archive& ar, boost::container::vector& t, + const unsigned int file_version) { boost::serialization::split_free(ar, t, file_version); } -} // serialization +} // namespace serialization } // namespace boost #include BOOST_SERIALIZATION_COLLECTION_TRAITS(boost::container::vector) -#endif // BOOST_SERIALIZATION_VECTOR_HPP +#endif // BOOST_SERIALIZATION_BOOST_VECTOR_HPP diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 7b8329c4d..5074e352f 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -80,16 +80,18 @@ std::shared_ptr KernelSystem::CreateAddressArbiter(std::string n return address_arbiter; } +void AddressArbiter::WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) { + ASSERT(reason == ThreadWakeupReason::Timeout); + // Remove the newly-awakened thread from the Arbiter's waiting list. + waiting_threads.erase(std::remove(waiting_threads.begin(), waiting_threads.end(), thread), + waiting_threads.end()); +}; + ResultCode AddressArbiter::ArbitrateAddress(std::shared_ptr thread, ArbitrationType type, VAddr address, s32 value, u64 nanoseconds) { - auto timeout_callback = [this](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(reason == ThreadWakeupReason::Timeout); - // Remove the newly-awakened thread from the Arbiter's waiting list. - waiting_threads.erase(std::remove(waiting_threads.begin(), waiting_threads.end(), thread), - waiting_threads.end()); - }; + auto timeout_callback = std::dynamic_pointer_cast(shared_from_this()); switch (type) { diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 19b80315f..85a2a065a 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -12,6 +12,7 @@ #include #include "common/common_types.h" #include "core/hle/kernel/object.h" +#include "core/hle/kernel/thread.h" #include "core/hle/result.h" // Address arbiters are an underlying kernel synchronization object that can be created/used via @@ -34,7 +35,7 @@ enum class ArbitrationType : u32 { DecrementAndWaitIfLessThanWithTimeout, }; -class AddressArbiter final : public Object { +class AddressArbiter final : public Object, public WakeupCallback { public: explicit AddressArbiter(KernelSystem& kernel); ~AddressArbiter() override; @@ -56,6 +57,9 @@ public: ResultCode ArbitrateAddress(std::shared_ptr thread, ArbitrationType type, VAddr address, s32 value, u64 nanoseconds); + void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object); + private: KernelSystem& kernel; diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index ab4ecfd05..b1e2f7d8b 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -16,6 +16,46 @@ namespace Kernel { +class HLERequestContext::ThreadCallback : public Kernel::WakeupCallback { + +public: + ThreadCallback(std::shared_ptr context_, + std::shared_ptr callback_) + : context(context_), callback(callback_) {} + void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) { + ASSERT(thread->status == ThreadStatus::WaitHleEvent); + if (callback) { + callback->WakeUp(thread, *context, reason); + } + + auto& process = thread->owner_process; + // We must copy the entire command buffer *plus* the entire static buffers area, since + // the translation might need to read from it in order to retrieve the StaticBuffer + // target addresses. + std::array cmd_buff; + Memory::MemorySystem& memory = context->kernel.memory; + memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), + cmd_buff.size() * sizeof(u32)); + context->WriteToOutgoingCommandBuffer(cmd_buff.data(), *process); + // Copy the translated command buffer back into the thread's command buffer area. + memory.WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), + cmd_buff.size() * sizeof(u32)); + } + +private: + ThreadCallback() = default; + std::shared_ptr callback{}; + std::shared_ptr context{}; + + template + void serialize(Archive& ar, const unsigned int) { + ar& callback; + ar& context; + } + friend class boost::serialization::access; +}; + SessionRequestHandler::SessionInfo::SessionInfo(std::shared_ptr session, std::unique_ptr data) : session(std::move(session)), data(std::move(data)) {} @@ -33,34 +73,16 @@ void SessionRequestHandler::ClientDisconnected(std::shared_ptr se connected_sessions.end()); } -std::shared_ptr HLERequestContext::SleepClientThread(const std::string& reason, - std::chrono::nanoseconds timeout, - WakeupCallback&& callback) { +std::shared_ptr HLERequestContext::SleepClientThread( + const std::string& reason, std::chrono::nanoseconds timeout, + std::shared_ptr callback) { // Put the client thread to sleep until the wait event is signaled or the timeout expires. - thread->wakeup_callback = [context = *this, - callback](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) mutable { - ASSERT(thread->status == ThreadStatus::WaitHleEvent); - callback(thread, context, reason); - - auto& process = thread->owner_process; - // We must copy the entire command buffer *plus* the entire static buffers area, since - // the translation might need to read from it in order to retrieve the StaticBuffer - // target addresses. - std::array cmd_buff; - Memory::MemorySystem& memory = context.kernel.memory; - memory.ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), - cmd_buff.size() * sizeof(u32)); - context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process); - // Copy the translated command buffer back into the thread's command buffer area. - memory.WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), - cmd_buff.size() * sizeof(u32)); - }; + thread->wakeup_callback = std::make_shared(shared_from_this(), callback); auto event = kernel.CreateEvent(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); thread->status = ThreadStatus::WaitHleEvent; thread->wait_objects = {event}; - event->AddWaitingThread(SharedFrom(thread)); + event->AddWaitingThread(thread); if (timeout.count() > 0) thread->WakeAfterDelay(timeout.count()); @@ -68,8 +90,10 @@ std::shared_ptr HLERequestContext::SleepClientThread(const std::string& r return event; } +HLERequestContext::HLERequestContext() : kernel(Core::Global()) {} + HLERequestContext::HLERequestContext(KernelSystem& kernel, std::shared_ptr session, - Thread* thread) + std::shared_ptr thread) : kernel(kernel), session(std::move(session)), thread(thread) { cmd_buf[0] = 0; } @@ -98,8 +122,9 @@ void HLERequestContext::AddStaticBuffer(u8 buffer_id, std::vector data) { static_buffers[buffer_id] = std::move(data); } -ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, - Process& src_process) { +ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer( + const u32_le* src_cmdbuf, std::shared_ptr src_process_) { + auto& src_process = *src_process_; IPC::Header header{src_cmdbuf[0]}; std::size_t untranslated_size = 1u + header.normal_params_size; @@ -158,7 +183,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr } case IPC::DescriptorType::MappedBuffer: { u32 next_id = static_cast(request_mapped_buffers.size()); - request_mapped_buffers.emplace_back(kernel.memory, src_process, descriptor, + request_mapped_buffers.emplace_back(kernel.memory, src_process_, descriptor, src_cmdbuf[i], next_id); cmd_buf[i++] = next_id; break; @@ -170,7 +195,7 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr if (should_record) { std::vector translated_cmdbuf{cmd_buf.begin(), cmd_buf.begin() + command_size}; - kernel.GetIPCRecorder().SetRequestInfo(SharedFrom(thread), std::move(untranslated_cmdbuf), + kernel.GetIPCRecorder().SetRequestInfo(thread, std::move(untranslated_cmdbuf), std::move(translated_cmdbuf)); } @@ -248,7 +273,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, if (should_record) { std::vector translated_cmdbuf{dst_cmdbuf, dst_cmdbuf + command_size}; - kernel.GetIPCRecorder().SetReplyInfo(SharedFrom(thread), std::move(untranslated_cmdbuf), + kernel.GetIPCRecorder().SetReplyInfo(thread, std::move(untranslated_cmdbuf), std::move(translated_cmdbuf)); } @@ -262,13 +287,15 @@ MappedBuffer& HLERequestContext::GetMappedBuffer(u32 id_from_cmdbuf) { void HLERequestContext::ReportUnimplemented() const { if (kernel.GetIPCRecorder().IsEnabled()) { - kernel.GetIPCRecorder().SetHLEUnimplemented(SharedFrom(thread)); + kernel.GetIPCRecorder().SetHLEUnimplemented(thread); } } -MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, - VAddr address, u32 id) - : memory(&memory), id(id), address(address), process(&process) { +MappedBuffer::MappedBuffer() : memory(&Core::Global().Memory()) {} + +MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, std::shared_ptr process, + u32 descriptor, VAddr address, u32 id) + : memory(&memory), id(id), address(address), process(process) { IPC::MappedBufferDescInfo desc{descriptor}; size = desc.size; perms = desc.perms; @@ -287,3 +314,5 @@ void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t } } // namespace Kernel + +SERIALIZE_EXPORT_IMPL(Kernel::HLERequestContext::ThreadCallback) diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 2177b733e..56c6d8ce1 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -16,6 +16,7 @@ #include #include #include "common/common_types.h" +#include "common/serialization/boost_small_vector.hpp" #include "common/swap.h" #include "core/hle/ipc.h" #include "core/hle/kernel/object.h" @@ -127,7 +128,7 @@ private: class MappedBuffer { public: - MappedBuffer(Memory::MemorySystem& memory, const Process& process, u32 descriptor, + MappedBuffer(Memory::MemorySystem& memory, std::shared_ptr process, u32 descriptor, VAddr address, u32 id); // interface for service @@ -151,9 +152,21 @@ private: Memory::MemorySystem* memory; u32 id; VAddr address; - const Process* process; - std::size_t size; + std::shared_ptr process; + u32 size; IPC::MappedBufferPermissions perms; + + MappedBuffer(); + + template + void serialize(Archive& ar, const unsigned int) { + ar& id; + ar& address; + ar& process; + ar& size; + ar& perms; + } + friend class boost::serialization::access; }; /** @@ -185,9 +198,10 @@ private: * id of the memory interface and let kernel convert it back to client vaddr. No real unmapping is * needed in this case, though. */ -class HLERequestContext { +class HLERequestContext : std::enable_shared_from_this { public: - HLERequestContext(KernelSystem& kernel, std::shared_ptr session, Thread* thread); + HLERequestContext(KernelSystem& kernel, std::shared_ptr session, + std::shared_ptr thread); ~HLERequestContext(); /// Returns a pointer to the IPC command buffer for this request. @@ -203,8 +217,12 @@ public: return session; } - using WakeupCallback = std::function thread, HLERequestContext& context, ThreadWakeupReason reason)>; + class WakeupCallback { + public: + virtual ~WakeupCallback() = default; + virtual void WakeUp(std::shared_ptr thread, HLERequestContext& context, + ThreadWakeupReason reason) = 0; + }; /** * Puts the specified guest thread to sleep until the returned event is signaled or until the @@ -219,7 +237,7 @@ public: */ std::shared_ptr SleepClientThread(const std::string& reason, std::chrono::nanoseconds timeout, - WakeupCallback&& callback); + std::shared_ptr callback); /** * Resolves a object id from the request command buffer into a pointer to an object. See the @@ -259,26 +277,43 @@ public: MappedBuffer& GetMappedBuffer(u32 id_from_cmdbuf); /// Populates this context with data from the requesting process/thread. - ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process); + ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, + std::shared_ptr src_process); /// Writes data from this context back to the requesting process/thread. ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const; /// Reports an unimplemented function. void ReportUnimplemented() const; + class ThreadCallback; + friend class ThreadCallback; + private: KernelSystem& kernel; std::array cmd_buf; std::shared_ptr session; - Thread* thread; + std::shared_ptr thread; // TODO(yuriks): Check common usage of this and optimize size accordingly boost::container::small_vector, 8> request_handles; // The static buffers will be created when the IPC request is translated. std::array, IPC::MAX_STATIC_BUFFERS> static_buffers; // The mapped buffers will be created when the IPC request is translated boost::container::small_vector request_mapped_buffers; + + HLERequestContext(); + template + void serialize(Archive& ar, const unsigned int) { + ar& cmd_buf; + ar& session; + ar& thread; + ar& request_handles; + ar& static_buffers; + ar& request_mapped_buffers; + } + friend class boost::serialization::access; }; } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::SessionRequestHandler::SessionDataBase) +BOOST_CLASS_EXPORT_KEY(Kernel::HLERequestContext::ThreadCallback) diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index e39732c14..eb1488840 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -72,7 +72,7 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy if (handle == CurrentThread) { object = src_thread; } else if (handle == CurrentProcess) { - object = SharedFrom(src_process); + object = src_process; } else if (handle != 0) { object = src_process->handle_table.GetGeneric(handle); if (descriptor == IPC::DescriptorType::MoveHandle) { diff --git a/src/core/hle/kernel/ipc_debugger/recorder.cpp b/src/core/hle/kernel/ipc_debugger/recorder.cpp index 968815c5b..f1e4a09f1 100644 --- a/src/core/hle/kernel/ipc_debugger/recorder.cpp +++ b/src/core/hle/kernel/ipc_debugger/recorder.cpp @@ -52,7 +52,7 @@ void Recorder::RegisterRequest(const std::shared_ptr& cli RequestRecord record = {/* id */ ++record_count, /* status */ RequestStatus::Sent, - /* client_process */ GetObjectInfo(client_thread->owner_process), + /* client_process */ GetObjectInfo(client_thread->owner_process.get()), /* client_thread */ GetObjectInfo(client_thread.get()), /* client_session */ GetObjectInfo(client_session.get()), /* client_port */ GetObjectInfo(client_session->parent->port.get()), @@ -82,7 +82,7 @@ void Recorder::SetRequestInfo(const std::shared_ptr& client_thre record.translated_request_cmdbuf = std::move(translated_cmdbuf); if (server_thread) { - record.server_process = GetObjectInfo(server_thread->owner_process); + record.server_process = GetObjectInfo(server_thread->owner_process.get()); record.server_thread = GetObjectInfo(server_thread.get()); } else { record.is_hle = true; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index c07bfdbca..e7b7314d6 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -134,7 +134,7 @@ public: */ ResultVal> CreateThread(std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, - VAddr stack_top, Process& owner_process); + VAddr stack_top, std::shared_ptr owner_process); /** * Creates a semaphore. diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 4b393b63d..8bb82fc83 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -71,12 +71,12 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { // If this ServerSession has an associated HLE handler, forward the request to it. if (hle_handler != nullptr) { std::array cmd_buf; - Kernel::Process* current_process = thread->owner_process; + auto current_process = thread->owner_process; kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), cmd_buf.size() * sizeof(u32)); - Kernel::HLERequestContext context(kernel, SharedFrom(this), thread.get()); - context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), *current_process); + Kernel::HLERequestContext context(kernel, SharedFrom(this), thread); + context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), current_process); hle_handler->HandleSyncRequest(context); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b5ebaf936..7f7cc1272 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -282,7 +282,7 @@ void SVC::ExitProcess() { // Stop all the process threads that are currently waiting for objects. auto& thread_list = kernel.GetThreadManager().GetThreadList(); for (auto& thread : thread_list) { - if (thread->owner_process != current_process.get()) + if (thread->owner_process != current_process) continue; if (thread.get() == kernel.GetThreadManager().GetCurrentThread()) @@ -403,6 +403,73 @@ ResultCode SVC::CloseHandle(Handle handle) { return kernel.GetCurrentProcess()->handle_table.Close(handle); } +static ResultCode ReceiveIPCRequest(Kernel::KernelSystem& kernel, Memory::MemorySystem& memory, + std::shared_ptr server_session, + std::shared_ptr thread); + +class SVC_SyncCallback : public Kernel::WakeupCallback { +public: + SVC_SyncCallback(bool do_output_) : do_output(do_output_) {} + void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) { + + if (reason == ThreadWakeupReason::Timeout) { + thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); + return; + } + + ASSERT(reason == ThreadWakeupReason::Signal); + + thread->SetWaitSynchronizationResult(RESULT_SUCCESS); + + // The wait_all case does not update the output index. + if (do_output) { + thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); + } + } + +private: + bool do_output; + + SVC_SyncCallback() = default; + template + void serialize(Archive& ar, const unsigned int) { + ar& do_output; + } + friend class boost::serialization::access; +}; + +class SVC_IPCCallback : public Kernel::WakeupCallback { +public: + SVC_IPCCallback(Core::System& system_) : system(system_) {} + + void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) { + + ASSERT(thread->status == ThreadStatus::WaitSynchAny); + ASSERT(reason == ThreadWakeupReason::Signal); + + ResultCode result = RESULT_SUCCESS; + + if (object->GetHandleType() == HandleType::ServerSession) { + auto server_session = DynamicObjectCast(object); + result = ReceiveIPCRequest(system.Kernel(), system.Memory(), server_session, thread); + } + + thread->SetWaitSynchronizationResult(result); + thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); + } + +private: + Core::System& system; + + SVC_IPCCallback() : system(Core::Global()) {} + + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; +}; + /// Wait for a handle to synchronize, timeout after the specified nanoseconds ResultCode SVC::WaitSynchronization1(Handle handle, s64 nano_seconds) { auto object = kernel.GetCurrentProcess()->handle_table.Get(handle); @@ -426,21 +493,7 @@ ResultCode SVC::WaitSynchronization1(Handle handle, s64 nano_seconds) { // Create an event to wake the thread up after the specified nanosecond delay has passed thread->WakeAfterDelay(nano_seconds); - thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(thread->status == ThreadStatus::WaitSynchAny); - - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return; - } - - ASSERT(reason == ThreadWakeupReason::Signal); - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - - // WaitSynchronization1 doesn't have an output index like WaitSynchronizationN, so we - // don't have to do anything else here. - }; + thread->wakeup_callback = std::make_shared(false); system.PrepareReschedule(); @@ -515,20 +568,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle // Create an event to wake the thread up after the specified nanosecond delay has passed thread->WakeAfterDelay(nano_seconds); - thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(thread->status == ThreadStatus::WaitSynchAll); - - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return; - } - - ASSERT(reason == ThreadWakeupReason::Signal); - - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - // The wait_all case does not update the output index. - }; + thread->wakeup_callback = std::make_shared(false); system.PrepareReschedule(); @@ -575,20 +615,7 @@ ResultCode SVC::WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle // Create an event to wake the thread up after the specified nanosecond delay has passed thread->WakeAfterDelay(nano_seconds); - thread->wakeup_callback = [](ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(thread->status == ThreadStatus::WaitSynchAny); - - if (reason == ThreadWakeupReason::Timeout) { - thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); - return; - } - - ASSERT(reason == ThreadWakeupReason::Signal); - - thread->SetWaitSynchronizationResult(RESULT_SUCCESS); - thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); - }; + thread->wakeup_callback = std::make_shared(true); system.PrepareReschedule(); @@ -730,22 +757,7 @@ ResultCode SVC::ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_co thread->wait_objects = std::move(objects); - thread->wakeup_callback = [& kernel = this->kernel, &memory = this->memory]( - ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object) { - ASSERT(thread->status == ThreadStatus::WaitSynchAny); - ASSERT(reason == ThreadWakeupReason::Signal); - - ResultCode result = RESULT_SUCCESS; - - if (object->GetHandleType() == HandleType::ServerSession) { - auto server_session = DynamicObjectCast(object); - result = ReceiveIPCRequest(kernel, memory, server_session, thread); - } - - thread->SetWaitSynchronizationResult(result); - thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); - }; + thread->wakeup_callback = std::make_shared(system); system.PrepareReschedule(); @@ -911,7 +923,7 @@ ResultCode SVC::CreateThread(Handle* out_handle, u32 entry_point, u32 arg, VAddr CASCADE_RESULT(std::shared_ptr thread, kernel.CreateThread(name, entry_point, priority, arg, processor_id, stack_top, - *current_process)); + current_process)); thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 @@ -1020,7 +1032,7 @@ ResultCode SVC::GetProcessIdOfThread(u32* process_id, Handle thread_handle) { if (thread == nullptr) return ERR_INVALID_HANDLE; - const std::shared_ptr process = SharedFrom(thread->owner_process); + const std::shared_ptr process = thread->owner_process; ASSERT_MSG(process != nullptr, "Invalid parent process for thread={:#010X}", thread_handle); @@ -1611,3 +1623,6 @@ void SVCContext::CallSVC(u32 immediate) { } } // namespace Kernel + +SERIALIZE_EXPORT_IMPL(Kernel::SVC_SyncCallback) +SERIALIZE_EXPORT_IMPL(Kernel::SVC_IPCCallback) diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h index efddff9e8..4cf265400 100644 --- a/src/core/hle/kernel/svc.h +++ b/src/core/hle/kernel/svc.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "common/common_types.h" namespace Core { @@ -25,4 +26,10 @@ private: std::unique_ptr impl; }; +class SVC_SyncCallback; +class SVC_IPCCallback; + } // namespace Kernel + +BOOST_CLASS_EXPORT_KEY(Kernel::SVC_SyncCallback) +BOOST_CLASS_EXPORT_KEY(Kernel::SVC_IPCCallback) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 1af2d4f4d..13a3017a5 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -48,7 +48,7 @@ void Thread::serialize(Archive& ar, const unsigned int file_version) { ar& wait_objects; ar& wait_address; ar& name; - // TODO: How the hell to do wakeup_callback + ar& wakeup_callback; } SERIALIZE_IMPL(Thread) @@ -138,8 +138,8 @@ void ThreadManager::SwitchContext(Thread* new_thread) { ready_queue.remove(new_thread->current_priority, new_thread); new_thread->status = ThreadStatus::Running; - if (previous_process.get() != current_thread->owner_process) { - kernel.SetCurrentProcess(SharedFrom(current_thread->owner_process)); + if (previous_process != current_thread->owner_process) { + kernel.SetCurrentProcess(current_thread->owner_process); } cpu->LoadContext(new_thread->context); @@ -196,7 +196,7 @@ void ThreadManager::ThreadWakeupCallback(u64 thread_id, s64 cycles_late) { // Invoke the wakeup callback before clearing the wait objects if (thread->wakeup_callback) - thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr); + thread->wakeup_callback->WakeUp(ThreadWakeupReason::Timeout, thread, nullptr); // Remove the thread from each of its waiting objects' waitlists for (auto& object : thread->wait_objects) @@ -313,10 +313,9 @@ static void ResetThreadContext(const std::unique_ptrSetCpsr(USER32MODE | ((entry_point & 1) << 5)); // Usermode and THUMB mode } -ResultVal> KernelSystem::CreateThread(std::string name, VAddr entry_point, - u32 priority, u32 arg, - s32 processor_id, VAddr stack_top, - Process& owner_process) { +ResultVal> KernelSystem::CreateThread( + std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, VAddr stack_top, + std::shared_ptr owner_process) { // Check if priority is in ranged. Lowest priority -> highest priority id. if (priority > ThreadPrioLowest) { LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); @@ -330,7 +329,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, // TODO(yuriks): Other checks, returning 0xD9001BEA - if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) { + if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) { LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:08x}", name, entry_point); // TODO: Verify error return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, @@ -353,10 +352,10 @@ ResultVal> KernelSystem::CreateThread(std::string name, thread->wait_address = 0; thread->name = std::move(name); thread_manager->wakeup_callback_table[thread->thread_id] = thread.get(); - thread->owner_process = &owner_process; + thread->owner_process = owner_process; // Find the next available TLS index, and mark it as used - auto& tls_slots = owner_process.tls_slots; + auto& tls_slots = owner_process->tls_slots; auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); @@ -372,13 +371,13 @@ ResultVal> KernelSystem::CreateThread(std::string name, "Not enough space in region to allocate a new TLS page for thread"); return ERR_OUT_OF_MEMORY; } - owner_process.memory_used += Memory::PAGE_SIZE; + owner_process->memory_used += Memory::PAGE_SIZE; tls_slots.emplace_back(0); // The page is completely available at the start available_page = tls_slots.size() - 1; available_slot = 0; // Use the first slot in the new page - auto& vm_manager = owner_process.vm_manager; + auto& vm_manager = owner_process->vm_manager; // Map the page to the current process' address space. vm_manager.MapBackingMemory(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, @@ -391,7 +390,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE + available_slot * Memory::TLS_ENTRY_SIZE; - memory.ZeroBlock(owner_process, thread->tls_address, Memory::TLS_ENTRY_SIZE); + memory.ZeroBlock(*owner_process, thread->tls_address, Memory::TLS_ENTRY_SIZE); // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used // to initialize the context @@ -438,7 +437,7 @@ std::shared_ptr SetupMainThread(KernelSystem& kernel, u32 entry_point, u // Initialize new "main" thread auto thread_res = kernel.CreateThread("main", entry_point, priority, 0, owner_process->ideal_processor, - Memory::HEAP_VADDR_END, *owner_process); + Memory::HEAP_VADDR_END, owner_process); std::shared_ptr thread = std::move(thread_res).Unwrap(); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 219db9f2d..9941c76db 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -59,6 +59,15 @@ enum class ThreadWakeupReason { Timeout // The thread was woken up due to a wait timeout. }; +class Thread; + +class WakeupCallback { +public: + virtual ~WakeupCallback() = default; + virtual void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, + std::shared_ptr object) = 0; +}; + class ThreadManager { public: explicit ThreadManager(Kernel::KernelSystem& kernel); @@ -300,7 +309,7 @@ public: /// Mutexes that this thread is currently waiting for. boost::container::flat_set> pending_mutexes; - Process* owner_process; ///< Process that owns this thread + std::shared_ptr owner_process; ///< Process that owns this thread /// Objects that the thread is waiting on, in the same order as they were // passed to WaitSynchronization1/N. @@ -310,12 +319,10 @@ public: std::string name; - using WakeupCallback = void(ThreadWakeupReason reason, std::shared_ptr thread, - std::shared_ptr object); // Callback that will be invoked when the thread is resumed from a waiting state. If the thread // was waiting via WaitSynchronizationN then the object will be the last object that became // available. In case of a timeout, the object will be nullptr. - std::function wakeup_callback; + std::shared_ptr wakeup_callback; private: ThreadManager& thread_manager; diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 94ae632cd..6fe75b6d8 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -80,7 +80,7 @@ void WaitObject::WakeupAllWaitingThreads() { // Invoke the wakeup callback before clearing the wait objects if (thread->wakeup_callback) - thread->wakeup_callback(ThreadWakeupReason::Signal, thread, SharedFrom(this)); + thread->wakeup_callback->WakeUp(ThreadWakeupReason::Signal, thread, SharedFrom(this)); for (auto& object : thread->wait_objects) object->RemoveWaitingThread(thread.get()); diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index 946e27211..c8727314b 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -71,12 +71,7 @@ void File::Read(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(buffer); std::chrono::nanoseconds read_timeout_ns{backend->GetReadDelayNs(length)}; - ctx.SleepClientThread("file::read", read_timeout_ns, - [](std::shared_ptr /*thread*/, - Kernel::HLERequestContext& /*ctx*/, - Kernel::ThreadWakeupReason /*reason*/) { - // Nothing to do here - }); + ctx.SleepClientThread("file::read", read_timeout_ns, nullptr); } void File::Write(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index e027e837f..010600ee2 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -76,12 +76,7 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { LOG_ERROR(Service_FS, "failed to get a handle for file {}", file_path.DebugStr()); } - ctx.SleepClientThread("fs_user::open", open_timeout_ns, - [](std::shared_ptr /*thread*/, - Kernel::HLERequestContext& /*ctx*/, - Kernel::ThreadWakeupReason /*reason*/) { - // Nothing to do here - }); + ctx.SleepClientThread("fs_user::open", open_timeout_ns, nullptr); } void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { @@ -134,12 +129,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { file_path.DebugStr(), mode.hex, attributes); } - ctx.SleepClientThread("fs_user::open_directly", open_timeout_ns, - [](std::shared_ptr /*thread*/, - Kernel::HLERequestContext& /*ctx*/, - Kernel::ThreadWakeupReason /*reason*/) { - // Nothing to do here - }); + ctx.SleepClientThread("fs_user::open_directly", open_timeout_ns, nullptr); } void FS_USER::DeleteFile(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index dddf55333..eef8cbd1d 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -1170,6 +1170,29 @@ void NWM_UDS::GetChannel(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_NWM, "called"); } +class NWM_UDS::ThreadCallback : public Kernel::HLERequestContext::WakeupCallback { +public: + ThreadCallback(u16 command_id_) : command_id(command_id_) {} + + void WakeUp(std::shared_ptr thread, Kernel::HLERequestContext& ctx, + Kernel::ThreadWakeupReason reason) { + // TODO(B3N30): Add error handling for host full and timeout + IPC::RequestBuilder rb(ctx, command_id, 1, 0); + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NWM, "connection sequence finished"); + } + +private: + ThreadCallback() = default; + u16 command_id; + + template + void serialize(Archive& ar, const unsigned int) { + ar& command_id; + } + friend class boost::serialization::access; +}; + void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, const u8* network_info_buffer, std::size_t network_info_size, u8 connection_type, std::vector passphrase) { @@ -1183,15 +1206,8 @@ void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx, u16 command_id, // Since this timing is handled by core_timing it could differ from the 'real world' time static constexpr std::chrono::nanoseconds UDSConnectionTimeout{300000000}; - connection_event = ctx.SleepClientThread( - "uds::ConnectToNetwork", UDSConnectionTimeout, - [command_id](std::shared_ptr thread, Kernel::HLERequestContext& ctx, - Kernel::ThreadWakeupReason reason) { - // TODO(B3N30): Add error handling for host full and timeout - IPC::RequestBuilder rb(ctx, command_id, 1, 0); - rb.Push(RESULT_SUCCESS); - LOG_DEBUG(Service_NWM, "connection sequence finished"); - }); + connection_event = ctx.SleepClientThread("uds::ConnectToNetwork", UDSConnectionTimeout, + std::make_shared(command_id)); } void NWM_UDS::ConnectToNetwork(Kernel::HLERequestContext& ctx) { @@ -1418,3 +1434,5 @@ NWM_UDS::~NWM_UDS() { } } // namespace Service::NWM + +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_UDS::ThreadCallback) diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index 07dd7e9ba..b2ab1d76a 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "common/common_types.h" #include "common/swap.h" #include "core/hle/service/service.h" @@ -127,6 +128,8 @@ public: explicit NWM_UDS(Core::System& system); ~NWM_UDS(); + class ThreadCallback; + private: Core::System& system; @@ -560,3 +563,4 @@ private: SERVICE_CONSTRUCT(Service::NWM::NWM_UDS) BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_UDS) +BOOST_CLASS_EXPORT_KEY(Service::NWM::NWM_UDS::ThreadCallback) diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 396bd3559..10179f416 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/core.h" @@ -71,6 +72,46 @@ void SRV::EnableNotification(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_SRV, "(STUBBED) called"); } +class SRV::ThreadCallback : public Kernel::HLERequestContext::WakeupCallback { + +public: + ThreadCallback(Core::System& system_, std::string name_) : system(system_), name(name_) {} + + void WakeUp(std::shared_ptr thread, Kernel::HLERequestContext& ctx, + Kernel::ThreadWakeupReason reason) { + LOG_ERROR(Service_SRV, "called service={} wakeup", name); + auto client_port = system.ServiceManager().GetServicePort(name); + + auto session = client_port.Unwrap()->Connect(); + if (session.Succeeded()) { + LOG_DEBUG(Service_SRV, "called service={} -> session={}", name, + (*session)->GetObjectId()); + IPC::RequestBuilder rb(ctx, 0x5, 1, 2); + rb.Push(session.Code()); + rb.PushMoveObjects(std::move(session).Unwrap()); + } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED) { + LOG_ERROR(Service_SRV, "called service={} -> ERR_MAX_CONNECTIONS_REACHED", name); + UNREACHABLE(); + } else { + LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, session.Code().raw); + IPC::RequestBuilder rb(ctx, 0x5, 1, 0); + rb.Push(session.Code()); + } + } + +private: + Core::System& system; + std::string name; + + ThreadCallback() : system(Core::Global()) {} + + template + void serialize(Archive& ar, const unsigned int) { + ar& name; + } + friend class boost::serialization::access; +}; + /** * SRV::GetServiceHandle service function * Inputs: @@ -100,28 +141,7 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { // TODO(yuriks): Permission checks go here - auto get_handle = [name, this](std::shared_ptr thread, - Kernel::HLERequestContext& ctx, - Kernel::ThreadWakeupReason reason) { - LOG_ERROR(Service_SRV, "called service={} wakeup", name); - auto client_port = system.ServiceManager().GetServicePort(name); - - auto session = client_port.Unwrap()->Connect(); - if (session.Succeeded()) { - LOG_DEBUG(Service_SRV, "called service={} -> session={}", name, - (*session)->GetObjectId()); - IPC::RequestBuilder rb(ctx, 0x5, 1, 2); - rb.Push(session.Code()); - rb.PushMoveObjects(std::move(session).Unwrap()); - } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED) { - LOG_ERROR(Service_SRV, "called service={} -> ERR_MAX_CONNECTIONS_REACHED", name); - UNREACHABLE(); - } else { - LOG_ERROR(Service_SRV, "called service={} -> error 0x{:08X}", name, session.Code().raw); - IPC::RequestBuilder rb(ctx, 0x5, 1, 0); - rb.Push(session.Code()); - } - }; + auto get_handle = std::make_shared(system, name); auto client_port = system.ServiceManager().GetServicePort(name); if (client_port.Failed()) { @@ -266,3 +286,5 @@ SRV::SRV(Core::System& system) : ServiceFramework("srv:", 4), system(system) { SRV::~SRV() = default; } // namespace Service::SM + +SERIALIZE_EXPORT_IMPL(Service::SM::SRV::ThreadCallback) diff --git a/src/core/hle/service/sm/srv.h b/src/core/hle/service/sm/srv.h index 2382f4842..7d17f87a5 100644 --- a/src/core/hle/service/sm/srv.h +++ b/src/core/hle/service/sm/srv.h @@ -6,6 +6,7 @@ #include #include +#include #include "core/hle/service/service.h" namespace Core { @@ -25,6 +26,8 @@ public: explicit SRV(Core::System& system); ~SRV(); + class ThreadCallback; + private: void RegisterClient(Kernel::HLERequestContext& ctx); void EnableNotification(Kernel::HLERequestContext& ctx); @@ -40,3 +43,5 @@ private: }; } // namespace Service::SM + +BOOST_CLASS_EXPORT_KEY(Service::SM::SRV::ThreadCallback) diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 414d64021..a4f7c8062 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -37,7 +37,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel IPC::MakeHeader(0x1234, 0, 0), }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); REQUIRE(context.CommandBuffer()[0] == 0x12340000); } @@ -50,7 +50,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0xAABBCCDD, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); REQUIRE(output[1] == 0x12345678); @@ -67,7 +67,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel a_handle, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); @@ -83,7 +83,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel a_handle, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); @@ -103,7 +103,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel process->handle_table.Create(c).Unwrap(), }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); @@ -118,7 +118,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0, }; - auto result = context.PopulateFromIncomingCommandBuffer(input, *process); + auto result = context.PopulateFromIncomingCommandBuffer(input, process); REQUIRE(result == RESULT_SUCCESS); auto* output = context.CommandBuffer(); @@ -132,7 +132,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0x98989898, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); REQUIRE(context.CommandBuffer()[2] == process->process_id); } @@ -153,7 +153,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); CHECK(context.GetStaticBuffer(0) == mem->Vector()); @@ -175,7 +175,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); std::vector other_buffer(buffer.GetSize()); context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer.GetSize()); @@ -219,7 +219,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address_mapped, }; - context.PopulateFromIncomingCommandBuffer(input, *process); + context.PopulateFromIncomingCommandBuffer(input, process); auto* output = context.CommandBuffer(); CHECK(output[1] == 0x12345678); @@ -365,7 +365,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { target_address, }; - context.PopulateFromIncomingCommandBuffer(input_cmdbuff, *process); + context.PopulateFromIncomingCommandBuffer(input_cmdbuff, process); context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size()); From f2de70c3fbdef9ac16bcbc5c6773c97311bd663b Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 6 Jan 2020 23:20:18 +0000 Subject: [PATCH 062/129] Fix crash bugs --- CMakeLists.txt | 2 +- TODO | 14 +++++++------- save0.citrasave | Bin 0 -> 776 bytes src/common/archives.h | 3 +-- src/core/core.cpp | 20 ++++++++++++++------ src/core/hle/kernel/hle_ipc.h | 2 +- src/core/hle/kernel/server_session.cpp | 9 +++++---- src/core/memory.cpp | 3 +++ 8 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 save0.citrasave diff --git a/CMakeLists.txt b/CMakeLists.txt index f986a39af..45deee61a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,7 +123,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # set up output paths for executable binaries -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}) # System imported libraries diff --git a/TODO b/TODO index 097c310a7..a422fda4d 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,11 @@ ☐ Save/load UI ✔ Basic version @done(20-01-03 15:27) ☐ Multiple slots etc. +☐ Custom texture cache +☐ Review constructor/initialization code +☐ Review core timing events +☐ Review base class serialization everywhere +☐ Serialize codeset with an apploader reference instead ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ Page tables @done(20-01-05 16:33) @@ -32,7 +37,6 @@ Not needed as nothing serializes file buffers ✘ Replace delay generator with virtual fns @cancelled(20-01-03 13:16) While they have no state, the extra refactoring here is unneeded -☐ Custom texture cache ✘ MMIO @cancelled(20-01-01 01:06) Seems that this whole subsystem is only used in tests ✘ Movie @cancelled(20-01-01 01:07) @@ -44,9 +48,6 @@ ✘ Telemetry session @cancelled(20-01-01 01:12) Doesn't need to be serialized here ✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) -☐ Review constructor/initialization code -☐ Review core timing events -☐ Review base class serialization everywhere ✔ Fix CI @done(19-12-31 21:32) ✔ HW @done(19-08-13 15:41) ✔ GPU regs @done(19-08-13 15:41) @@ -57,8 +58,8 @@ ✔ PICA state @done(19-08-13 15:41) ✔ Primitive assembly @done(19-12-22 16:05) ✔ Shader @done(19-08-13 16:03) -☐ HLE @started(19-08-13 16:43) - ☐ Kernel @started(19-08-13 16:43) +✔ HLE @started(19-08-13 16:43) @done(20-01-06 20:37) @lasted(20w6d4h54m19s) + ✔ Kernel @started(19-08-13 16:43) @done(20-01-06 20:37) @lasted(20w6d4h54m17s) Most of these require adding Core::Global ✔ Address arbiter @done(19-08-13 16:40) ✔ Client port @done(19-08-13 16:40) @@ -74,7 +75,6 @@ ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) ✔ Code set @started(19-12-22 18:41) @done(20-01-03 15:15) @lasted(1w4d20h34m2s) Needs a way to reference loaded images (so we don't serialize the entire ROM as well) - ☐ Serialize codeset with an apploader reference instead ✔ Resource limit @done(19-08-13 16:43) ✔ Semaphore @done(19-08-13 16:44) ✔ Server port @done(19-08-13 16:44) diff --git a/save0.citrasave b/save0.citrasave new file mode 100644 index 0000000000000000000000000000000000000000..578174ec6b7489150da4ff634caacf0e34d2ddd8 GIT binary patch literal 776 zcmWe*fPmuEqRhmc%&Nqa%=|nntHh$@jLfoBK?W8U77j+J8VJP9?L0*8h?10RqH1|V?|A17eUl4nX1q zlntb43brUPIsz>Kd4++2my6*Yh!z9_5UsL-A0!C@U@rjWfQ|zq29QTVfSFN%k%^f} zfI&eCB+MWP^p>C^gOH$rlAxiY0HY&Nw8DXvfgdC}gusXY|Nn!WyQGVg;ep2k7Zj)K z{eZ+8iXbT*ADCiTFv9qtbN~VcxmJk<1>lfo1CtP8ILQfOfdU*DXW(!L6CgooJb{=H X09FNMLyV0NPAw`+ErKZk({Muob(AbM literal 0 HcmV?d00001 diff --git a/src/common/archives.h b/src/common/archives.h index 29f23865b..6000bef2c 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -11,5 +11,4 @@ using oarchive = boost::archive::binary_oarchive; #define SERIALIZE_EXPORT_IMPL(A) \ BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ - BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) \ - BOOST_CLASS_EXPORT_IMPLEMENT(A) + BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) diff --git a/src/core/core.cpp b/src/core/core.cpp index bada80b55..20a8f32fe 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -44,6 +44,8 @@ #include "network/network.h" #include "video_core/video_core.h" +#include "core/hle/service/pm/pm_app.h" + namespace Core { /*static*/ System System::s_instance; @@ -214,8 +216,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique(*memory, *timing, - [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique( + *memory, *timing, [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -420,11 +422,17 @@ void System::serialize(Archive& ar, const unsigned int file_version) { } void System::Save(std::ostream& stream) const { - { - oarchive oa{stream}; - oa&* this; + try { + + { + oarchive oa{stream}; + oa&* this; + } + VideoCore::Save(stream); + + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error saving: {}", e.what()); } - VideoCore::Save(stream); } void System::Load(std::istream& stream) { diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 56c6d8ce1..01fec190b 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -198,7 +198,7 @@ private: * id of the memory interface and let kernel convert it back to client vaddr. No real unmapping is * needed in this case, though. */ -class HLERequestContext : std::enable_shared_from_this { +class HLERequestContext : public std::enable_shared_from_this { public: HLERequestContext(KernelSystem& kernel, std::shared_ptr session, std::shared_ptr thread); diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 8bb82fc83..3dc20e9a7 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -75,10 +75,11 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { kernel.memory.ReadBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), cmd_buf.size() * sizeof(u32)); - Kernel::HLERequestContext context(kernel, SharedFrom(this), thread); - context.PopulateFromIncomingCommandBuffer(cmd_buf.data(), current_process); + auto context = + std::make_shared(kernel, SharedFrom(this), thread); + context->PopulateFromIncomingCommandBuffer(cmd_buf.data(), current_process); - hle_handler->HandleSyncRequest(context); + hle_handler->HandleSyncRequest(*context); ASSERT(thread->status == Kernel::ThreadStatus::Running || thread->status == Kernel::ThreadStatus::WaitHleEvent); @@ -86,7 +87,7 @@ ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread) { // put the thread to sleep then the writing of the command buffer will be deferred to the // wakeup callback. if (thread->status == Kernel::ThreadStatus::Running) { - context.WriteToOutgoingCommandBuffer(cmd_buf.data(), *current_process); + context->WriteToOutgoingCommandBuffer(cmd_buf.data(), *current_process); kernel.memory.WriteBlock(*current_process, thread->GetCommandBufferAddress(), cmd_buf.data(), cmd_buf.size() * sizeof(u32)); } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index ceb6aad4e..cd3cf8aed 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -452,6 +452,9 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) { default: UNREACHABLE(); } + if (offset_into_region >= target_mem->GetSize()) { + return {nullptr}; + } return {target_mem, offset_into_region}; } From 996aba39feda48356cddc61af1242cff7b5551e4 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 8 Jan 2020 22:13:56 +0000 Subject: [PATCH 063/129] Correct exports; add some file serialization; fix service base object serialization --- TODO | 1 + src/common/archives.h | 1 + src/common/file_util.cpp | 8 ++++++ src/common/file_util.h | 29 ++++++++++++++++++++- src/common/memory_ref.h | 6 +++++ src/core/file_sys/archive_extsavedata.cpp | 4 +++ src/core/file_sys/archive_extsavedata.h | 3 +++ src/core/file_sys/archive_sdmc.cpp | 4 +++ src/core/file_sys/archive_sdmc.h | 3 +++ src/core/file_sys/archive_sdmcwriteonly.cpp | 4 +++ src/core/file_sys/archive_sdmcwriteonly.h | 3 +++ src/core/file_sys/delay_generator.h | 12 ++++++++- src/core/file_sys/disk_archive.h | 9 +++++++ src/core/file_sys/file_backend.h | 8 ++++++ src/core/file_sys/savedata_archive.cpp | 5 ++++ src/core/file_sys/savedata_archive.h | 4 +++ src/core/hle/service/cam/cam_q.h | 6 +---- src/core/hle/service/cfg/cfg_nor.h | 3 +++ src/core/hle/service/dlp/dlp_clnt.h | 6 +---- src/core/hle/service/dlp/dlp_fkcl.h | 6 +---- src/core/hle/service/dlp/dlp_srvr.h | 6 +---- src/core/hle/service/err_f.h | 6 +---- src/core/hle/service/fs/file.h | 11 ++++++++ src/core/hle/service/fs/fs_user.h | 2 ++ src/core/hle/service/gsp/gsp_gpu.h | 2 ++ src/core/hle/service/http_c.h | 2 ++ src/core/hle/service/ldr_ro/ldr_ro.h | 2 ++ src/core/hle/service/mic_u.cpp | 1 + src/core/hle/service/mvd/mvd_std.h | 6 +---- src/core/hle/service/news/news_s.h | 2 ++ src/core/hle/service/news/news_u.h | 3 +++ src/core/hle/service/nim/nim_aoc.h | 3 +++ src/core/hle/service/nim/nim_s.h | 3 +++ src/core/hle/service/nwm/nwm_cec.h | 3 +++ src/core/hle/service/nwm/nwm_ext.h | 3 +++ src/core/hle/service/nwm/nwm_inf.h | 3 +++ src/core/hle/service/nwm/nwm_sap.h | 3 +++ src/core/hle/service/nwm/nwm_soc.h | 3 +++ src/core/hle/service/nwm/nwm_tst.h | 3 +++ src/core/hle/service/nwm/nwm_uds.cpp | 1 + src/core/hle/service/pm/pm_app.h | 3 +++ src/core/hle/service/pm/pm_dbg.h | 3 +++ src/core/hle/service/ps/ps_ps.h | 2 ++ src/core/hle/service/pxi/dev.h | 3 +++ src/core/hle/service/qtm/qtm_c.h | 3 +++ src/core/hle/service/qtm/qtm_s.h | 3 +++ src/core/hle/service/qtm/qtm_sp.h | 3 +++ src/core/hle/service/qtm/qtm_u.h | 3 +++ src/core/hle/service/service.h | 7 +++++ src/core/hle/service/ssl_c.h | 2 ++ src/core/hle/service/y2r_u.cpp | 1 + src/core/memory.cpp | 4 ++- 52 files changed, 197 insertions(+), 33 deletions(-) diff --git a/TODO b/TODO index a422fda4d..def70ac2b 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,7 @@ ☐ Review constructor/initialization code ☐ Review core timing events ☐ Review base class serialization everywhere + Make sure that all base/derived relationships are registered ☐ Serialize codeset with an apploader reference instead ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) diff --git a/src/common/archives.h b/src/common/archives.h index 6000bef2c..eef292634 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -10,5 +10,6 @@ using oarchive = boost::archive::binary_oarchive; template void A::serialize(oarchive & ar, const unsigned int file_version); #define SERIALIZE_EXPORT_IMPL(A) \ + BOOST_CLASS_EXPORT_IMPLEMENT(A) \ BOOST_SERIALIZATION_REGISTER_ARCHIVE(iarchive) \ BOOST_SERIALIZATION_REGISTER_ARCHIVE(oarchive) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index d59e34dae..ca86f7bfc 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -901,10 +901,18 @@ IOFile& IOFile::operator=(IOFile&& other) { void IOFile::Swap(IOFile& other) { std::swap(m_file, other.m_file); std::swap(m_good, other.m_good); + std::swap(filename, other.filename); + std::swap(openmode, other.openmode); + std::swap(flags, other.flags); } bool IOFile::Open(const std::string& filename, const char openmode[], int flags) { Close(); + + this->filename = filename; + this->openmode = openmode; + this->flags = flags; + #ifdef _WIN32 if (flags != 0) { m_file = _wfsopen(Common::UTF8ToUTF16W(filename).c_str(), diff --git a/src/common/file_util.h b/src/common/file_util.h index 09c3cb6f0..c09aa88d6 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #ifdef _MSC_VER #include "common/string_util.h" @@ -221,7 +223,6 @@ public: void Swap(IOFile& other); - bool Open(const std::string& filename, const char openmode[], int flags = 0); bool Close(); template @@ -305,8 +306,34 @@ public: } private: + bool Open(const std::string& filename, const char openmode[], int flags = 0); + std::FILE* m_file = nullptr; bool m_good = true; + + std::string filename; + std::string openmode; + u32 flags; + + template + void save(Archive& ar, const unsigned int) const { + ar << filename; + ar << openmode; + ar << flags; + ar << Tell(); + } + + template + void load(Archive& ar, const unsigned int) { + ar >> filename; + ar >> openmode; + ar >> flags; + u64 pos; + ar >> pos; + Seek(pos, SEEK_SET); + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; } // namespace FileUtil diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index 05b1c7901..ae30b009c 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -14,6 +14,11 @@ public: virtual ~BackingMem() = default; virtual u8* GetPtr() = 0; virtual u32 GetSize() const = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; /// Backing memory implemented by a local buffer @@ -39,6 +44,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& data; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 22084b690..59973b8c5 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -80,6 +80,8 @@ public: static constexpr u64 IPCDelayNanoseconds(3085068); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; /** @@ -300,3 +302,5 @@ void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::ExtSaveDataDelayGenerator) diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index b00e1633d..c9b84c984 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -103,6 +103,9 @@ std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) */ Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low); +class ExtSaveDataDelayGenerator; + } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_ExtSaveData) +BOOST_CLASS_EXPORT_KEY(FileSys::ExtSaveDataDelayGenerator) diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 1c5118320..4c3ce6d69 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -41,6 +41,8 @@ public: static constexpr u64 IPCDelayNanoseconds(269082); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; ResultVal> SDMCArchive::OpenFile(const Path& path, @@ -409,3 +411,5 @@ ResultVal ArchiveFactory_SDMC::GetFormatInfo(const Path& path return ResultCode(-1); } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::SDMCDelayGenerator) diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 2e0abf44b..6051abef0 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -86,7 +86,10 @@ private: friend class boost::serialization::access; }; +class SDMCDelayGenerator; + } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::SDMCArchive) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMC) +BOOST_CLASS_EXPORT_KEY(FileSys::SDMCDelayGenerator) diff --git a/src/core/file_sys/archive_sdmcwriteonly.cpp b/src/core/file_sys/archive_sdmcwriteonly.cpp index ea64dc864..241e93f0a 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.cpp +++ b/src/core/file_sys/archive_sdmcwriteonly.cpp @@ -39,6 +39,8 @@ public: static constexpr u64 IPCDelayNanoseconds(269082); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; ResultVal> SDMCWriteOnlyArchive::OpenFile(const Path& path, @@ -100,3 +102,5 @@ ResultVal ArchiveFactory_SDMCWriteOnly::GetFormatInfo(const P } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::SDMCWriteOnlyDelayGenerator) diff --git a/src/core/file_sys/archive_sdmcwriteonly.h b/src/core/file_sys/archive_sdmcwriteonly.h index 2ba504aa7..19982a9db 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.h +++ b/src/core/file_sys/archive_sdmcwriteonly.h @@ -72,7 +72,10 @@ private: friend class boost::serialization::access; }; +class SDMCWriteOnlyDelayGenerator; + } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::SDMCWriteOnlyArchive) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SDMCWriteOnly) +BOOST_CLASS_EXPORT_KEY(FileSys::SDMCWriteOnlyDelayGenerator) diff --git a/src/core/file_sys/delay_generator.h b/src/core/file_sys/delay_generator.h index 8fa92ac41..6513a730e 100644 --- a/src/core/file_sys/delay_generator.h +++ b/src/core/file_sys/delay_generator.h @@ -5,10 +5,18 @@ #pragma once #include -#include +#include #include #include "common/common_types.h" +#define SERIALIZE_DELAY_GENERATOR \ +private: \ + template \ + void serialize(Archive& ar, const unsigned int) { \ + ar& boost::serialization::base_object(*this); \ + } \ + friend class boost::serialization::access; + namespace FileSys { class DelayGenerator { @@ -28,6 +36,8 @@ class DefaultDelayGenerator : public DelayGenerator { public: u64 GetReadDelayNs(std::size_t length) override; u64 GetOpenDelayNs() override; + + SERIALIZE_DELAY_GENERATOR }; } // namespace FileSys diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h index 481aa470a..9251749ce 100644 --- a/src/core/file_sys/disk_archive.h +++ b/src/core/file_sys/disk_archive.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "common/file_util.h" #include "core/file_sys/archive_backend.h" @@ -43,6 +45,13 @@ public: protected: Mode mode; std::unique_ptr file; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& mode; + ar& file; + } }; class DiskDirectory : public DirectoryBackend { diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index c865c98e8..04f03a77d 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "core/hle/result.h" #include "delay_generator.h" @@ -90,6 +92,12 @@ public: protected: std::unique_ptr delay_generator; + + template + void serialize(Archive& ar, const unsigned int) { + ar& delay_generator; + } + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/file_sys/savedata_archive.cpp b/src/core/file_sys/savedata_archive.cpp index 8d7830468..1f22b50ab 100644 --- a/src/core/file_sys/savedata_archive.cpp +++ b/src/core/file_sys/savedata_archive.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/file_util.h" #include "core/file_sys/disk_archive.h" #include "core/file_sys/errors.h" @@ -33,6 +34,8 @@ public: static constexpr u64 IPCDelayNanoseconds(269082); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; ResultVal> SaveDataArchive::OpenFile(const Path& path, @@ -353,3 +356,5 @@ u64 SaveDataArchive::GetFreeBytes() const { } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::SaveDataDelayGenerator) diff --git a/src/core/file_sys/savedata_archive.h b/src/core/file_sys/savedata_archive.h index 176d35710..47f2f75e0 100644 --- a/src/core/file_sys/savedata_archive.h +++ b/src/core/file_sys/savedata_archive.h @@ -40,4 +40,8 @@ protected: std::string mount_point; }; +class SaveDataDelayGenerator; + } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataDelayGenerator) diff --git a/src/core/hle/service/cam/cam_q.h b/src/core/hle/service/cam/cam_q.h index ab901cf85..992b38390 100644 --- a/src/core/hle/service/cam/cam_q.h +++ b/src/core/hle/service/cam/cam_q.h @@ -13,11 +13,7 @@ public: CAM_Q(); private: - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::CAM diff --git a/src/core/hle/service/cfg/cfg_nor.h b/src/core/hle/service/cfg/cfg_nor.h index 1eca85a05..7e0a1a2b8 100644 --- a/src/core/hle/service/cfg/cfg_nor.h +++ b/src/core/hle/service/cfg/cfg_nor.h @@ -11,6 +11,9 @@ namespace Service::CFG { class CFG_NOR final : public ServiceFramework { public: CFG_NOR(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::CFG diff --git a/src/core/hle/service/dlp/dlp_clnt.h b/src/core/hle/service/dlp/dlp_clnt.h index 835d01748..ac6933e7e 100644 --- a/src/core/hle/service/dlp/dlp_clnt.h +++ b/src/core/hle/service/dlp/dlp_clnt.h @@ -14,11 +14,7 @@ public: ~DLP_CLNT() = default; private: - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::DLP diff --git a/src/core/hle/service/dlp/dlp_fkcl.h b/src/core/hle/service/dlp/dlp_fkcl.h index d778ace8b..c05a77b49 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.h +++ b/src/core/hle/service/dlp/dlp_fkcl.h @@ -14,11 +14,7 @@ public: ~DLP_FKCL() = default; private: - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::DLP diff --git a/src/core/hle/service/dlp/dlp_srvr.h b/src/core/hle/service/dlp/dlp_srvr.h index 1f171f950..625740d2f 100644 --- a/src/core/hle/service/dlp/dlp_srvr.h +++ b/src/core/hle/service/dlp/dlp_srvr.h @@ -16,11 +16,7 @@ public: private: void IsChild(Kernel::HLERequestContext& ctx); - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::DLP diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h index de92fed05..1b9fad452 100644 --- a/src/core/hle/service/err_f.h +++ b/src/core/hle/service/err_f.h @@ -35,11 +35,7 @@ private: Core::System& system; - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; void InstallInterfaces(Core::System& system); diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index ff4a5670a..18317212e 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -19,6 +19,17 @@ struct FileSessionSlot : public Kernel::SessionRequestHandler::SessionDataBase { u64 offset; ///< Offset that this session will start reading from. u64 size; ///< Max size of the file that this session is allowed to access bool subfile; ///< Whether this file was opened via OpenSubFile or not. + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); + ar& priority; + ar& offset; + ar& size; + ar& subfile; + } }; // TODO: File is not a real service, but it can still utilize ServiceFramework::RegisterHandlers. diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 29b47a99c..83183ecf6 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -26,6 +26,8 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); ar& program_id; } friend class boost::serialization::access; diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index 6194f0446..a97aee278 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -203,6 +203,8 @@ public: private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); ar& gsp; ar& interrupt_event; ar& thread_id; diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h index a3aa62ae0..641b6b4d1 100644 --- a/src/core/hle/service/http_c.h +++ b/src/core/hle/service/http_c.h @@ -240,6 +240,8 @@ struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); ar& current_http_context; ar& session_id; ar& num_http_contexts; diff --git a/src/core/hle/service/ldr_ro/ldr_ro.h b/src/core/hle/service/ldr_ro/ldr_ro.h index 2b6f79f03..7581884f6 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.h +++ b/src/core/hle/service/ldr_ro/ldr_ro.h @@ -18,6 +18,8 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); ar& loaded_crs; } friend class boost::serialization::access; diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 34b16094a..478bf110f 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -25,6 +25,7 @@ namespace Service::MIC { template void MIC_U::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar&* impl.get(); } SERIALIZE_IMPL(MIC_U) diff --git a/src/core/hle/service/mvd/mvd_std.h b/src/core/hle/service/mvd/mvd_std.h index 6e8312e59..fed41e6f0 100644 --- a/src/core/hle/service/mvd/mvd_std.h +++ b/src/core/hle/service/mvd/mvd_std.h @@ -14,11 +14,7 @@ public: ~MVD_STD() = default; private: - template - void serialize(Archive& ar, const unsigned int) { - ar& boost::serialization::base_object(*this); - } - friend class boost::serialization::access; + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::MVD diff --git a/src/core/hle/service/news/news_s.h b/src/core/hle/service/news/news_s.h index 711a0e99b..9d1ce829f 100644 --- a/src/core/hle/service/news/news_s.h +++ b/src/core/hle/service/news/news_s.h @@ -24,6 +24,8 @@ private: * 2 : Number of notifications */ void GetTotalNotifications(Kernel::HLERequestContext& ctx); + + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NEWS diff --git a/src/core/hle/service/news/news_u.h b/src/core/hle/service/news/news_u.h index 472dd579c..8e672256d 100644 --- a/src/core/hle/service/news/news_u.h +++ b/src/core/hle/service/news/news_u.h @@ -12,6 +12,9 @@ namespace Service::NEWS { class NEWS_U final : public ServiceFramework { public: NEWS_U(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NEWS diff --git a/src/core/hle/service/nim/nim_aoc.h b/src/core/hle/service/nim/nim_aoc.h index 2d06a9d1c..003b3fd85 100644 --- a/src/core/hle/service/nim/nim_aoc.h +++ b/src/core/hle/service/nim/nim_aoc.h @@ -12,6 +12,9 @@ class NIM_AOC final : public ServiceFramework { public: NIM_AOC(); ~NIM_AOC(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NIM diff --git a/src/core/hle/service/nim/nim_s.h b/src/core/hle/service/nim/nim_s.h index 6281270f5..10b041456 100644 --- a/src/core/hle/service/nim/nim_s.h +++ b/src/core/hle/service/nim/nim_s.h @@ -12,6 +12,9 @@ class NIM_S final : public ServiceFramework { public: NIM_S(); ~NIM_S(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NIM diff --git a/src/core/hle/service/nwm/nwm_cec.h b/src/core/hle/service/nwm/nwm_cec.h index 4f62f32f1..674c98cae 100644 --- a/src/core/hle/service/nwm/nwm_cec.h +++ b/src/core/hle/service/nwm/nwm_cec.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_CEC final : public ServiceFramework { public: NWM_CEC(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_ext.h b/src/core/hle/service/nwm/nwm_ext.h index a8d43df70..1e8bcfde3 100644 --- a/src/core/hle/service/nwm/nwm_ext.h +++ b/src/core/hle/service/nwm/nwm_ext.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_EXT final : public ServiceFramework { public: NWM_EXT(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_inf.h b/src/core/hle/service/nwm/nwm_inf.h index f13fd4158..9f8c65a2b 100644 --- a/src/core/hle/service/nwm/nwm_inf.h +++ b/src/core/hle/service/nwm/nwm_inf.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_INF final : public ServiceFramework { public: NWM_INF(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_sap.h b/src/core/hle/service/nwm/nwm_sap.h index 1a289542c..0422dc658 100644 --- a/src/core/hle/service/nwm/nwm_sap.h +++ b/src/core/hle/service/nwm/nwm_sap.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_SAP final : public ServiceFramework { public: NWM_SAP(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_soc.h b/src/core/hle/service/nwm/nwm_soc.h index 883a20854..f13490e83 100644 --- a/src/core/hle/service/nwm/nwm_soc.h +++ b/src/core/hle/service/nwm/nwm_soc.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_SOC final : public ServiceFramework { public: NWM_SOC(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_tst.h b/src/core/hle/service/nwm/nwm_tst.h index e58fa3371..576d4d124 100644 --- a/src/core/hle/service/nwm/nwm_tst.h +++ b/src/core/hle/service/nwm/nwm_tst.h @@ -11,6 +11,9 @@ namespace Service::NWM { class NWM_TST final : public ServiceFramework { public: NWM_TST(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::NWM diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index eef8cbd1d..2aa64f7fc 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -28,6 +28,7 @@ namespace Service::NWM { template void NWM_UDS::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& node_map; ar& connection_event; ar& received_beacons; diff --git a/src/core/hle/service/pm/pm_app.h b/src/core/hle/service/pm/pm_app.h index 0fb290aba..9aefb0cee 100644 --- a/src/core/hle/service/pm/pm_app.h +++ b/src/core/hle/service/pm/pm_app.h @@ -12,6 +12,9 @@ class PM_APP final : public ServiceFramework { public: PM_APP(); ~PM_APP() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::PM diff --git a/src/core/hle/service/pm/pm_dbg.h b/src/core/hle/service/pm/pm_dbg.h index 1cfdea6fe..3a6e3c5c7 100644 --- a/src/core/hle/service/pm/pm_dbg.h +++ b/src/core/hle/service/pm/pm_dbg.h @@ -12,6 +12,9 @@ class PM_DBG final : public ServiceFramework { public: PM_DBG(); ~PM_DBG() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::PM diff --git a/src/core/hle/service/ps/ps_ps.h b/src/core/hle/service/ps/ps_ps.h index 39f6d62b2..f5005d444 100644 --- a/src/core/hle/service/ps/ps_ps.h +++ b/src/core/hle/service/ps/ps_ps.h @@ -18,6 +18,8 @@ public: ~PS_PS() = default; private: + SERVICE_SERIALIZATION_SIMPLE + /** * PS_PS::SignRsaSha256 service function * Inputs: diff --git a/src/core/hle/service/pxi/dev.h b/src/core/hle/service/pxi/dev.h index ed17435b6..f16491077 100644 --- a/src/core/hle/service/pxi/dev.h +++ b/src/core/hle/service/pxi/dev.h @@ -13,6 +13,9 @@ class DEV final : public ServiceFramework { public: DEV(); ~DEV(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::PXI diff --git a/src/core/hle/service/qtm/qtm_c.h b/src/core/hle/service/qtm/qtm_c.h index 8ad05b6e1..b601cd9de 100644 --- a/src/core/hle/service/qtm/qtm_c.h +++ b/src/core/hle/service/qtm/qtm_c.h @@ -12,6 +12,9 @@ class QTM_C final : public ServiceFramework { public: QTM_C(); ~QTM_C() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::QTM diff --git a/src/core/hle/service/qtm/qtm_s.h b/src/core/hle/service/qtm/qtm_s.h index 51e1a4bc8..b32a497db 100644 --- a/src/core/hle/service/qtm/qtm_s.h +++ b/src/core/hle/service/qtm/qtm_s.h @@ -12,6 +12,9 @@ class QTM_S final : public ServiceFramework { public: QTM_S(); ~QTM_S() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::QTM diff --git a/src/core/hle/service/qtm/qtm_sp.h b/src/core/hle/service/qtm/qtm_sp.h index 3c16dea37..2f290f192 100644 --- a/src/core/hle/service/qtm/qtm_sp.h +++ b/src/core/hle/service/qtm/qtm_sp.h @@ -12,6 +12,9 @@ class QTM_SP final : public ServiceFramework { public: QTM_SP(); ~QTM_SP() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::QTM diff --git a/src/core/hle/service/qtm/qtm_u.h b/src/core/hle/service/qtm/qtm_u.h index f6b54c8af..d1aee1e97 100644 --- a/src/core/hle/service/qtm/qtm_u.h +++ b/src/core/hle/service/qtm/qtm_u.h @@ -12,6 +12,9 @@ class QTM_U final : public ServiceFramework { public: QTM_U(); ~QTM_U() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::QTM diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index d39e72aca..0261d061f 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -219,6 +219,13 @@ extern const std::array service_module_map; friend class boost::serialization::access; \ friend class ::construct_access; +#define SERVICE_SERIALIZATION_SIMPLE \ + template \ + void serialize(Archive& ar, const unsigned int) { \ + ar& boost::serialization::base_object(*this); \ + } \ + friend class boost::serialization::access; + #define SERVICE_CONSTRUCT(T) \ namespace boost::serialization { \ template \ diff --git a/src/core/hle/service/ssl_c.h b/src/core/hle/service/ssl_c.h index 3984f7ecc..30b87378a 100644 --- a/src/core/hle/service/ssl_c.h +++ b/src/core/hle/service/ssl_c.h @@ -23,6 +23,8 @@ private: // TODO: Implement a proper CSPRNG in the future when actual security is needed std::mt19937 rand_gen; + + SERVICE_SERIALIZATION_SIMPLE }; void InstallInterfaces(Core::System& system); diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 0c981b545..45e7da13d 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -20,6 +20,7 @@ namespace Service::Y2R { template void Y2R_U::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& completion_event; ar& conversion; ar& dithering_weight_params; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index cd3cf8aed..4c083d8c0 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -170,7 +170,9 @@ private: MemorySystem::Impl& impl; template - void serialize(Archive& ar, const unsigned int) {} + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } friend class boost::serialization::access; }; From 9525d81344151d2116665a42a7e06ba98cb8db5d Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Wed, 8 Jan 2020 23:19:49 +0000 Subject: [PATCH 064/129] More base-derived fixes --- TODO | 5 +++++ src/core/file_sys/archive_extsavedata.h | 1 + src/core/file_sys/archive_ncch.h | 4 +++- src/core/file_sys/archive_other_savedata.h | 2 ++ src/core/file_sys/archive_savedata.h | 1 + src/core/file_sys/archive_sdmc.h | 1 + src/core/file_sys/archive_sdmcwriteonly.h | 1 + src/core/file_sys/archive_selfncch.h | 6 ++++++ src/core/file_sys/archive_systemsavedata.h | 1 + src/core/file_sys/savedata_archive.cpp | 1 + src/core/file_sys/savedata_archive.h | 11 +++++++++++ src/core/hle/kernel/config_mem.h | 1 + src/core/hle/kernel/hle_ipc.cpp | 1 + src/core/hle/kernel/hle_ipc.h | 5 +++++ src/core/hle/kernel/server_session.h | 2 +- src/core/hle/kernel/shared_memory.h | 1 + src/core/hle/kernel/shared_page.h | 1 + src/core/hle/kernel/svc.cpp | 5 ++++- src/core/hle/kernel/thread.cpp | 1 + src/core/hle/kernel/thread.h | 5 +++++ src/core/hle/service/nwm/nwm_uds.cpp | 1 + src/core/hle/service/sm/srv.cpp | 15 +++++++++++++++ src/core/hle/service/sm/srv.h | 6 ++++++ 23 files changed, 75 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index def70ac2b..a8efb78eb 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,11 @@ ☐ Review base class serialization everywhere Make sure that all base/derived relationships are registered ☐ Serialize codeset with an apploader reference instead +☐ Additional stuff to serialize + ☐ Self-NCCH archive + ☐ File backends + ☐ Directory backends + ☐ File/directory 'services' ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ Page tables @done(20-01-05 16:33) diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index c9b84c984..f33dd1a89 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -60,6 +60,7 @@ private: ArchiveFactory_ExtSaveData() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& shared; ar& mount_point; } diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 0a3f95b5c..d17fbc3a2 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -116,7 +116,9 @@ public: private: template - void serialize(Archive& ar, const unsigned int) {} + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index a9deae95a..c5bf98a68 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -35,6 +35,7 @@ private: ArchiveFactory_OtherSaveDataPermitted() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sd_savedata_source; } friend class boost::serialization::access; @@ -62,6 +63,7 @@ private: ArchiveFactory_OtherSaveDataGeneral() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sd_savedata_source; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 3ebe94a63..6bb22f7a8 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -34,6 +34,7 @@ private: ArchiveFactory_SaveData() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sd_savedata_source; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 6051abef0..265dd7e93 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -81,6 +81,7 @@ private: ArchiveFactory_SDMC() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sdmc_directory; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_sdmcwriteonly.h b/src/core/file_sys/archive_sdmcwriteonly.h index 19982a9db..f4149961c 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.h +++ b/src/core/file_sys/archive_sdmcwriteonly.h @@ -67,6 +67,7 @@ private: ArchiveFactory_SDMCWriteOnly() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& sdmc_directory; } friend class boost::serialization::access; diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index de7fd75e0..571789b9f 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -47,6 +47,12 @@ private: /// Mapping of ProgramId -> NCCHData std::unordered_map ncch_data; // TODO: Remove this, or actually set the values here + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index cf18cab89..d4f204a66 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -37,6 +37,7 @@ private: ArchiveFactory_SystemSaveData() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& base_path; } friend class boost::serialization::access; diff --git a/src/core/file_sys/savedata_archive.cpp b/src/core/file_sys/savedata_archive.cpp index 1f22b50ab..090dc6fb0 100644 --- a/src/core/file_sys/savedata_archive.cpp +++ b/src/core/file_sys/savedata_archive.cpp @@ -357,4 +357,5 @@ u64 SaveDataArchive::GetFreeBytes() const { } // namespace FileSys +SERIALIZE_EXPORT_IMPL(FileSys::SaveDataArchive) SERIALIZE_EXPORT_IMPL(FileSys::SaveDataDelayGenerator) diff --git a/src/core/file_sys/savedata_archive.h b/src/core/file_sys/savedata_archive.h index 47f2f75e0..c9956e135 100644 --- a/src/core/file_sys/savedata_archive.h +++ b/src/core/file_sys/savedata_archive.h @@ -38,10 +38,21 @@ public: protected: std::string mount_point; + +private: + SaveDataArchive() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& mount_point; + } + friend class boost::serialization::access; }; class SaveDataDelayGenerator; } // namespace FileSys +BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataArchive) BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataDelayGenerator) diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index 0ec67fb5e..46595976e 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -70,6 +70,7 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); ar& boost::serialization::make_binary_object(&config_mem, sizeof(config_mem)); } }; diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index b1e2f7d8b..23f577490 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -50,6 +50,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& callback; ar& context; } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 01fec190b..046a31e2e 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -222,6 +222,11 @@ public: virtual ~WakeupCallback() = default; virtual void WakeUp(std::shared_ptr thread, HLERequestContext& context, ThreadWakeupReason reason) = 0; + + private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; /** diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 331ac8397..74dbef624 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -111,7 +111,7 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::base_object(*this); + ar& boost::serialization::base_object(*this); ar& name; ar& parent; ar& hle_handler; diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index aa2be05a6..cb2dee685 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -109,6 +109,7 @@ private: template void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); ar& linear_heap_phys_offset; ar& backing_blocks; ar& size; diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index 7b1f7ed16..c94cc079e 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -117,6 +117,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& boost::serialization::make_binary_object(&shared_page, sizeof(shared_page)); } friend class boost::serialization::access; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 7f7cc1272..371bbdfe3 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -434,6 +434,7 @@ private: SVC_SyncCallback() = default; template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& do_output; } friend class boost::serialization::access; @@ -466,7 +467,9 @@ private: SVC_IPCCallback() : system(Core::Global()) {} template - void serialize(Archive& ar, const unsigned int) {} + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 13a3017a5..f7379f50d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -32,6 +32,7 @@ namespace Kernel { template void Thread::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); ar&* context.get(); ar& thread_id; ar& status; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 9941c76db..c64e24071 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -66,6 +66,11 @@ public: virtual ~WakeupCallback() = default; virtual void WakeUp(ThreadWakeupReason reason, std::shared_ptr thread, std::shared_ptr object) = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; class ThreadManager { diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 2aa64f7fc..01bdd821e 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -1189,6 +1189,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& command_id; } friend class boost::serialization::access; diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 10179f416..91b26b497 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -3,6 +3,9 @@ // Refer to the license.txt file included. #include +#include +#include +#include #include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" @@ -21,8 +24,19 @@ #include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/srv.h" +SERVICE_CONSTRUCT_IMPL(Service::SM::SRV) +SERIALIZE_EXPORT_IMPL(Service::SM::SRV) + namespace Service::SM { +template +void SRV::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& notification_semaphore; + ar& get_service_handle_delayed_map; +} +SERIALIZE_IMPL(SRV) + constexpr int MAX_PENDING_NOTIFICATIONS = 16; /** @@ -107,6 +121,7 @@ private: template void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); ar& name; } friend class boost::serialization::access; diff --git a/src/core/hle/service/sm/srv.h b/src/core/hle/service/sm/srv.h index 7d17f87a5..753218dca 100644 --- a/src/core/hle/service/sm/srv.h +++ b/src/core/hle/service/sm/srv.h @@ -40,8 +40,14 @@ private: Core::System& system; std::shared_ptr notification_semaphore; std::unordered_map> get_service_handle_delayed_map; + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::SM +SERVICE_CONSTRUCT(Service::SM::SRV) +BOOST_CLASS_EXPORT_KEY(Service::SM::SRV) BOOST_CLASS_EXPORT_KEY(Service::SM::SRV::ThreadCallback) From ca971ff31f49456e01d5e7f9747327f2ce18133a Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 10 Jan 2020 23:47:39 +0000 Subject: [PATCH 065/129] Serialize file/directory services --- TODO | 4 ++-- src/core/file_sys/archive_backend.h | 30 ++++++++++++++++++++++++++- src/core/file_sys/directory_backend.h | 5 +++++ src/core/hle/service/fs/directory.cpp | 12 +++++++++++ src/core/hle/service/fs/directory.h | 9 ++++++++ src/core/hle/service/fs/file.cpp | 13 ++++++++++++ src/core/hle/service/fs/file.h | 11 ++++++++++ 7 files changed, 81 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index a8efb78eb..a76890185 100644 --- a/TODO +++ b/TODO @@ -4,14 +4,14 @@ ☐ Custom texture cache ☐ Review constructor/initialization code ☐ Review core timing events -☐ Review base class serialization everywhere +✔ Review base class serialization everywhere @done(20-01-10 23:47) Make sure that all base/derived relationships are registered ☐ Serialize codeset with an apploader reference instead ☐ Additional stuff to serialize ☐ Self-NCCH archive ☐ File backends ☐ Directory backends - ☐ File/directory 'services' + ✔ File/directory 'services' @done(20-01-10 23:46) ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ Page tables @done(20-01-05 16:33) diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 756613a30..6468c0630 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" @@ -63,7 +65,33 @@ private: LowPathType type; std::vector binary; std::string string; - std::u16string u16str; + std::u16string u16str{}; + + template + void serialize(Archive& ar, const unsigned int) { + ar& type; + switch (type) { + case LowPathType::Binary: + ar& binary; + break; + case LowPathType::Char: + ar& string; + break; + case LowPathType::Wchar: + static_assert(sizeof(wchar_t) == sizeof(char16_t)); + { + std::wstring wstring(reinterpret_cast(u16str.data())); + ar& wstring; + if (!Archive::is_saving::value) { + u16str = std::u16string(reinterpret_cast(wstring.data())); + } + } + break; + default: + break; + } + } + friend class boost::serialization::access; }; /// Parameters of the archive, as specified in the Create or Format call. diff --git a/src/core/file_sys/directory_backend.h b/src/core/file_sys/directory_backend.h index e9f124b02..4c9dbb4df 100644 --- a/src/core/file_sys/directory_backend.h +++ b/src/core/file_sys/directory_backend.h @@ -53,6 +53,11 @@ public: * @return true if the directory closed correctly */ virtual bool Close() const = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/hle/service/fs/directory.cpp b/src/core/hle/service/fs/directory.cpp index a72a9307a..16b12905c 100644 --- a/src/core/hle/service/fs/directory.cpp +++ b/src/core/hle/service/fs/directory.cpp @@ -2,13 +2,25 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/logging/log.h" #include "core/file_sys/directory_backend.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/fs/directory.h" +SERIALIZE_EXPORT_IMPL(Service::FS::Directory) + namespace Service::FS { +template +void Directory::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& path; + ar& backend; +} + +Directory::Directory() : ServiceFramework("", 1) {} + Directory::Directory(std::unique_ptr&& backend, const FileSys::Path& path) : ServiceFramework("", 1), path(path), backend(std::move(backend)) { diff --git a/src/core/hle/service/fs/directory.h b/src/core/hle/service/fs/directory.h index 890b26648..77956b166 100644 --- a/src/core/hle/service/fs/directory.h +++ b/src/core/hle/service/fs/directory.h @@ -25,6 +25,15 @@ public: protected: void Read(Kernel::HLERequestContext& ctx); void Close(Kernel::HLERequestContext& ctx); + +private: + Directory(); + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::FS + +BOOST_CLASS_EXPORT_KEY(Service::FS::Directory) diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index c8727314b..b878197d7 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" #include "core/file_sys/errors.h" @@ -13,8 +14,20 @@ #include "core/hle/kernel/server_session.h" #include "core/hle/service/fs/file.h" +SERIALIZE_EXPORT_IMPL(Service::FS::File) +SERIALIZE_EXPORT_IMPL(Service::FS::FileSessionSlot) + namespace Service::FS { +template +void File::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& path; + ar& backend; +} + +File::File() : ServiceFramework("", 1), kernel(Core::Global()) {} + File::File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path) : ServiceFramework("", 1), path(path), backend(std::move(backend)), kernel(kernel) { diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 18317212e..98d448755 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -6,6 +6,7 @@ #include #include "core/file_sys/archive_backend.h" +#include "core/global.h" #include "core/hle/service/service.h" namespace Core { @@ -30,6 +31,7 @@ private: ar& size; ar& subfile; } + friend class boost::serialization::access; }; // TODO: File is not a real service, but it can still utilize ServiceFramework::RegisterHandlers. @@ -71,6 +73,15 @@ private: void OpenSubFile(Kernel::HLERequestContext& ctx); Kernel::KernelSystem& kernel; + + File(); + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::FS + +BOOST_CLASS_EXPORT_KEY(Service::FS::FileSessionSlot) +BOOST_CLASS_EXPORT_KEY(Service::FS::File) From e4f05884c3be6249a8ab03e8b2c6bb8cb9caa7ac Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sat, 11 Jan 2020 16:33:48 +0000 Subject: [PATCH 066/129] Fixed serialization runtime exceptions --- TODO | 19 +++++++++---------- src/common/file_util.h | 1 + src/core/file_sys/archive_ncch.cpp | 1 + src/core/file_sys/archive_ncch.h | 14 +++++++++++--- src/core/file_sys/archive_selfncch.cpp | 21 +++++++++++++++++++++ src/core/file_sys/archive_selfncch.h | 18 ++++++++++++++++++ src/core/file_sys/ivfc_archive.cpp | 6 ++++++ src/core/file_sys/ivfc_archive.h | 22 ++++++++++++++++++++++ src/core/file_sys/romfs_reader.h | 21 ++++++++++++++++++--- src/core/hle/kernel/config_mem.cpp | 3 +++ src/core/hle/kernel/config_mem.h | 3 +++ src/core/hle/kernel/shared_page.cpp | 2 ++ src/core/hle/kernel/shared_page.h | 3 +++ src/core/hle/service/gsp/gsp_lcd.h | 3 +++ src/core/hle/service/ir/ir_rst.cpp | 1 - src/core/hle/service/ir/ir_u.h | 3 +++ src/core/hle/service/ir/ir_user.cpp | 11 +++++++++-- src/core/hle/service/ir/ir_user.h | 4 +++- src/core/hle/service/mic_u.cpp | 1 - src/core/hle/service/nwm/nwm_uds.cpp | 4 +++- src/core/hle/service/nwm/nwm_uds.h | 1 + src/core/hle/service/sm/srv.cpp | 1 - src/core/hle/service/y2r_u.cpp | 1 - 23 files changed, 140 insertions(+), 24 deletions(-) diff --git a/TODO b/TODO index a76890185..83603d1c6 100644 --- a/TODO +++ b/TODO @@ -3,14 +3,15 @@ ☐ Multiple slots etc. ☐ Custom texture cache ☐ Review constructor/initialization code -☐ Review core timing events +☐ Core timing events +☐ Serialize codeset with an apploader reference instead ✔ Review base class serialization everywhere @done(20-01-10 23:47) Make sure that all base/derived relationships are registered -☐ Serialize codeset with an apploader reference instead -☐ Additional stuff to serialize - ☐ Self-NCCH archive - ☐ File backends - ☐ Directory backends +✔ Additional stuff to serialize @done(20-01-11 16:32) + ✔ Self-NCCH archive @done(20-01-11 16:32) + ✔ File backends @done(20-01-11 16:32) + ✘ Directory backends @cancelled(20-01-11 16:32) + Not needed for now ✔ File/directory 'services' @done(20-01-10 23:46) ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) @@ -37,10 +38,8 @@ ✔ SDMC @done(20-01-02 23:34) ✔ Normal @done(20-01-02 23:34) ✔ Write-only @done(20-01-02 23:34) - ✘ IVFC @cancelled(20-01-03 13:22) - Seems IVFCArchive is never used.. which is good because it has a file reference! - ✘ File refs @cancelled(20-01-03 13:22) - Not needed as nothing serializes file buffers + ✔ IVFC @done(20-01-11 16:33) + ✔ File refs @done(20-01-11 16:33) ✘ Replace delay generator with virtual fns @cancelled(20-01-03 13:16) While they have no state, the extra refactoring here is unneeded ✘ MMIO @cancelled(20-01-01 01:06) diff --git a/src/common/file_util.h b/src/common/file_util.h index c09aa88d6..71f943ed3 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -334,6 +334,7 @@ private: } BOOST_SERIALIZATION_SPLIT_MEMBER() + friend class boost::serialization::access; }; } // namespace FileUtil diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index 636bb81ed..789547f0e 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp @@ -30,6 +30,7 @@ // FileSys namespace SERIALIZE_EXPORT_IMPL(FileSys::NCCHArchive) +SERIALIZE_EXPORT_IMPL(FileSys::NCCHFile) SERIALIZE_EXPORT_IMPL(FileSys::ArchiveFactory_NCCH) namespace FileSys { diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index d17fbc3a2..2d38f9a2e 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -95,9 +95,16 @@ public: void Flush() const override {} private: - NCCHFile() = default; // NOTE: If the public ctor has behaviour, need to replace this with - // *_construct_data - std::vector file_buffer; // TODO: Replace with file ref for serialization + std::vector file_buffer; + + NCCHFile() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& file_buffer; // TODO: See about a more efficient way to do this + } + friend class boost::serialization::access; }; /// File system interface to the NCCH archive @@ -125,4 +132,5 @@ private: } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::NCCHArchive) +BOOST_CLASS_EXPORT_KEY(FileSys::NCCHFile) BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_NCCH) diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index 214ad7c08..e866e9bc0 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp @@ -77,6 +77,15 @@ public: private: std::shared_ptr> data; + + ExeFSSectionFile() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& data; + } + friend class boost::serialization::access; }; // SelfNCCHArchive represents the running application itself. From this archive the application can @@ -234,6 +243,15 @@ private: } NCCHData ncch_data; + + SelfNCCHArchive() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& ncch_data; + } + friend class boost::serialization::access; }; void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) { @@ -300,3 +318,6 @@ ResultVal ArchiveFactory_SelfNCCH::GetFormatInfo(const Path&, } } // namespace FileSys + +SERIALIZE_EXPORT_IMPL(FileSys::ExeFSSectionFile) +SERIALIZE_EXPORT_IMPL(FileSys::SelfNCCHArchive) diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index 571789b9f..d7b1cf301 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -25,6 +27,17 @@ struct NCCHData { std::shared_ptr> banner; std::shared_ptr romfs_file; std::shared_ptr update_romfs_file; + +private: + template + void serialize(Archive& ar, const unsigned int) { + ar& icon; + ar& logo; + ar& banner; + ar& romfs_file; + ar& update_romfs_file; + } + friend class boost::serialization::access; }; /// File system interface to the SelfNCCH archive @@ -55,6 +68,11 @@ private: friend class boost::serialization::access; }; +class ExeFSSectionFile; +class SelfNCCHArchive; + } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::ArchiveFactory_SelfNCCH) +BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSSectionFile) +BOOST_CLASS_EXPORT_KEY(FileSys::SelfNCCHArchive) diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index ba16f8cd8..3dbef7049 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "common/archives.h" #include "common/common_types.h" #include "common/logging/log.h" #include "core/file_sys/ivfc_archive.h" @@ -12,6 +13,11 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::IVFCFile) +SERIALIZE_EXPORT_IMPL(FileSys::IVFCDelayGenerator) +SERIALIZE_EXPORT_IMPL(FileSys::RomFSDelayGenerator) +SERIALIZE_EXPORT_IMPL(FileSys::ExeFSDelayGenerator) + namespace FileSys { IVFCArchive::IVFCArchive(std::shared_ptr file, diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index 8168e04f4..3926f5229 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "common/file_util.h" #include "core/file_sys/archive_backend.h" @@ -38,6 +40,8 @@ class IVFCDelayGenerator : public DelayGenerator { static constexpr u64 IPCDelayNanoseconds(9438006); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; class RomFSDelayGenerator : public DelayGenerator { @@ -60,6 +64,8 @@ public: static constexpr u64 IPCDelayNanoseconds(9438006); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; class ExeFSDelayGenerator : public DelayGenerator { @@ -82,6 +88,8 @@ public: static constexpr u64 IPCDelayNanoseconds(9438006); return IPCDelayNanoseconds; } + + SERIALIZE_DELAY_GENERATOR }; /** @@ -128,6 +136,15 @@ public: private: std::shared_ptr romfs_file; + + IVFCFile() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& romfs_file; + } + friend class boost::serialization::access; }; class IVFCDirectory : public DirectoryBackend { @@ -162,3 +179,8 @@ private: }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFile) +BOOST_CLASS_EXPORT_KEY(FileSys::IVFCDelayGenerator) +BOOST_CLASS_EXPORT_KEY(FileSys::RomFSDelayGenerator) +BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSDelayGenerator) diff --git a/src/core/file_sys/romfs_reader.h b/src/core/file_sys/romfs_reader.h index 72a02cde3..ab1986fe6 100644 --- a/src/core/file_sys/romfs_reader.h +++ b/src/core/file_sys/romfs_reader.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "common/common_types.h" #include "common/file_util.h" @@ -29,9 +30,23 @@ private: FileUtil::IOFile file; std::array key; std::array ctr; - std::size_t file_offset; - std::size_t crypto_offset; - std::size_t data_size; + u64 file_offset; + u64 crypto_offset; + u64 data_size; + + RomFSReader() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& is_encrypted; + ar& file; + ar& key; + ar& ctr; + ar& file_offset; + ar& crypto_offset; + ar& data_size; + } + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/hle/kernel/config_mem.cpp b/src/core/hle/kernel/config_mem.cpp index 58bef4110..4b262b501 100644 --- a/src/core/hle/kernel/config_mem.cpp +++ b/src/core/hle/kernel/config_mem.cpp @@ -3,10 +3,13 @@ // Refer to the license.txt file included. #include +#include "common/archives.h" #include "core/hle/kernel/config_mem.h" //////////////////////////////////////////////////////////////////////////////////////////////////// +SERIALIZE_EXPORT_IMPL(ConfigMem::Handler) + namespace ConfigMem { Handler::Handler() { diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index 46595976e..74d934345 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -10,6 +10,7 @@ // putting this as a subset of HLE for now. #include +#include #include "common/common_funcs.h" #include "common/common_types.h" #include "common/memory_ref.h" @@ -76,3 +77,5 @@ private: }; } // namespace ConfigMem + +BOOST_CLASS_EXPORT_KEY(ConfigMem::Handler) diff --git a/src/core/hle/kernel/shared_page.cpp b/src/core/hle/kernel/shared_page.cpp index f7b02993f..5456a48e0 100644 --- a/src/core/hle/kernel/shared_page.cpp +++ b/src/core/hle/kernel/shared_page.cpp @@ -14,6 +14,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// +SERIALIZE_EXPORT_IMPL(SharedPage::Handler) + namespace boost::serialization { template diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index c94cc079e..b74470b4a 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -131,3 +132,5 @@ template void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int); } // namespace boost::serialization + +BOOST_CLASS_EXPORT_KEY(SharedPage::Handler) diff --git a/src/core/hle/service/gsp/gsp_lcd.h b/src/core/hle/service/gsp/gsp_lcd.h index 781d9dba8..31d17f540 100644 --- a/src/core/hle/service/gsp/gsp_lcd.h +++ b/src/core/hle/service/gsp/gsp_lcd.h @@ -12,6 +12,9 @@ class GSP_LCD final : public ServiceFramework { public: GSP_LCD(); ~GSP_LCD() = default; + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::GSP diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index dc9612e62..751460a04 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -29,7 +29,6 @@ void IR_RST::serialize(Archive& ar, const unsigned int) { // update_callback_id and input devices are set separately ReloadInputDevices(); } -SERIALIZE_IMPL(IR_RST) struct PadDataEntry { PadState current_state; diff --git a/src/core/hle/service/ir/ir_u.h b/src/core/hle/service/ir/ir_u.h index eaa54c657..ecaf1be28 100644 --- a/src/core/hle/service/ir/ir_u.h +++ b/src/core/hle/service/ir/ir_u.h @@ -12,6 +12,9 @@ namespace Service::IR { class IR_U final : public ServiceFramework { public: IR_U(); + +private: + SERVICE_SERIALIZATION_SIMPLE }; } // namespace Service::IR diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index 64a298103..4bf6e7499 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include "common/string_util.h" #include "common/swap.h" #include "core/core.h" @@ -13,6 +15,9 @@ #include "core/hle/service/ir/extra_hid.h" #include "core/hle/service/ir/ir_user.h" +SERIALIZE_EXPORT_IMPL(Service::IR::IR_USER) +SERVICE_CONSTRUCT_IMPL(Service::IR::IR_USER) + namespace Service::IR { template @@ -23,10 +28,9 @@ void IR_USER::serialize(Archive& ar, const unsigned int) { ar& receive_event; ar& shared_memory; ar& connected_device; - ar&* receive_buffer.get(); + ar& receive_buffer; ar&* extra_hid.get(); } -SERIALIZE_IMPL(IR_USER) // This is a header that will present in the ir:USER shared memory if it is initialized with // InitializeIrNopShared service function. Otherwise the shared memory doesn't have this header if @@ -204,6 +208,8 @@ private: u32 max_data_size; private: + BufferManager() = default; + template void serialize(Archive& ar, const unsigned int) { ar& info; @@ -449,6 +455,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) { using namespace Kernel; + connected_device = false; conn_status_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ConnectionStatusEvent"); send_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:SendEvent"); receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent"); diff --git a/src/core/hle/service/ir/ir_user.h b/src/core/hle/service/ir/ir_user.h index 75bbeb779..afb9be4f7 100644 --- a/src/core/hle/service/ir/ir_user.h +++ b/src/core/hle/service/ir/ir_user.h @@ -7,7 +7,6 @@ #include #include #include -#include #include "core/hle/service/service.h" namespace Kernel { @@ -177,3 +176,6 @@ private: }; } // namespace Service::IR + +BOOST_CLASS_EXPORT_KEY(Service::IR::IR_USER) +SERVICE_CONSTRUCT(Service::IR::IR_USER) diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 478bf110f..bd324ada2 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -28,7 +28,6 @@ void MIC_U::serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object(*this); ar&* impl.get(); } -SERIALIZE_IMPL(MIC_U) /// Microphone audio encodings. enum class Encoding : u8 { diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 01bdd821e..b2793285f 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -24,6 +24,9 @@ #include "core/hle/service/nwm/uds_data.h" #include "core/memory.h" +SERIALIZE_EXPORT_IMPL(Service::NWM::NWM_UDS) +SERVICE_CONSTRUCT_IMPL(Service::NWM::NWM_UDS) + namespace Service::NWM { template @@ -34,7 +37,6 @@ void NWM_UDS::serialize(Archive& ar, const unsigned int) { ar& received_beacons; // wifi_packet_received set in constructor } -SERIALIZE_IMPL(NWM_UDS) namespace ErrCodes { enum { diff --git a/src/core/hle/service/nwm/nwm_uds.h b/src/core/hle/service/nwm/nwm_uds.h index b2ab1d76a..7ae471a53 100644 --- a/src/core/hle/service/nwm/nwm_uds.h +++ b/src/core/hle/service/nwm/nwm_uds.h @@ -557,6 +557,7 @@ private: template void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::NWM diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 91b26b497..f9c62e9ad 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -35,7 +35,6 @@ void SRV::serialize(Archive& ar, const unsigned int) { ar& notification_semaphore; ar& get_service_handle_delayed_map; } -SERIALIZE_IMPL(SRV) constexpr int MAX_PENDING_NOTIFICATIONS = 16; diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 45e7da13d..89da8058c 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -28,7 +28,6 @@ void Y2R_U::serialize(Archive& ar, const unsigned int) { ar& transfer_end_interrupt_enabled; ar& spacial_dithering_enabled; } -SERIALIZE_IMPL(Y2R_U) static const CoefficientSet standard_coefficients[4] = { {{0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B}}, // ITU_Rec601 From 8abc5525be98854abecee14046d8e175a8b68b79 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 12 Jan 2020 00:24:44 +0000 Subject: [PATCH 067/129] Added Signals; more runtime fixes --- src/citra_qt/main.cpp | 11 ++---- src/common/thread_queue_list.h | 30 ++++++++++++---- src/core/arm/arm_interface.h | 2 +- src/core/core.cpp | 50 +++++++++++++++++++++----- src/core/core.h | 11 +++--- src/core/core_timing.cpp | 12 +++---- src/core/file_sys/ivfc_archive.cpp | 1 + src/core/file_sys/ivfc_archive.h | 12 +++++++ src/core/hle/kernel/kernel.cpp | 5 ++- src/core/hle/kernel/kernel.h | 7 ++-- src/core/hle/kernel/memory.cpp | 16 ++++----- src/core/hle/kernel/process.h | 2 +- src/core/hle/kernel/shared_memory.cpp | 4 +-- src/core/hle/kernel/thread.cpp | 4 +-- src/core/hle/service/gsp/gsp_gpu.cpp | 4 --- src/core/hle/service/gsp/gsp_gpu.h | 2 +- src/core/hle/service/ldr_ro/ldr_ro.cpp | 1 + 17 files changed, 118 insertions(+), 56 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 08e3cac02..7fe4936f5 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -1504,19 +1504,12 @@ void GMainWindow::OnCheats() { } void GMainWindow::OnSave() { - Core::System& system{Core::System::GetInstance()}; - auto fs = std::ofstream("save0.citrasave"); - emu_thread->SetRunning(false); - Core::System::GetInstance().Save(fs); - emu_thread->SetRunning(true); + Core::System::GetInstance().SendSignal(Core::System::Signal::Save); } void GMainWindow::OnLoad() { if (QFileInfo("save0.citrasave").exists()) { - auto fs = std::ifstream("save0.citrasave"); - emu_thread->SetRunning(false); - Core::System::GetInstance().Load(fs); - emu_thread->SetRunning(true); + Core::System::GetInstance().SendSignal(Core::System::Signal::Load); } } diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 093d86781..f5db59f05 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -160,15 +160,33 @@ private: // The priority level queues of thread ids. std::array queues; + s32 ToIndex(Queue* q) const { + if (q == nullptr) { + return -2; + } else if (q == UnlinkedTag()) { + return -1; + } else { + return static_cast(q - &queues[0]); + } + } + + Queue* ToPointer(s32 idx) { + if (idx == -1) { + return UnlinkedTag(); + } else if (idx < 0) { + return nullptr; + } else { + return &queues[idx]; + } + } + friend class boost::serialization::access; template void save(Archive& ar, const unsigned int file_version) const { - s32 idx = first == UnlinkedTag() ? -1 : static_cast(first - &queues[0]); + s32 idx = ToIndex(first); ar << idx; for (auto i = 0; i < NUM_QUEUES; i++) { - s32 idx1 = first == UnlinkedTag() - ? -1 - : static_cast(queues[i].next_nonempty - &queues[0]); + s32 idx1 = ToIndex(queues[i].next_nonempty); ar << idx1; ar << queues[i].data; } @@ -178,10 +196,10 @@ private: void load(Archive& ar, const unsigned int file_version) { s32 idx; ar >> idx; - first = idx < 0 ? UnlinkedTag() : &queues[idx]; + first = ToPointer(idx); for (auto i = 0; i < NUM_QUEUES; i++) { ar >> idx; - queues[i].next_nonempty = idx < 0 ? UnlinkedTag() : &queues[idx]; + queues[i].next_nonempty = ToPointer(idx); ar >> queues[i].data; } } diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index be30499d1..e416a5f4c 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -264,7 +264,7 @@ private: ar >> r; SetCP15Register(static_cast(i), r); } - // TODO: Clear caches etc? + ClearInstructionCache(); } BOOST_SERIALIZATION_SPLIT_MEMBER() diff --git a/src/core/core.cpp b/src/core/core.cpp index 20a8f32fe..fcd1268da 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include #include @@ -103,15 +104,38 @@ System::ResultStatus System::RunLoop(bool tight_loop) { HW::Update(); Reschedule(); - if (reset_requested.exchange(false)) { + auto signal = current_signal.exchange(Signal::None); + switch (signal) { + case Signal::Reset: Reset(); - } else if (shutdown_requested.exchange(false)) { + break; + case Signal::Shutdown: return ResultStatus::ShutdownRequested; + break; + case Signal::Load: { + auto stream = std::ifstream("save0.citrasave", std::fstream::binary); + System::Load(stream); + } break; + case Signal::Save: { + auto stream = std::ofstream("save0.citrasave", std::fstream::binary); + System::Save(stream); + } break; + default: + break; } return status; } +bool System::SendSignal(System::Signal signal) { + auto prev = System::Signal::None; + if (!current_signal.compare_exchange_strong(prev, signal)) { + LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, prev); + return false; + } + return true; +} + System::ResultStatus System::SingleStep() { return RunLoop(false); } @@ -216,8 +240,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique( - *memory, *timing, [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique(*memory, *timing, + [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -409,6 +433,7 @@ void System::Reset() { template void System::serialize(Archive& ar, const unsigned int file_version) { + Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF); ar&* cpu_core.get(); ar&* service_manager.get(); ar& GPU::g_regs; @@ -436,11 +461,20 @@ void System::Save(std::ostream& stream) const { } void System::Load(std::istream& stream) { - { - iarchive ia{stream}; - ia&* this; + try { + + { + iarchive ia{stream}; + ia&* this; + } + VideoCore::Load(stream); + + // Flush state through: + Kernel().SetCurrentProcess(Kernel().GetCurrentProcess()); + + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error loading: {}", e.what()); } - VideoCore::Load(stream); } } // namespace Core diff --git a/src/core/core.h b/src/core/core.h index 75e0e1a54..a3b2f5cdd 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -116,14 +116,18 @@ public: /// Shutdown and then load again void Reset(); + enum class Signal : u32 { None, Shutdown, Reset, Save, Load }; + + bool SendSignal(Signal signal); + /// Request reset of the system void RequestReset() { - reset_requested = true; + SendSignal(Signal::Reset); } /// Request shutdown of the system void RequestShutdown() { - shutdown_requested = true; + SendSignal(Signal::Shutdown); } /** @@ -341,8 +345,7 @@ private: Frontend::EmuWindow* m_emu_window; std::string m_filepath; - std::atomic reset_requested; - std::atomic shutdown_requested; + std::atomic current_signal; friend class boost::serialization::access; template diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index df355ab27..976a6f3ba 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -23,14 +23,10 @@ bool Timing::Event::operator<(const Event& right) const { TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback callback) { // check for existing type with same name. // we want event type names to remain unique so that we can use them for serialization. - ASSERT_MSG(event_types.find(name) == event_types.end(), - "CoreTiming Event \"{}\" is already registered. Events should only be registered " - "during Init to avoid breaking save states.", - name); - - auto info = event_types.emplace(name, TimingEventType{callback, nullptr}); + auto info = event_types.emplace(name, TimingEventType{}); TimingEventType* event_type = &info.first->second; event_type->name = &info.first->first; + event_type->callback = callback; return event_type; } @@ -129,6 +125,10 @@ void Timing::Advance() { Event evt = std::move(event_queue.front()); std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); event_queue.pop_back(); + if (event_types.find(*evt.type->name) == event_types.end()) { + LOG_ERROR(Core, "Unknown queued event"); + continue; + } evt.type->callback(evt.userdata, global_timer - evt.time); } diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index 3dbef7049..10d085164 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -14,6 +14,7 @@ // FileSys namespace SERIALIZE_EXPORT_IMPL(FileSys::IVFCFile) +SERIALIZE_EXPORT_IMPL(FileSys::IVFCFileInMemory) SERIALIZE_EXPORT_IMPL(FileSys::IVFCDelayGenerator) SERIALIZE_EXPORT_IMPL(FileSys::RomFSDelayGenerator) SERIALIZE_EXPORT_IMPL(FileSys::ExeFSDelayGenerator) diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index 3926f5229..145fabb98 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -176,11 +176,23 @@ private: std::vector romfs_file; u64 data_offset; u64 data_size; + + IVFCFileInMemory() = default; + + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& romfs_file; + ar& data_offset; + ar& data_size; + } + friend class boost::serialization::access; }; } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFile) +BOOST_CLASS_EXPORT_KEY(FileSys::IVFCFileInMemory) BOOST_CLASS_EXPORT_KEY(FileSys::IVFCDelayGenerator) BOOST_CLASS_EXPORT_KEY(FileSys::RomFSDelayGenerator) BOOST_CLASS_EXPORT_KEY(FileSys::ExeFSDelayGenerator) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 968e905ac..3c3dfc6c6 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -23,6 +23,9 @@ KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, std::function prepare_reschedule_callback, u32 system_mode) : memory(memory), timing(timing), prepare_reschedule_callback(std::move(prepare_reschedule_callback)) { + for (auto i = 0; i < memory_regions.size(); i++) { + memory_regions[i] = std::make_shared(); + } MemoryInit(system_mode); resource_limits = std::make_unique(*this); @@ -107,7 +110,7 @@ template void KernelSystem::serialize(Archive& ar, const unsigned int file_version) { ar& memory_regions; ar& named_ports; - ar&* current_cpu.get(); + // current_cpu set externally // NB: subsystem references and prepare_reschedule_callback are constant ar&* resource_limits.get(); ar& next_object_id; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index e7b7314d6..41ef5272b 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -134,7 +134,8 @@ public: */ ResultVal> CreateThread(std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, - VAddr stack_top, std::shared_ptr owner_process); + VAddr stack_top, + std::shared_ptr owner_process); /** * Creates a semaphore. @@ -232,11 +233,11 @@ public: IPCDebugger::Recorder& GetIPCRecorder(); const IPCDebugger::Recorder& GetIPCRecorder() const; - MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); + std::shared_ptr GetMemoryRegion(MemoryRegion region); void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping); - std::array memory_regions; + std::array, 3> memory_regions{}; /// Adds a port to the named port table void AddNamedPort(std::string name, std::shared_ptr port); diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp index 04d09fa46..f8db3c31e 100644 --- a/src/core/hle/kernel/memory.cpp +++ b/src/core/hle/kernel/memory.cpp @@ -49,9 +49,9 @@ void KernelSystem::MemoryInit(u32 mem_type) { // the sizes specified in the memory_region_sizes table. VAddr base = 0; for (int i = 0; i < 3; ++i) { - memory_regions[i].Reset(base, memory_region_sizes[mem_type][i]); + memory_regions[i]->Reset(base, memory_region_sizes[mem_type][i]); - base += memory_regions[i].size; + base += memory_regions[i]->size; } // We must've allocated the entire FCRAM by the end @@ -63,20 +63,20 @@ void KernelSystem::MemoryInit(u32 mem_type) { // app_mem_malloc does not always match the configured size for memory_region[0]: in case the // n3DS type override is in effect it reports the size the game expects, not the real one. config_mem.app_mem_alloc = memory_region_sizes[mem_type][0]; - config_mem.sys_mem_alloc = memory_regions[1].size; - config_mem.base_mem_alloc = memory_regions[2].size; + config_mem.sys_mem_alloc = memory_regions[1]->size; + config_mem.base_mem_alloc = memory_regions[2]->size; shared_page_handler = std::make_shared(timing); } -MemoryRegionInfo* KernelSystem::GetMemoryRegion(MemoryRegion region) { +std::shared_ptr KernelSystem::GetMemoryRegion(MemoryRegion region) { switch (region) { case MemoryRegion::APPLICATION: - return &memory_regions[0]; + return memory_regions[0]; case MemoryRegion::SYSTEM: - return &memory_regions[1]; + return memory_regions[1]; case MemoryRegion::BASE: - return &memory_regions[2]; + return memory_regions[2]; default: UNREACHABLE(); } diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 576cf7e15..6eb79d227 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -200,7 +200,7 @@ public: u32 memory_used = 0; - MemoryRegionInfo* memory_region = nullptr; + std::shared_ptr memory_region = nullptr; /// The Thread Local Storage area is allocated as processes create threads, /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 23f67f733..47c966fec 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -42,7 +42,7 @@ ResultVal> KernelSystem::CreateSharedMemory( if (address == 0) { // We need to allocate a block from the Linear Heap ourselves. // We'll manually allocate some memory from the linear heap in the specified region. - MemoryRegionInfo* memory_region = GetMemoryRegion(region); + auto memory_region = GetMemoryRegion(region); auto offset = memory_region->LinearAllocate(size); ASSERT_MSG(offset, "Not enough space in region to allocate shared memory!"); @@ -79,7 +79,7 @@ std::shared_ptr KernelSystem::CreateSharedMemoryForApplet( auto shared_memory{std::make_shared(*this)}; // Allocate memory in heap - MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); + auto memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); auto backing_blocks = memory_region->HeapAllocate(size); ASSERT_MSG(!backing_blocks.empty(), "Not enough space in region to allocate shared memory!"); shared_memory->holding_memory = backing_blocks; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f7379f50d..5382f9ec8 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -32,7 +32,7 @@ namespace Kernel { template void Thread::serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::base_object(*this); + ar& boost::serialization::base_object(*this); ar&* context.get(); ar& thread_id; ar& status; @@ -363,7 +363,7 @@ ResultVal> KernelSystem::CreateThread( if (needs_allocation) { // There are no already-allocated pages with free slots, lets allocate a new one. // TLS pages are allocated from the BASE region in the linear heap. - MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE); + auto memory_region = GetMemoryRegion(MemoryRegion::BASE); // Allocate some memory from the end of the linear heap for this region. auto offset = memory_region->LinearAllocate(Memory::PAGE_SIZE); diff --git a/src/core/hle/service/gsp/gsp_gpu.cpp b/src/core/hle/service/gsp/gsp_gpu.cpp index 78d84499b..5a41f5ca0 100644 --- a/src/core/hle/service/gsp/gsp_gpu.cpp +++ b/src/core/hle/service/gsp/gsp_gpu.cpp @@ -824,10 +824,6 @@ std::unique_ptr GSP_GPU::MakeSes return std::make_unique(this); } -SessionData::SessionData() { - UNREACHABLE(); -} - SessionData::SessionData(GSP_GPU* gsp) : gsp(gsp) { // Assign a new thread id to this session when it connects. Note: In the real GSP service this // is done through a real thread (svcCreateThread) but we have to simulate it since our HLE diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index a97aee278..82ecf2480 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -187,7 +187,7 @@ class GSP_GPU; class SessionData : public Kernel::SessionRequestHandler::SessionDataBase { public: - SessionData(); + SessionData() = default; SessionData(GSP_GPU* gsp); ~SessionData(); diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp index 0a61f4c23..8ac6f1068 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp @@ -15,6 +15,7 @@ SERVICE_CONSTRUCT_IMPL(Service::LDR::RO) SERIALIZE_EXPORT_IMPL(Service::LDR::RO) +SERIALIZE_EXPORT_IMPL(Service::LDR::ClientSlot) namespace Service::LDR { From c24ea0f0eea2d263cf3cd9bb616332fed3085c5f Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 12 Jan 2020 20:01:29 +0000 Subject: [PATCH 068/129] Serialize core timing --- TODO | 3 ++- src/core/core.cpp | 1 + src/core/core_timing.cpp | 10 +++++++-- src/core/core_timing.h | 42 ++++++++++++++++++++++++++++++++++++ src/core/hle/kernel/thread.h | 1 + 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 83603d1c6..9cc333d46 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,10 @@ ☐ Save/load UI ✔ Basic version @done(20-01-03 15:27) ☐ Multiple slots etc. +☐ Add 'force flush all' to Rasterizer interface + impls ☐ Custom texture cache ☐ Review constructor/initialization code -☐ Core timing events +✔ Core timing events @done(20-01-12 15:14) ☐ Serialize codeset with an apploader reference instead ✔ Review base class serialization everywhere @done(20-01-10 23:47) Make sure that all base/derived relationships are registered diff --git a/src/core/core.cpp b/src/core/core.cpp index fcd1268da..fa60035dc 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -434,6 +434,7 @@ void System::Reset() { template void System::serialize(Archive& ar, const unsigned int file_version) { Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF); + ar&* timing.get(); ar&* cpu_core.get(); ar&* service_manager.get(); ar& GPU::g_regs; diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 976a6f3ba..4b2729a76 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -11,6 +11,8 @@ namespace Core { +Timing* Timing::deserializing = nullptr; + // Sort by time, unless the times are the same, in which case sort by the order added to the queue bool Timing::Event::operator>(const Event& right) const { return std::tie(time, fifo_order) > std::tie(right.time, right.fifo_order); @@ -26,7 +28,9 @@ TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback ca auto info = event_types.emplace(name, TimingEventType{}); TimingEventType* event_type = &info.first->second; event_type->name = &info.first->first; - event_type->callback = callback; + if (callback != nullptr) { + event_type->callback = callback; + } return event_type; } @@ -129,7 +133,9 @@ void Timing::Advance() { LOG_ERROR(Core, "Unknown queued event"); continue; } - evt.type->callback(evt.userdata, global_timer - evt.time); + if (evt.type->callback != nullptr) { + evt.type->callback(evt.userdata, global_timer - evt.time); + } } is_global_timer_sane = false; diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 229fc37f4..1e6a3b021 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "common/common_types.h" #include "common/logging/log.h" #include "common/threadsafe_queue.h" @@ -190,6 +192,8 @@ public: s64 GetDowncount() const; private: + static Timing* deserializing; + struct Event { s64 time; u64 fifo_order; @@ -198,6 +202,29 @@ private: bool operator>(const Event& right) const; bool operator<(const Event& right) const; + + private: + template + void save(Archive& ar, const unsigned int) const { + ar& time; + ar& fifo_order; + ar& userdata; + std::string name = *(type->name); + ar << name; + } + + template + void load(Archive& ar, const unsigned int) { + ar& time; + ar& fifo_order; + ar& userdata; + std::string name; + ar >> name; + type = Timing::deserializing->RegisterEvent(name, nullptr); + } + friend class boost::serialization::access; + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; static constexpr int MAX_SLICE_LENGTH = 20000; @@ -229,6 +256,21 @@ private: // executing the first cycle of each slice to prepare the slice length and downcount for // that slice. bool is_global_timer_sane = true; + + template + void serialize(Archive& ar, const unsigned int) { + // event_types set during initialization of other things + deserializing = this; + MoveEvents(); + ar& global_timer; + ar& slice_length; + ar& downcount; + ar& event_queue; + ar& event_fifo_id; + ar& idled_cycles; + deserializing = nullptr; + } + friend class boost::serialization::access; }; } // namespace Core diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index c64e24071..0286e210d 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -172,6 +172,7 @@ private: ar& ready_queue; ar& wakeup_callback_table; ar& thread_list; + SwitchContext(current_thread.get()); } }; From 2217b3558d98dfcc8a40d901a643c2fb72a9c476 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Thu, 16 Jan 2020 00:53:20 +0000 Subject: [PATCH 069/129] Fixed file services serialization --- src/common/file_util.cpp | 13 +++++-------- src/common/file_util.h | 3 ++- src/core/core.cpp | 4 ++++ src/core/hle/service/fs/directory.cpp | 9 ++++++--- src/core/hle/service/fs/file.cpp | 10 ++++++++-- src/core/hle/service/fs/file.h | 1 + 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index ca86f7bfc..c5da82973 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -881,8 +881,9 @@ std::string SanitizePath(std::string_view path_, DirectorySeparator directory_se IOFile::IOFile() {} -IOFile::IOFile(const std::string& filename, const char openmode[], int flags) { - Open(filename, openmode, flags); +IOFile::IOFile(const std::string& filename, const char openmode[], int flags) + : filename(filename), openmode(openmode), flags(flags) { + Open(); } IOFile::~IOFile() { @@ -906,13 +907,9 @@ void IOFile::Swap(IOFile& other) { std::swap(flags, other.flags); } -bool IOFile::Open(const std::string& filename, const char openmode[], int flags) { +bool IOFile::Open() { Close(); - this->filename = filename; - this->openmode = openmode; - this->flags = flags; - #ifdef _WIN32 if (flags != 0) { m_file = _wfsopen(Common::UTF8ToUTF16W(filename).c_str(), @@ -922,7 +919,7 @@ bool IOFile::Open(const std::string& filename, const char openmode[], int flags) Common::UTF8ToUTF16W(openmode).c_str()); } #else - m_file = fopen(filename.c_str(), openmode); + m_file = fopen(filename.c_str(), openmode.c_str()); #endif m_good = IsOpen(); diff --git a/src/common/file_util.h b/src/common/file_util.h index 71f943ed3..0368d3665 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -306,7 +306,7 @@ public: } private: - bool Open(const std::string& filename, const char openmode[], int flags = 0); + bool Open(); std::FILE* m_file = nullptr; bool m_good = true; @@ -330,6 +330,7 @@ private: ar >> flags; u64 pos; ar >> pos; + Open(); Seek(pos, SEEK_SET); } diff --git a/src/core/core.cpp b/src/core/core.cpp index fa60035dc..985d37291 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -113,12 +113,16 @@ System::ResultStatus System::RunLoop(bool tight_loop) { return ResultStatus::ShutdownRequested; break; case Signal::Load: { + LOG_INFO(Core, "Begin load"); auto stream = std::ifstream("save0.citrasave", std::fstream::binary); System::Load(stream); + LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { + LOG_INFO(Core, "Begin save"); auto stream = std::ofstream("save0.citrasave", std::fstream::binary); System::Save(stream); + LOG_INFO(Core, "Save completed"); } break; default: break; diff --git a/src/core/hle/service/fs/directory.cpp b/src/core/hle/service/fs/directory.cpp index 16b12905c..c7fb085ea 100644 --- a/src/core/hle/service/fs/directory.cpp +++ b/src/core/hle/service/fs/directory.cpp @@ -19,11 +19,14 @@ void Directory::serialize(Archive& ar, const unsigned int) { ar& backend; } -Directory::Directory() : ServiceFramework("", 1) {} - Directory::Directory(std::unique_ptr&& backend, const FileSys::Path& path) - : ServiceFramework("", 1), path(path), backend(std::move(backend)) { + : Directory() { + this->backend = std::move(backend); + this->path = path; +} + +Directory::Directory() : ServiceFramework("", 1), path(""), backend(nullptr) { static const FunctionInfo functions[] = { // clang-format off {0x08010042, &Directory::Read, "Read"}, diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index b878197d7..e86d93723 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -26,11 +26,17 @@ void File::serialize(Archive& ar, const unsigned int) { ar& backend; } -File::File() : ServiceFramework("", 1), kernel(Core::Global()) {} +File::File() : File(Core::Global()) {} File::File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path) - : ServiceFramework("", 1), path(path), backend(std::move(backend)), kernel(kernel) { + : File(kernel) { + this->backend = std::move(backend); + this->path = path; +} + +File::File(Kernel::KernelSystem& kernel) + : ServiceFramework("", 1), path(""), backend(nullptr), kernel(kernel) { static const FunctionInfo functions[] = { {0x08010100, &File::OpenSubFile, "OpenSubFile"}, {0x080200C2, &File::Read, "Read"}, diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 98d448755..6aa301a7b 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -74,6 +74,7 @@ private: Kernel::KernelSystem& kernel; + File(Kernel::KernelSystem& kernel); File(); template From b2370ea35317040ca1159e46ec5c2653898a36ad Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 17 Jan 2020 01:01:18 +0000 Subject: [PATCH 070/129] Fixed setting the right DSP service on deserialization --- src/core/core.cpp | 5 ++++- src/core/core_timing.cpp | 5 +++-- src/video_core/geometry_pipeline.h | 8 ++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 985d37291..d199b16e2 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -448,7 +448,10 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* kernel.get(); // This needs to be set from somewhere - might as well be here! - Service::GSP::SetGlobalModule(*this); + if (Archive::is_loading::value) { + Service::GSP::SetGlobalModule(*this); + DSP().SetServiceToInterrupt(ServiceManager().GetService("dsp::DSP")); + } } void System::Save(std::ostream& stream) const { diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 4b2729a76..116ba3a40 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -130,8 +130,9 @@ void Timing::Advance() { std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); event_queue.pop_back(); if (event_types.find(*evt.type->name) == event_types.end()) { - LOG_ERROR(Core, "Unknown queued event"); - continue; + LOG_ERROR(Core, "Unknown queued event {}", *evt.type->name); + } else if (evt.type->callback == nullptr) { + LOG_ERROR(Core, "Event '{}' has no callback", *evt.type->name); } if (evt.type->callback != nullptr) { evt.type->callback(evt.userdata, global_timer - evt.time); diff --git a/src/video_core/geometry_pipeline.h b/src/video_core/geometry_pipeline.h index 1ca2d00c4..1a903b1e0 100644 --- a/src/video_core/geometry_pipeline.h +++ b/src/video_core/geometry_pipeline.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "video_core/shader/shader.h" namespace Pica { @@ -12,6 +13,9 @@ namespace Pica { struct State; class GeometryPipelineBackend; +class GeometryPipeline_Point; +class GeometryPipeline_VariablePrimitive; +class GeometryPipeline_FixedPrimitive; /// A pipeline receiving from vertex shader and sending to geometry shader and primitive assembler class GeometryPipeline { @@ -52,3 +56,7 @@ private: friend class boost::serialization::access; }; } // namespace Pica + +BOOST_CLASS_EXPORT_KEY(Pica::GeometryPipeline_Point) +BOOST_CLASS_EXPORT_KEY(Pica::GeometryPipeline_VariablePrimitive) +BOOST_CLASS_EXPORT_KEY(Pica::GeometryPipeline_FixedPrimitive) From 35c3ca995cd68f6c827599146c42c7aebfac1567 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 17 Jan 2020 01:34:03 +0000 Subject: [PATCH 071/129] Fixed a bug (??) in arm_dynarmic where PageTableChanged could reset the CPU context --- src/core/arm/dynarmic/arm_dynarmic.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index eb3295956..b6494d40e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -283,15 +283,21 @@ void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, std::size_t length) { void ARM_Dynarmic::PageTableChanged() { current_page_table = memory.GetCurrentPageTable(); + Dynarmic::A32::Context ctx{}; + if (jit) { + jit->SaveContext(ctx); + } auto iter = jits.find(current_page_table); if (iter != jits.end()) { jit = iter->second.get(); + jit->LoadContext(ctx); return; } auto new_jit = MakeJit(); jit = new_jit.get(); + jit->LoadContext(ctx); jits.emplace(current_page_table, std::move(new_jit)); } From 0effb229cd754640def04b7d9f9dd3187137aa43 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 17 Jan 2020 07:58:40 +0000 Subject: [PATCH 072/129] Fix geometry pipeline; attempt to fix motion controls --- src/core/hle/service/hid/hid.cpp | 4 +++- src/video_core/geometry_pipeline.cpp | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index f20cebca7..012a37e6b 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -40,7 +40,9 @@ void Module::serialize(Archive& ar, const unsigned int) { ar& next_gyroscope_index; ar& enable_accelerometer_count; ar& enable_gyroscope_count; - ReloadInputDevices(); + if (Archive::is_loading::value) { + LoadInputDevices(); + } // Pad state not needed as it's always updated // Update events are set in the constructor // Devices are set from the implementation (and are stateless afaik) diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp index 159f1df0b..7e002d55d 100644 --- a/src/video_core/geometry_pipeline.cpp +++ b/src/video_core/geometry_pipeline.cpp @@ -49,7 +49,7 @@ private: // TODO: what happens when the input size is not divisible by the output size? class GeometryPipeline_Point : public GeometryPipelineBackend { public: - GeometryPipeline_Point() : regs(g_state.regs), unit(g_state.gs_unit) { + GeometryPipeline_Point(const Regs& regs, Shader::GSUnitState& unit) : regs(regs), unit(unit) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 0); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -89,6 +89,8 @@ private: Common::Vec4* buffer_end; unsigned int vs_output_num; + GeometryPipeline_Point() : regs(g_state.regs), unit(g_state.gs_unit) {} + template static void serialize_common(Class* self, Archive& ar, const unsigned int version) { ar& boost::serialization::base_object(*self); @@ -125,7 +127,8 @@ private: // value in the batch. This mode is usually used for subdivision. class GeometryPipeline_VariablePrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_VariablePrimitive() : regs(g_state.regs), setup(g_state.gs) { + GeometryPipeline_VariablePrimitive(const Regs& regs, Shader::ShaderSetup& setup) + : regs(regs), setup(setup) { ASSERT(regs.pipeline.variable_primitive == 1); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -183,6 +186,8 @@ private: Common::Vec4* buffer_cur; unsigned int vs_output_num; + GeometryPipeline_VariablePrimitive() : regs(g_state.regs), setup(g_state.gs) {} + template static void serialize_common(Class* self, Archive& ar, const unsigned int version) { ar& boost::serialization::base_object(*self); @@ -217,7 +222,8 @@ private: // particle system. class GeometryPipeline_FixedPrimitive : public GeometryPipelineBackend { public: - GeometryPipeline_FixedPrimitive() : regs(g_state.regs), setup(g_state.gs) { + GeometryPipeline_FixedPrimitive(const Regs& regs, Shader::ShaderSetup& setup) + : regs(regs), setup(setup) { ASSERT(regs.pipeline.variable_primitive == 0); ASSERT(regs.gs.input_to_uniform == 1); vs_output_num = regs.pipeline.vs_outmap_total_minus_1_a + 1; @@ -256,6 +262,8 @@ private: Common::Vec4* buffer_end; unsigned int vs_output_num; + GeometryPipeline_FixedPrimitive() : regs(g_state.regs), setup(g_state.gs) {} + template static void serialize_common(Class* self, Archive& ar, const unsigned int version) { ar& boost::serialization::base_object(*self); @@ -329,13 +337,13 @@ void GeometryPipeline::Reconfigure() { switch (state.regs.pipeline.gs_config.mode) { case PipelineRegs::GSMode::Point: - backend = std::make_unique(); + backend = std::make_unique(state.regs, state.gs_unit); break; case PipelineRegs::GSMode::VariablePrimitive: - backend = std::make_unique(); + backend = std::make_unique(state.regs, state.gs); break; case PipelineRegs::GSMode::FixedPrimitive: - backend = std::make_unique(); + backend = std::make_unique(state.regs, state.gs); break; default: UNREACHABLE(); From 3e34ad6890a08bc2572da52a6b4fc2f967b4681d Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 16 Jan 2020 23:17:07 -0700 Subject: [PATCH 073/129] Hack: Workaround crash when loading state and gyro is used --- src/core/hle/service/hid/hid.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 012a37e6b..6898c1024 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -207,6 +207,10 @@ void Module::UpdateAccelerometerCallback(u64 userdata, s64 cycles_late) { next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); Common::Vec3 accel; + if (!motion_device) { + is_device_reload_pending.exchange(true); + return; + } std::tie(accel, std::ignore) = motion_device->GetStatus(); accel *= accelerometer_coef; // TODO(wwylele): do a time stretch like the one in UpdateGyroscopeCallback @@ -254,6 +258,10 @@ void Module::UpdateGyroscopeCallback(u64 userdata, s64 cycles_late) { GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; Common::Vec3 gyro; + if (!motion_device) { + is_device_reload_pending.exchange(true); + return; + } std::tie(std::ignore, gyro) = motion_device->GetStatus(); double stretch = system.perf_stats->GetLastFrameTimeScale(); gyro *= gyroscope_coef * static_cast(stretch); From 55c75b5e3e3be6e4baa34aaab4520d3c49d9645c Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 16 Jan 2020 23:17:55 -0700 Subject: [PATCH 074/129] Add ClearAll to rasterizer cache for fully wiping the cache on save/load --- src/core/core.cpp | 4 ++- src/core/memory.cpp | 10 +++++++ src/core/memory.h | 6 ++++ src/video_core/rasterizer_interface.h | 3 ++ .../renderer_opengl/gl_rasterizer.cpp | 4 +++ .../renderer_opengl/gl_rasterizer.h | 1 + .../renderer_opengl/gl_rasterizer_cache.cpp | 29 +++++++++++++++++-- .../renderer_opengl/gl_rasterizer_cache.h | 3 ++ src/video_core/swrasterizer/swrasterizer.h | 1 + 9 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index d199b16e2..aeab0d2b5 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -437,7 +437,9 @@ void System::Reset() { template void System::serialize(Archive& ar, const unsigned int file_version) { - Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF); + // flush on save, don't flush on load + bool should_flush = !Archive::is_loading::value; + Memory::RasterizerClearAll(should_flush); ar&* timing.get(); ar&* cpu_core.get(); ar&* service_manager.get(); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 4c083d8c0..a0fa2a738 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -556,6 +556,16 @@ void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) { VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size); } +void RasterizerClearAll(bool flush) { + // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be + // null here + if (VideoCore::g_renderer == nullptr) { + return; + } + + VideoCore::g_renderer->Rasterizer()->ClearAll(flush); +} + void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be // null here diff --git a/src/core/memory.h b/src/core/memory.h index 348fee3c9..eb5b6d69c 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -283,6 +283,12 @@ enum class FlushMode { FlushAndInvalidate, }; +/** + * Flushes and invalidates all memory in the rasterizer cache and removes any leftover state + * If flush is true, the rasterizer should flush any cached resources to RAM before clearing + */ +void RasterizerClearAll(bool flush); + /** * Flushes and invalidates any externally cached rasterizer resources touching the given virtual * address region. diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 468d84084..a2510292e 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -55,6 +55,9 @@ public: /// and invalidated virtual void FlushAndInvalidateRegion(PAddr addr, u32 size) = 0; + /// Removes as much state as possible from the rasterizer in preparation for a save/load state + virtual void ClearAll(bool flush) = 0; + /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0 virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { return false; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 862dcac00..34bac4f87 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1367,6 +1367,10 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(PAddr addr, u32 size) { res_cache.InvalidateRegion(addr, size, nullptr); } +void RasterizerOpenGL::ClearAll(bool flush) { + res_cache.ClearAll(flush); +} + bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { MICROPROFILE_SCOPE(OpenGL_Blits); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b3356a69b..92cca2e4e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -53,6 +53,7 @@ public: void FlushRegion(PAddr addr, u32 size) override; void InvalidateRegion(PAddr addr, u32 size) override; void FlushAndInvalidateRegion(PAddr addr, u32 size) override; + void ClearAll(bool flush) override; bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override; bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override; bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index af2a918a6..4dcc64832 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1276,9 +1276,7 @@ void main() { } RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { - FlushAll(); - while (!surface_cache.empty()) - UnregisterSurface(*surface_cache.begin()->second.begin()); + ClearAll(false); } MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64)); @@ -1927,6 +1925,31 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, PAddr addr, } } +void RasterizerCacheOpenGL::ClearAll(bool flush) { + const SurfaceInterval flush_interval(0x0, 0xFFFFFFFF); + // Force flush all surfaces from the cache + if (flush) { + FlushRegion(0x0, 0xFFFFFFFF); + } + // Unmark all of the marked pages + for (auto& pair : RangeFromInterval(cached_pages, flush_interval)) { + const auto interval = pair.first & flush_interval; + const int count = pair.second; + + const PAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS; + const PAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS; + const u32 interval_size = interval_end_addr - interval_start_addr; + + VideoCore::g_memory->RasterizerMarkRegionCached(interval_start_addr, interval_size, false); + } + + // Remove the whole cache without really looking at it. + cached_pages -= flush_interval; + dirty_regions -= flush_interval; + surface_cache -= flush_interval; + remove_surfaces.clear(); +} + void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, Surface flush_surface) { if (size == 0) return; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index cd601ef29..69322f713 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -482,6 +482,9 @@ public: /// Flush all cached resources tracked by this cache manager void FlushAll(); + /// Clear all cached resources tracked by this cache manager + void ClearAll(bool flush); + private: void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface); diff --git a/src/video_core/swrasterizer/swrasterizer.h b/src/video_core/swrasterizer/swrasterizer.h index e2292f4a4..9e7a140f1 100644 --- a/src/video_core/swrasterizer/swrasterizer.h +++ b/src/video_core/swrasterizer/swrasterizer.h @@ -22,6 +22,7 @@ class SWRasterizer : public RasterizerInterface { void FlushRegion(PAddr addr, u32 size) override {} void InvalidateRegion(PAddr addr, u32 size) override {} void FlushAndInvalidateRegion(PAddr addr, u32 size) override {} + void ClearAll(bool flush) override {} }; } // namespace VideoCore From c983528862987d248c6dcf0db83ed08f3c8dae76 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Sun, 19 Jan 2020 22:49:22 +0000 Subject: [PATCH 075/129] Reworked DSP serialization --- externals/boost | 2 +- src/audio_core/dsp_interface.h | 5 +++ src/audio_core/hle/hle.cpp | 37 +++++++++++++++++--- src/audio_core/hle/hle.h | 9 +++++ src/audio_core/hle/mixers.h | 12 +++++++ src/audio_core/hle/shared_memory.h | 7 ++++ src/audio_core/hle/source.h | 54 ++++++++++++++++++++++++++++-- src/core/core.cpp | 15 ++++++--- 8 files changed, 128 insertions(+), 13 deletions(-) diff --git a/externals/boost b/externals/boost index 6d7edc593..eb10fac1e 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 6d7edc593be8e47c8de7bc5f7d6b32971fad0c24 +Subproject commit eb10fac1e1dfa4881c273d87e23d41509017223a diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h index fc3d7cab2..00adfa3ea 100644 --- a/src/audio_core/dsp_interface.h +++ b/src/audio_core/dsp_interface.h @@ -6,6 +6,7 @@ #include #include +#include #include "audio_core/audio_types.h" #include "audio_core/time_stretch.h" #include "common/common_types.h" @@ -113,6 +114,10 @@ private: Common::RingBuffer fifo; std::array last_frame{}; TimeStretcher time_stretcher; + + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace AudioCore diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index 873d6a72e..f96e2b642 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -1,7 +1,13 @@ +#pragma optimize("", off) // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include +#include +#include +#include #include "audio_core/audio_types.h" #ifdef HAVE_MF #include "audio_core/hle/wmf_decoder.h" @@ -22,11 +28,21 @@ #include "core/core.h" #include "core/core_timing.h" +SERIALIZE_EXPORT_IMPL(AudioCore::DspHle) + using InterruptType = Service::DSP::DSP_DSP::InterruptType; using Service::DSP::DSP_DSP; namespace AudioCore { +DspHle::DspHle() : DspHle(Core::System::GetInstance().Memory()) {} + +template +void DspHle::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar&* impl.get(); +} + static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles struct DspHle::Impl final { @@ -60,7 +76,7 @@ private: void AudioTickCallback(s64 cycles_late); DspState dsp_state = DspState::Off; - std::array, num_dsp_pipe> pipe_data; + std::array, num_dsp_pipe> pipe_data{}; HLE::DspMemory dsp_memory; std::array sources{{ @@ -70,14 +86,25 @@ private: HLE::Source(15), HLE::Source(16), HLE::Source(17), HLE::Source(18), HLE::Source(19), HLE::Source(20), HLE::Source(21), HLE::Source(22), HLE::Source(23), }}; - HLE::Mixers mixers; + HLE::Mixers mixers{}; DspHle& parent; - Core::TimingEventType* tick_event; + Core::TimingEventType* tick_event{}; - std::unique_ptr decoder; + std::unique_ptr decoder{}; - std::weak_ptr dsp_dsp; + std::weak_ptr dsp_dsp{}; + + template + void serialize(Archive& ar, const unsigned int) { + ar& dsp_state; + ar& pipe_data; + ar& dsp_memory.raw_memory; + ar& sources; + ar& mixers; + ar& dsp_dsp; + } + friend class boost::serialization::access; }; DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(parent_) { diff --git a/src/audio_core/hle/hle.h b/src/audio_core/hle/hle.h index 4ab468331..11ec2820a 100644 --- a/src/audio_core/hle/hle.h +++ b/src/audio_core/hle/hle.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "audio_core/audio_types.h" #include "audio_core/dsp_interface.h" #include "common/common_types.h" @@ -42,6 +43,14 @@ private: struct Impl; friend struct Impl; std::unique_ptr impl; + + DspHle(); + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace AudioCore + +BOOST_CLASS_EXPORT_KEY(AudioCore::DspHle) diff --git a/src/audio_core/hle/mixers.h b/src/audio_core/hle/mixers.h index c5bfd512f..5043be38c 100644 --- a/src/audio_core/hle/mixers.h +++ b/src/audio_core/hle/mixers.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "audio_core/audio_types.h" #include "audio_core/hle/shared_memory.h" @@ -54,6 +55,17 @@ private: void DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& samples); /// INTERNAL: Generate DspStatus based on internal state. DspStatus GetCurrentStatus() const; + + template + void serialize(Archive& ar, const unsigned int) { + ar& current_frame; + ar& state.intermediate_mixer_volume; + ar& state.mixer1_enabled; + ar& state.mixer2_enabled; + ar& state.intermediate_mix_buffer; + ar& state.output_format; + } + friend class boost::serialization::access; }; } // namespace AudioCore::HLE diff --git a/src/audio_core/hle/shared_memory.h b/src/audio_core/hle/shared_memory.h index 8ab9aa88e..43bf1df69 100644 --- a/src/audio_core/hle/shared_memory.h +++ b/src/audio_core/hle/shared_memory.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "audio_core/audio_types.h" #include "audio_core/hle/common.h" #include "common/bit_field.h" @@ -56,6 +57,12 @@ private: return (value << 16) | (value >> 16); } u32_le storage; + + template + void serialize(Archive& ar, const unsigned int) { + ar& storage; + } + friend class boost::serialization::access; }; static_assert(std::is_trivially_copyable::value, "u32_dsp isn't trivially copyable"); diff --git a/src/audio_core/hle/source.h b/src/audio_core/hle/source.h index b0db4a5d3..17c31672b 100644 --- a/src/audio_core/hle/source.h +++ b/src/audio_core/hle/source.h @@ -6,6 +6,10 @@ #include #include +#include +#include +#include +#include #include #include "audio_core/audio_types.h" #include "audio_core/codec.h" @@ -85,6 +89,24 @@ private: bool from_queue; u32_dsp play_position; // = 0; bool has_played; // = false; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& physical_address; + ar& length; + ar& adpcm_ps; + ar& adpcm_yn; + ar& adpcm_dirty; + ar& is_looping; + ar& buffer_id; + ar& mono_or_stereo; + ar& format; + ar& from_queue; + ar& play_position; + ar& has_played; + } + friend class boost::serialization::access; }; struct BufferOrder { @@ -107,7 +129,7 @@ private: // Buffer queue - std::priority_queue, BufferOrder> input_queue; + std::priority_queue, BufferOrder> input_queue = {}; MonoOrStereo mono_or_stereo = MonoOrStereo::Mono; Format format = Format::ADPCM; @@ -115,7 +137,7 @@ private: u32 current_sample_number = 0; u32 next_sample_number = 0; - AudioInterp::StereoBuffer16 current_buffer; + AudioInterp::StereoBuffer16 current_buffer = {}; // buffer_id state @@ -135,7 +157,27 @@ private: // Filter state - SourceFilters filters; + SourceFilters filters = {}; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& enabled; + ar& sync; + ar& gain; + ar& input_queue; + ar& mono_or_stereo; + ar& format; + ar& current_sample_number; + ar& next_sample_number; + ar& current_buffer; + ar& buffer_update; + ar& current_buffer_id; + ar& adpcm_coeffs; + ar& rate_multiplier; + ar& interpolation_mode; + } + friend class boost::serialization::access; } state; @@ -150,6 +192,12 @@ private: bool DequeueBuffer(); /// INTERNAL: Generates a SourceStatus::Status based on our internal state. SourceStatus::Status GetCurrentStatus(); + + template + void serialize(Archive& ar, const unsigned int) { + ar& state; + } + friend class boost::serialization::access; }; } // namespace AudioCore::HLE diff --git a/src/core/core.cpp b/src/core/core.cpp index aeab0d2b5..03b64b04e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,3 +1,4 @@ +#pragma optimize("", off) // Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -244,8 +245,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique(); - kernel = std::make_unique(*memory, *timing, - [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique( + *memory, *timing, [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -445,14 +446,20 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* service_manager.get(); ar& GPU::g_regs; ar& LCD::g_regs; - ar & dsp_core->GetDspMemory(); + if (Archive::is_loading::value) { + dsp_core.reset(); + } + ar& dsp_core; ar&* memory.get(); ar&* kernel.get(); // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); - DSP().SetServiceToInterrupt(ServiceManager().GetService("dsp::DSP")); + + memory->SetDSP(*dsp_core); + dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id); + dsp_core->EnableStretching(Settings::values.enable_audio_stretching); } } From 246ae84a521fa286b21beca30638f2150f52f5d9 Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Mon, 20 Jan 2020 21:32:38 +0000 Subject: [PATCH 076/129] Pretty sure ARM/Thread serialization works now --- src/core/arm/arm_interface.h | 17 +++++++++++++++-- src/core/arm/dynarmic/arm_dynarmic.cpp | 14 +++++++++++--- src/core/arm/dynarmic/arm_dynarmic.h | 4 +++- src/core/arm/dyncom/arm_dyncom.cpp | 8 +++++++- src/core/arm/dyncom/arm_dyncom.h | 4 +++- src/core/core.cpp | 3 --- src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/thread.h | 1 - 8 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index e416a5f4c..8ef51519b 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -11,6 +11,10 @@ #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" +namespace Memory { +struct PageTable; +} + /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { public: @@ -111,7 +115,9 @@ public: virtual void InvalidateCacheRange(u32 start_address, std::size_t length) = 0; /// Notify CPU emulation that page tables have changed - virtual void PageTableChanged() = 0; + virtual void SetPageTable(const std::shared_ptr& page_table) = 0; + + virtual std::shared_ptr GetPageTable() const = 0; /** * Set the Program Counter to an address @@ -214,11 +220,15 @@ public: /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; + virtual void PurgeState() = 0; + private: friend class boost::serialization::access; template void save(Archive& ar, const unsigned int file_version) const { + auto page_table = GetPageTable(); + ar << page_table; for (auto i = 0; i < 15; i++) { auto r = GetReg(i); ar << r; @@ -243,6 +253,10 @@ private: template void load(Archive& ar, const unsigned int file_version) { + PurgeState(); + std::shared_ptr page_table = nullptr; + ar >> page_table; + SetPageTable(page_table); u32 r; for (auto i = 0; i < 15; i++) { ar >> r; @@ -264,7 +278,6 @@ private: ar >> r; SetCP15Register(static_cast(i), r); } - ClearInstructionCache(); } BOOST_SERIALIZATION_SPLIT_MEMBER() diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index b6494d40e..33bc03a4f 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -167,7 +167,7 @@ ARM_Dynarmic::ARM_Dynarmic(Core::System* system, Memory::MemorySystem& memory, PrivilegeMode initial_mode) : system(*system), memory(memory), cb(std::make_unique(*this)) { interpreter_state = std::make_shared(system, memory, initial_mode); - PageTableChanged(); + SetPageTable(memory.GetCurrentPageTable()); } ARM_Dynarmic::~ARM_Dynarmic() = default; @@ -281,8 +281,12 @@ void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, std::size_t length) { jit->InvalidateCacheRange(start_address, length); } -void ARM_Dynarmic::PageTableChanged() { - current_page_table = memory.GetCurrentPageTable(); +std::shared_ptr ARM_Dynarmic::GetPageTable() const { + return current_page_table; +} + +void ARM_Dynarmic::SetPageTable(const std::shared_ptr& page_table) { + current_page_table = page_table; Dynarmic::A32::Context ctx{}; if (jit) { jit->SaveContext(ctx); @@ -309,3 +313,7 @@ std::unique_ptr ARM_Dynarmic::MakeJit() { config.define_unpredictable_behaviour = true; return std::make_unique(config); } + +void ARM_Dynarmic::PurgeState() { + ClearInstructionCache(); +} diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 690c1aa2e..c4d01835d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -51,7 +51,9 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; + void SetPageTable(const std::shared_ptr& page_table) override; + std::shared_ptr GetPageTable() const override; + void PurgeState() override; private: friend class DynarmicUserCallbacks; diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 6b67644e7..c069b428e 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -94,10 +94,16 @@ void ARM_DynCom::InvalidateCacheRange(u32, std::size_t) { ClearInstructionCache(); } -void ARM_DynCom::PageTableChanged() { +void ARM_DynCom::SetPageTable(const std::shared_ptr& page_table) { ClearInstructionCache(); } +std::shared_ptr ARM_DynCom::GetPageTable() const { + return nullptr; +} + +void ARM_DynCom::PurgeState() {} + void ARM_DynCom::SetPC(u32 pc) { state->Reg[15] = pc; } diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 7497b765f..39d55a62a 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -29,7 +29,6 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; - void PageTableChanged() override; void SetPC(u32 pc) override; u32 GetPC() const override; @@ -48,7 +47,10 @@ public: void SaveContext(const std::unique_ptr& arg) override; void LoadContext(const std::unique_ptr& arg) override; + void SetPageTable(const std::shared_ptr& page_table) override; + std::shared_ptr GetPageTable() const override; void PrepareReschedule() override; + void PurgeState() override; private: void ExecuteInstructions(u64 num_instructions); diff --git a/src/core/core.cpp b/src/core/core.cpp index 03b64b04e..18c2e77e1 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -486,9 +486,6 @@ void System::Load(std::istream& stream) { } VideoCore::Load(stream); - // Flush state through: - Kernel().SetCurrentProcess(Kernel().GetCurrentProcess()); - } catch (const std::exception& e) { LOG_ERROR(Core, "Error loading: {}", e.what()); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 3c3dfc6c6..ea3da508e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -61,7 +61,7 @@ void KernelSystem::SetCurrentProcess(std::shared_ptr process) { void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr page_table) { memory.SetCurrentPageTable(page_table); if (current_cpu != nullptr) { - current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed + current_cpu->SetPageTable(page_table); } } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 0286e210d..c64e24071 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -172,7 +172,6 @@ private: ar& ready_queue; ar& wakeup_callback_table; ar& thread_list; - SwitchContext(current_thread.get()); } }; From 5aa5cd60641401878158644a40007f9040732bae Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Thu, 13 Feb 2020 17:26:21 +0800 Subject: [PATCH 077/129] Fix externals/boost spec --- externals/boost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/boost b/externals/boost index eb10fac1e..6d7edc593 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit eb10fac1e1dfa4881c273d87e23d41509017223a +Subproject commit 6d7edc593be8e47c8de7bc5f7d6b32971fad0c24 From 7e8041df28252b0c974741ffecc87dcf87a7c406 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Fri, 14 Feb 2020 17:13:53 +0800 Subject: [PATCH 078/129] kernel/timer: Add missing base object --- src/core/hle/kernel/timer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index d2c513024..b591c1b03 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -115,6 +115,7 @@ private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object(*this); ar& reset_type; ar& initial_delay; ar& interval_delay; From 57efc419734aa8b9f187de2c610548061acef74b Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Fri, 14 Feb 2020 17:15:08 +0800 Subject: [PATCH 079/129] service/cecd: Add missing SessionData serialization --- src/core/hle/service/cecd/cecd.cpp | 1 + src/core/hle/service/cecd/cecd.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index f13df6926..36263f622 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -27,6 +27,7 @@ SERVICE_CONSTRUCT_IMPL(Service::CECD::Module) SERIALIZE_EXPORT_IMPL(Service::CECD::Module) +SERIALIZE_EXPORT_IMPL(Service::CECD::Module::SessionData) namespace Service::CECD { diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index dd7fff7cb..0870f31bf 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -248,6 +248,19 @@ public: FileSys::Path path; std::unique_ptr file; + + private: + template + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object( + *this); + ar& ncch_program_id; + ar& data_path_type; + ar& open_mode.raw; + ar& path; + ar& file; + } + friend class boost::serialization::access; }; class Interface : public ServiceFramework { @@ -626,3 +639,4 @@ void InstallInterfaces(Core::System& system); SERVICE_CONSTRUCT(Service::CECD::Module) BOOST_CLASS_EXPORT_KEY(Service::CECD::Module) +BOOST_CLASS_EXPORT_KEY(Service::CECD::Module::SessionData) From 7d880f94db5485fdda342cf72cedf0e7901a2293 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Sun, 16 Feb 2020 23:25:30 +0800 Subject: [PATCH 080/129] Add simple zstd compression Just a simple default compression is able to shrink savestate file size from ~160MB to ~20MB. --- src/core/core.cpp | 29 +++++++++++++++++++++++------ src/core/core.h | 2 +- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 18c2e77e1..0bbb79aea 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -13,6 +13,7 @@ #include "common/archives.h" #include "common/logging/log.h" #include "common/texture.h" +#include "common/zstd_compression.h" #include "core/arm/arm_interface.h" #ifdef ARCHITECTURE_x86_64 #include "core/arm/dynarmic/arm_dynarmic.h" @@ -116,7 +117,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) { case Signal::Load: { LOG_INFO(Core, "Begin load"); auto stream = std::ifstream("save0.citrasave", std::fstream::binary); - System::Load(stream); + System::Load(stream, FileUtil::GetSize("save0.citrasave")); LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { @@ -464,27 +465,43 @@ void System::serialize(Archive& ar, const unsigned int file_version) { } void System::Save(std::ostream& stream) const { + std::ostringstream sstream{std::ios_base::binary}; try { { - oarchive oa{stream}; + oarchive oa{sstream}; oa&* this; } - VideoCore::Save(stream); + VideoCore::Save(sstream); } catch (const std::exception& e) { LOG_ERROR(Core, "Error saving: {}", e.what()); } + const std::string& str{sstream.str()}; + auto buffer = Common::Compression::CompressDataZSTDDefault( + reinterpret_cast(str.data()), str.size()); + stream.write(reinterpret_cast(buffer.data()), buffer.size()); } -void System::Load(std::istream& stream) { +void System::Load(std::istream& stream, std::size_t size) { + std::vector decompressed; + { + std::vector buffer(size); + stream.read(reinterpret_cast(buffer.data()), size); + decompressed = Common::Compression::DecompressDataZSTD(buffer); + } + std::istringstream sstream{ + std::string{reinterpret_cast(decompressed.data()), decompressed.size()}, + std::ios_base::binary}; + decompressed.clear(); + try { { - iarchive ia{stream}; + iarchive ia{sstream}; ia&* this; } - VideoCore::Load(stream); + VideoCore::Load(sstream); } catch (const std::exception& e) { LOG_ERROR(Core, "Error loading: {}", e.what()); diff --git a/src/core/core.h b/src/core/core.h index a3b2f5cdd..80c1505b5 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -278,7 +278,7 @@ public: void Save(std::ostream& stream) const; - void Load(std::istream& stream); + void Load(std::istream& stream, std::size_t size); private: /** From a487016cb42d0d36ed8706909f4423571141fcaf Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Tue, 18 Feb 2020 13:19:52 +0800 Subject: [PATCH 081/129] core, citra_qt: Implement a save states file format and slot UI 10 slots are offered along with 'Save to Oldest Slot' and 'Load from Newest Slot'. The savestate format is similar to the movie file format. It is called CST (Citra SavesTate), and is basically a 0x100 byte header (consisting of magic, revision, creation time and title ID) followed by Zstd compressed raw savestate data. The savestate files are saved to the `states` folder in Citra's user folder. The files are named like `.<Slot ID>.cst`. --- src/citra_qt/main.cpp | 111 +++++++++++++++++++++--- src/citra_qt/main.h | 16 +++- src/citra_qt/main.ui | 29 ++++++- src/common/common_paths.h | 1 + src/common/file_util.cpp | 1 + src/common/file_util.h | 1 + src/core/CMakeLists.txt | 2 + src/core/core.cpp | 85 ++++++------------- src/core/core.h | 14 ++- src/core/savestate.cpp | 174 ++++++++++++++++++++++++++++++++++++++ src/core/savestate.h | 27 ++++++ 11 files changed, 384 insertions(+), 77 deletions(-) create mode 100644 src/core/savestate.cpp create mode 100644 src/core/savestate.h diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 7fe4936f5..de66e14ac 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -79,6 +79,7 @@ #include "core/hle/service/nfc/nfc.h" #include "core/loader/loader.h" #include "core/movie.h" +#include "core/savestate.h" #include "core/settings.h" #include "game_list_p.h" #include "video_core/renderer_base.h" @@ -166,6 +167,7 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { InitializeWidgets(); InitializeDebugWidgets(); InitializeRecentFileMenuActions(); + InitializeSaveStateMenuActions(); InitializeHotkeys(); ShowUpdaterWidgets(); @@ -383,6 +385,32 @@ void GMainWindow::InitializeRecentFileMenuActions() { UpdateRecentFiles(); } +void GMainWindow::InitializeSaveStateMenuActions() { + for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) { + actions_load_state[i] = new QAction(this); + actions_load_state[i]->setData(i + 1); + connect(actions_load_state[i], &QAction::triggered, this, &GMainWindow::OnLoadState); + ui.menu_Load_State->addAction(actions_load_state[i]); + + actions_save_state[i] = new QAction(this); + actions_save_state[i]->setData(i + 1); + connect(actions_save_state[i], &QAction::triggered, this, &GMainWindow::OnSaveState); + ui.menu_Save_State->addAction(actions_save_state[i]); + } + + connect(ui.action_Load_from_Newest_Slot, &QAction::triggered, + [this] { actions_load_state[newest_slot - 1]->trigger(); }); + connect(ui.action_Save_to_Oldest_Slot, &QAction::triggered, + [this] { actions_save_state[oldest_slot - 1]->trigger(); }); + + connect(ui.menu_Load_State->menuAction(), &QAction::hovered, this, + &GMainWindow::UpdateSaveStates); + connect(ui.menu_Save_State->menuAction(), &QAction::hovered, this, + &GMainWindow::UpdateSaveStates); + + UpdateSaveStates(); +} + void GMainWindow::InitializeHotkeys() { hotkey_registry.LoadHotkeys(); @@ -607,8 +635,6 @@ void GMainWindow::ConnectMenuEvents() { &GMainWindow::OnMenuReportCompatibility); connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); connect(ui.action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats); - connect(ui.action_Save, &QAction::triggered, this, &GMainWindow::OnSave); - connect(ui.action_Load, &QAction::triggered, this, &GMainWindow::OnLoad); // View connect(ui.action_Single_Window_Mode, &QAction::triggered, this, @@ -1036,8 +1062,6 @@ void GMainWindow::ShutdownGame() { ui.action_Stop->setEnabled(false); ui.action_Restart->setEnabled(false); ui.action_Cheats->setEnabled(false); - ui.action_Save->setEnabled(false); - ui.action_Load->setEnabled(false); ui.action_Load_Amiibo->setEnabled(false); ui.action_Remove_Amiibo->setEnabled(false); ui.action_Report_Compatibility->setEnabled(false); @@ -1061,6 +1085,8 @@ void GMainWindow::ShutdownGame() { game_fps_label->setVisible(false); emu_frametime_label->setVisible(false); + UpdateSaveStates(); + emulation_running = false; if (defer_update_prompt) { @@ -1107,6 +1133,62 @@ void GMainWindow::UpdateRecentFiles() { ui.menu_recent_files->setEnabled(num_recent_files != 0); } +void GMainWindow::UpdateSaveStates() { + if (!Core::System::GetInstance().IsPoweredOn()) { + ui.menu_Load_State->setEnabled(false); + ui.menu_Save_State->setEnabled(false); + return; + } + + ui.menu_Load_State->setEnabled(true); + ui.menu_Save_State->setEnabled(true); + ui.action_Load_from_Newest_Slot->setEnabled(false); + + oldest_slot = newest_slot = 0; + oldest_slot_time = std::numeric_limits<u64>::max(); + newest_slot_time = 0; + + u64 title_id; + if (Core::System::GetInstance().GetAppLoader().ReadProgramId(title_id) != + Loader::ResultStatus::Success) { + return; + } + auto savestates = Core::ListSaveStates(title_id); + for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) { + actions_load_state[i]->setEnabled(false); + actions_load_state[i]->setText(tr("Slot %1").arg(i + 1)); + actions_save_state[i]->setText(tr("Slot %1").arg(i + 1)); + } + for (const auto& savestate : savestates) { + const auto text = tr("Slot %1 - %2") + .arg(savestate.slot) + .arg(QDateTime::fromSecsSinceEpoch(savestate.time) + .toString(QStringLiteral("yyyy-MM-dd hh:mm:ss"))); + actions_load_state[savestate.slot - 1]->setEnabled(true); + actions_load_state[savestate.slot - 1]->setText(text); + actions_save_state[savestate.slot - 1]->setText(text); + + ui.action_Load_from_Newest_Slot->setEnabled(true); + + if (savestate.time > newest_slot_time) { + newest_slot = savestate.slot; + newest_slot_time = savestate.time; + } + if (savestate.time < oldest_slot_time) { + oldest_slot = savestate.slot; + oldest_slot_time = savestate.time; + } + } + for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) { + if (!actions_load_state[i]->isEnabled()) { + // Prefer empty slot + oldest_slot = i + 1; + oldest_slot_time = 0; + break; + } + } +} + void GMainWindow::OnGameListLoadFile(QString game_path) { BootGame(game_path); } @@ -1348,14 +1430,14 @@ void GMainWindow::OnStartGame() { ui.action_Stop->setEnabled(true); ui.action_Restart->setEnabled(true); ui.action_Cheats->setEnabled(true); - ui.action_Save->setEnabled(true); - ui.action_Load->setEnabled(true); ui.action_Load_Amiibo->setEnabled(true); ui.action_Report_Compatibility->setEnabled(true); ui.action_Enable_Frame_Advancing->setEnabled(true); ui.action_Capture_Screenshot->setEnabled(true); discord_rpc->Update(); + + UpdateSaveStates(); } void GMainWindow::OnPauseGame() { @@ -1503,14 +1585,19 @@ void GMainWindow::OnCheats() { cheat_dialog.exec(); } -void GMainWindow::OnSave() { - Core::System::GetInstance().SendSignal(Core::System::Signal::Save); +void GMainWindow::OnSaveState() { + QAction* action = qobject_cast<QAction*>(sender()); + assert(action); + + Core::System::GetInstance().SendSignal(Core::System::Signal::Save, action->data().toUInt()); + UpdateSaveStates(); } -void GMainWindow::OnLoad() { - if (QFileInfo("save0.citrasave").exists()) { - Core::System::GetInstance().SendSignal(Core::System::Signal::Load); - } +void GMainWindow::OnLoadState() { + QAction* action = qobject_cast<QAction*>(sender()); + assert(action); + + Core::System::GetInstance().SendSignal(Core::System::Signal::Load, action->data().toUInt()); } void GMainWindow::OnConfigure() { diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 1858d5988..ebe1a013a 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -4,6 +4,7 @@ #pragma once +#include <array> #include <memory> #include <QLabel> #include <QMainWindow> @@ -14,6 +15,7 @@ #include "common/announce_multiplayer_room.h" #include "core/core.h" #include "core/hle/service/am/am.h" +#include "core/savestate.h" #include "ui_main.h" class AboutDialog; @@ -106,6 +108,7 @@ private: void InitializeWidgets(); void InitializeDebugWidgets(); void InitializeRecentFileMenuActions(); + void InitializeSaveStateMenuActions(); void SetDefaultUIGeometry(); void SyncMenuUISettings(); @@ -149,6 +152,8 @@ private: */ void UpdateRecentFiles(); + void UpdateSaveStates(); + /** * If the emulation is running, * asks the user if he really want to close the emulator @@ -163,8 +168,8 @@ private slots: void OnStartGame(); void OnPauseGame(); void OnStopGame(); - void OnSave(); - void OnLoad(); + void OnSaveState(); + void OnLoadState(); void OnMenuReportCompatibility(); /// Called whenever a user selects a game in the game list widget. void OnGameListLoadFile(QString game_path); @@ -276,6 +281,13 @@ private: bool defer_update_prompt = false; QAction* actions_recent_files[max_recent_files_item]; + std::array<QAction*, Core::SaveStateSlotCount> actions_load_state; + std::array<QAction*, Core::SaveStateSlotCount> actions_save_state; + + u32 oldest_slot; + u64 oldest_slot_time; + u32 newest_slot; + u64 newest_slot_time; QTranslator translator; diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index c0c38e4c8..2eff98083 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -79,17 +79,32 @@ <property name="title"> <string>&Emulation</string> </property> + <widget class="QMenu" name="menu_Save_State"> + <property name="title"> + <string>Save State</string> + </property> + <addaction name="action_Save_to_Oldest_Slot"/> + <addaction name="separator"/> + </widget> + <widget class="QMenu" name="menu_Load_State"> + <property name="title"> + <string>Load State</string> + </property> + <addaction name="action_Load_from_Newest_Slot"/> + <addaction name="separator"/> + </widget> <addaction name="action_Start"/> <addaction name="action_Pause"/> <addaction name="action_Stop"/> <addaction name="action_Restart"/> <addaction name="separator"/> + <addaction name="menu_Load_State"/> + <addaction name="menu_Save_State"/> + <addaction name="separator"/> <addaction name="action_Report_Compatibility"/> <addaction name="separator"/> <addaction name="action_Configure"/> <addaction name="action_Cheats"/> - <addaction name="action_Save"/> - <addaction name="action_Load"/> </widget> <widget class="QMenu" name="menu_View"> <property name="title"> @@ -253,6 +268,16 @@ <string>Single Window Mode</string> </property> </action> + <action name="action_Save_to_Oldest_Slot"> + <property name="text"> + <string>Save to Oldest Slot</string> + </property> + </action> + <action name="action_Load_from_Newest_Slot"> + <property name="text"> + <string>Load from Newest Slot</string> + </property> + </action> <action name="action_Configure"> <property name="text"> <string>Configure...</string> diff --git a/src/common/common_paths.h b/src/common/common_paths.h index 13e71615e..eec4dde9c 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -47,6 +47,7 @@ #define DUMP_DIR "dump" #define LOAD_DIR "load" #define SHADER_DIR "shaders" +#define STATES_DIR "states" // Filenames // Files in the directory returned by GetUserPath(UserPath::LogDir) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index c5da82973..cd3f4e102 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -725,6 +725,7 @@ void SetUserPath(const std::string& path) { g_paths.emplace(UserPath::ShaderDir, user_path + SHADER_DIR DIR_SEP); g_paths.emplace(UserPath::DumpDir, user_path + DUMP_DIR DIR_SEP); g_paths.emplace(UserPath::LoadDir, user_path + LOAD_DIR DIR_SEP); + g_paths.emplace(UserPath::StatesDir, user_path + STATES_DIR DIR_SEP); } const std::string& GetUserPath(UserPath path) { diff --git a/src/common/file_util.h b/src/common/file_util.h index 0368d3665..8af5a2a61 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -36,6 +36,7 @@ enum class UserPath { RootDir, SDMCDir, ShaderDir, + StatesDir, SysDataDir, UserDir, }; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c6908c59a..2b02ffc41 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -447,6 +447,8 @@ add_library(core STATIC rpc/server.h rpc/udp_server.cpp rpc/udp_server.h + savestate.cpp + savestate.h settings.cpp settings.h telemetry_session.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index 0bbb79aea..f17474a85 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -10,10 +10,8 @@ #include "audio_core/dsp_interface.h" #include "audio_core/hle/hle.h" #include "audio_core/lle/lle.h" -#include "common/archives.h" #include "common/logging/log.h" #include "common/texture.h" -#include "common/zstd_compression.h" #include "core/arm/arm_interface.h" #ifdef ARCHITECTURE_x86_64 #include "core/arm/dynarmic/arm_dynarmic.h" @@ -63,6 +61,8 @@ Kernel::KernelSystem& Global() { return System::GetInstance().Kernel(); } +System::~System() = default; + System::ResultStatus System::RunLoop(bool tight_loop) { status = ResultStatus::Success; if (!cpu_core) { @@ -106,7 +106,16 @@ System::ResultStatus System::RunLoop(bool tight_loop) { HW::Update(); Reschedule(); - auto signal = current_signal.exchange(Signal::None); + Signal signal{Signal::None}; + u32 param{}; + { + std::lock_guard lock{signal_mutex}; + if (current_signal != Signal::None) { + signal = current_signal; + param = signal_param; + current_signal = Signal::None; + } + } switch (signal) { case Signal::Reset: Reset(); @@ -116,14 +125,16 @@ System::ResultStatus System::RunLoop(bool tight_loop) { break; case Signal::Load: { LOG_INFO(Core, "Begin load"); - auto stream = std::ifstream("save0.citrasave", std::fstream::binary); - System::Load(stream, FileUtil::GetSize("save0.citrasave")); + System::LoadState(param); + // auto stream = std::ifstream("save0.citrasave", std::fstream::binary); + // System::Load(stream, FileUtil::GetSize("save0.citrasave")); LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { LOG_INFO(Core, "Begin save"); - auto stream = std::ofstream("save0.citrasave", std::fstream::binary); - System::Save(stream); + System::SaveState(param); + // auto stream = std::ofstream("save0.citrasave", std::fstream::binary); + // System::Save(stream); LOG_INFO(Core, "Save completed"); } break; default: @@ -133,12 +144,14 @@ System::ResultStatus System::RunLoop(bool tight_loop) { return status; } -bool System::SendSignal(System::Signal signal) { - auto prev = System::Signal::None; - if (!current_signal.compare_exchange_strong(prev, signal)) { - LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, prev); +bool System::SendSignal(System::Signal signal, u32 param) { + std::lock_guard lock{signal_mutex}; + if (current_signal != signal && current_signal != Signal::None) { + LOG_ERROR(Core, "Unable to {} as {} is ongoing", signal, current_signal); return false; } + current_signal = signal; + signal_param = param; return true; } @@ -196,7 +209,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st } } cheat_engine = std::make_unique<Cheats::CheatEngine>(*this); - u64 title_id{0}; + title_id = 0; if (app_loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) { LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", static_cast<u32>(load_result)); @@ -246,8 +259,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo timing = std::make_unique<Timing>(); - kernel = std::make_unique<Kernel::KernelSystem>( - *memory, *timing, [this] { PrepareReschedule(); }, system_mode); + kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing, + [this] { PrepareReschedule(); }, system_mode); if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 @@ -464,48 +477,6 @@ void System::serialize(Archive& ar, const unsigned int file_version) { } } -void System::Save(std::ostream& stream) const { - std::ostringstream sstream{std::ios_base::binary}; - try { - - { - oarchive oa{sstream}; - oa&* this; - } - VideoCore::Save(sstream); - - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error saving: {}", e.what()); - } - const std::string& str{sstream.str()}; - auto buffer = Common::Compression::CompressDataZSTDDefault( - reinterpret_cast<const u8*>(str.data()), str.size()); - stream.write(reinterpret_cast<const char*>(buffer.data()), buffer.size()); -} - -void System::Load(std::istream& stream, std::size_t size) { - std::vector<u8> decompressed; - { - std::vector<u8> buffer(size); - stream.read(reinterpret_cast<char*>(buffer.data()), size); - decompressed = Common::Compression::DecompressDataZSTD(buffer); - } - std::istringstream sstream{ - std::string{reinterpret_cast<char*>(decompressed.data()), decompressed.size()}, - std::ios_base::binary}; - decompressed.clear(); - - try { - - { - iarchive ia{sstream}; - ia&* this; - } - VideoCore::Load(sstream); - - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error loading: {}", e.what()); - } -} +SERIALIZE_IMPL(System) } // namespace Core diff --git a/src/core/core.h b/src/core/core.h index 80c1505b5..0ce6924cd 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <mutex> #include <string> #include "boost/serialization/access.hpp" #include "common/common_types.h" @@ -92,6 +93,8 @@ public: ErrorUnknown ///< Any other error }; + ~System(); + /** * Run the core CPU loop * This function runs the core for the specified number of CPU instructions before trying to @@ -118,7 +121,7 @@ public: enum class Signal : u32 { None, Shutdown, Reset, Save, Load }; - bool SendSignal(Signal signal); + bool SendSignal(Signal signal, u32 param = 0); /// Request reset of the system void RequestReset() { @@ -276,9 +279,9 @@ public: return registered_image_interface; } - void Save(std::ostream& stream) const; + void SaveState(u32 slot) const; - void Load(std::istream& stream, std::size_t size); + void LoadState(u32 slot); private: /** @@ -344,8 +347,11 @@ private: /// Saved variables for reset Frontend::EmuWindow* m_emu_window; std::string m_filepath; + u64 title_id; - std::atomic<Signal> current_signal; + std::mutex signal_mutex; + Signal current_signal; + u32 signal_param; friend class boost::serialization::access; template <typename Archive> diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp new file mode 100644 index 000000000..d52789b2c --- /dev/null +++ b/src/core/savestate.cpp @@ -0,0 +1,174 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <chrono> +#include <cryptopp/hex.h> +#include "common/archives.h" +#include "common/logging/log.h" +#include "common/scm_rev.h" +#include "common/zstd_compression.h" +#include "core/core.h" +#include "core/savestate.h" +#include "video_core/video_core.h" + +namespace Core { + +#pragma pack(push, 1) +struct CSTHeader { + std::array<u8, 4> filetype; /// Unique Identifier to check the file type (always "CST"0x1B) + u64_le program_id; /// ID of the ROM being executed. Also called title_id + std::array<u8, 20> revision; /// Git hash of the revision this savestate was created with + u64_le time; /// The time when this save state was created + + std::array<u8, 216> reserved; /// Make heading 256 bytes so it has consistent size +}; +static_assert(sizeof(CSTHeader) == 256, "CSTHeader should be 256 bytes"); +#pragma pack(pop) + +constexpr std::array<u8, 4> header_magic_bytes{{'C', 'S', 'T', 0x1B}}; + +std::string GetSaveStatePath(u64 program_id, u32 slot) { + return fmt::format("{}{:016X}.{:02d}.cst", FileUtil::GetUserPath(FileUtil::UserPath::StatesDir), + program_id, slot); +} + +std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { + std::vector<SaveStateInfo> result; + for (u32 slot = 1; slot <= SaveStateSlotCount; ++slot) { + const auto path = GetSaveStatePath(program_id, slot); + if (!FileUtil::Exists(path)) { + continue; + } + + SaveStateInfo info; + info.slot = slot; + + FileUtil::IOFile file(path, "rb"); + if (!file) { + LOG_ERROR(Core, "Could not open file {}", path); + continue; + } + CSTHeader header; + if (file.GetSize() < sizeof(header)) { + LOG_ERROR(Core, "File too small {}", path); + continue; + } + if (file.ReadBytes(&header, sizeof(header)) != sizeof(header)) { + LOG_ERROR(Core, "Could not read from file {}", path); + continue; + } + if (header.filetype != header_magic_bytes) { + LOG_WARNING(Core, "Invalid save state file {}", path); + continue; + } + info.time = header.time; + + if (header.program_id != program_id) { + LOG_WARNING(Core, "Save state file isn't for the current game {}", path); + continue; + } + std::string revision = fmt::format("{:02x}", fmt::join(header.revision, "")); + if (revision == Common::g_scm_rev) { + info.status = SaveStateInfo::ValidationStatus::OK; + } else { + LOG_WARNING(Core, "Save state file created from a different revision {}", path); + info.status = SaveStateInfo::ValidationStatus::RevisionDismatch; + } + result.emplace_back(std::move(info)); + } + return result; +} + +void System::SaveState(u32 slot) const { + std::ostringstream sstream{std::ios_base::binary}; + try { + + { + oarchive oa{sstream}; + oa&* this; + } + VideoCore::Save(sstream); + + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error saving: {}", e.what()); + } + const std::string& str{sstream.str()}; + auto buffer = Common::Compression::CompressDataZSTDDefault( + reinterpret_cast<const u8*>(str.data()), str.size()); + + const auto path = GetSaveStatePath(title_id, slot); + if (!FileUtil::CreateFullPath(path)) { + LOG_ERROR(Core, "Could not create path {}", path); + return; + } + + FileUtil::IOFile file(path, "wb"); + if (!file) { + LOG_ERROR(Core, "Could not open file {}", path); + return; + } + + CSTHeader header{}; + header.filetype = header_magic_bytes; + header.program_id = title_id; + std::string rev_bytes; + CryptoPP::StringSource(Common::g_scm_rev, true, + new CryptoPP::HexDecoder(new CryptoPP::StringSink(rev_bytes))); + std::memcpy(header.revision.data(), rev_bytes.data(), sizeof(header.revision)); + header.time = std::chrono::duration_cast<std::chrono::seconds>( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + + if (file.WriteBytes(&header, sizeof(header)) != sizeof(header)) { + LOG_ERROR(Core, "Could not write to file {}", path); + return; + } + if (file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { + LOG_ERROR(Core, "Could not write to file {}", path); + return; + } +} + +void System::LoadState(u32 slot) { + const auto path = GetSaveStatePath(title_id, slot); + if (!FileUtil::Exists(path)) { + LOG_ERROR(Core, "File not exist {}", path); + return; + } + + std::vector<u8> decompressed; + { + std::vector<u8> buffer(FileUtil::GetSize(path) - sizeof(CSTHeader)); + + FileUtil::IOFile file(path, "rb"); + if (!file) { + LOG_ERROR(Core, "Could not open file {}", path); + return; + } + file.Seek(sizeof(CSTHeader), SEEK_SET); // Skip header + if (file.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { + LOG_ERROR(Core, "Could not read from file {}", path); + return; + } + decompressed = Common::Compression::DecompressDataZSTD(buffer); + } + std::istringstream sstream{ + std::string{reinterpret_cast<char*>(decompressed.data()), decompressed.size()}, + std::ios_base::binary}; + decompressed.clear(); + + try { + + { + iarchive ia{sstream}; + ia&* this; + } + VideoCore::Load(sstream); + + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error loading: {}", e.what()); + } +} + +} // namespace Core diff --git a/src/core/savestate.h b/src/core/savestate.h new file mode 100644 index 000000000..f67bee22f --- /dev/null +++ b/src/core/savestate.h @@ -0,0 +1,27 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <vector> +#include "common/common_types.h" + +namespace Core { + +struct CSTHeader; + +struct SaveStateInfo { + u32 slot; + u64 time; + enum class ValidationStatus { + OK, + RevisionDismatch, + } status; +}; + +constexpr u32 SaveStateSlotCount = 10; // Maximum count of savestate slots + +std::vector<SaveStateInfo> ListSaveStates(u64 program_id); + +} // namespace Core From 56046136424be85c625cd622506c2aefee38d915 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 27 Mar 2020 21:48:58 +0000 Subject: [PATCH 082/129] More merge fixes --- TODO | 2 +- save0.citrasave | Bin 776 -> 0 bytes src/core/core.cpp | 6 ++++++ src/core/core_timing.h | 7 ++++--- src/core/file_sys/layered_fs.cpp | 16 +++++++++++---- src/core/file_sys/layered_fs.h | 32 +++++++++++++++++++++++++++++ src/core/file_sys/romfs_reader.cpp | 3 +++ src/core/file_sys/romfs_reader.h | 10 +++++++++ src/core/hle/service/cecd/cecd.h | 2 +- 9 files changed, 69 insertions(+), 9 deletions(-) delete mode 100644 save0.citrasave diff --git a/TODO b/TODO index 9cc333d46..41fa8503a 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,7 @@ ☐ Save/load UI ✔ Basic version @done(20-01-03 15:27) ☐ Multiple slots etc. -☐ Add 'force flush all' to Rasterizer interface + impls +✔ Add 'force flush all' to Rasterizer interface + impls @done(20-03-07 21:54) ☐ Custom texture cache ☐ Review constructor/initialization code ✔ Core timing events @done(20-01-12 15:14) diff --git a/save0.citrasave b/save0.citrasave deleted file mode 100644 index 578174ec6b7489150da4ff634caacf0e34d2ddd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 776 zcmWe*fPmuEqRhmc%&Nqa%=|nntHh$@jLfoBK?W8U77j+J8VJP<q}YHMBnrX-WeOZj zK>9?L0*8h?10RqH1|V?|<IY3{4i2FBml@d%1~ao61Q-|^UU$fY)qu>A17eUl4nX1q zlntb43brUPIsz>Kd4++2my6*Yh!z9_5UsL-A0!C@U@rjWfQ|zq29QTVfSFN%k%^f} zfI&eCB+MWP^p>C^gOH$rlAxiY0HY&Nw8DXvfgdC}gusXY|Nn!WyQGVg;ep2k7Zj)K z{eZ+8iXbT*ADCiTFv9qtbN~VcxmJk<1>lfo1CtP8ILQfOfdU*DXW(!L6CgooJb{=H X09FNMLyV0NPAw`+ErKZk({Muob(AbM diff --git a/src/core/core.cpp b/src/core/core.cpp index fea1705ed..ca2299920 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -530,6 +530,9 @@ void System::Reset() { template <class Archive> void System::serialize(Archive& ar, const unsigned int file_version) { u32 num_cores; + if (Archive::is_saving::value) { + num_cores = this->GetNumCores(); + } ar& num_cores; if (num_cores != this->GetNumCores()) { throw std::runtime_error("Wrong N3DS mode"); @@ -547,6 +550,9 @@ void System::serialize(Archive& ar, const unsigned int file_version) { if (Archive::is_loading::value) { dsp_core.reset(); } + if (dsp_core) { + throw "BLEH"; + } ar& dsp_core; ar&* memory.get(); ar&* kernel.get(); diff --git a/src/core/core_timing.h b/src/core/core_timing.h index a56a9097d..4e11b7bd2 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -223,10 +223,12 @@ public: template <class Archive> void serialize(Archive& ar, const unsigned int) { MoveEvents(); - ar& slice_length; - ar& downcount; + // NOTE: ts_queue should be empty now ar& event_queue; ar& event_fifo_id; + ar& slice_length; + ar& downcount; + ar& executed_ticks; ar& idled_cycles; } friend class boost::serialization::access; @@ -283,7 +285,6 @@ private: deserializing = nullptr; } friend class boost::serialization::access; - }; } // namespace Core diff --git a/src/core/file_sys/layered_fs.cpp b/src/core/file_sys/layered_fs.cpp index 9d5fbf7c2..c8af6b5b0 100644 --- a/src/core/file_sys/layered_fs.cpp +++ b/src/core/file_sys/layered_fs.cpp @@ -5,6 +5,7 @@ #include <algorithm> #include <cstring> #include "common/alignment.h" +#include "common/archives.h" #include "common/assert.h" #include "common/common_paths.h" #include "common/file_util.h" @@ -13,6 +14,8 @@ #include "core/file_sys/layered_fs.h" #include "core/file_sys/patch.h" +SERIALIZE_EXPORT_IMPL(FileSys::LayeredFS) + namespace FileSys { struct FileRelocationInfo { @@ -51,11 +54,16 @@ struct FileMetadata { }; static_assert(sizeof(FileMetadata) == 0x20, "Size of FileMetadata is not correct"); -LayeredFS::LayeredFS(std::shared_ptr<RomFSReader> romfs_, std::string patch_path_, - std::string patch_ext_path_, bool load_relocations) - : romfs(std::move(romfs_)), patch_path(std::move(patch_path_)), - patch_ext_path(std::move(patch_ext_path_)) { +LayeredFS::LayeredFS() = default; +LayeredFS::LayeredFS(std::shared_ptr<RomFSReader> romfs_, std::string patch_path_, + std::string patch_ext_path_, bool load_relocations_) + : romfs(std::move(romfs_)), patch_path(std::move(patch_path_)), + patch_ext_path(std::move(patch_ext_path_)), load_relocations(load_relocations_) { + Load(); +} + +void LayeredFS::Load() { romfs->ReadFile(0, sizeof(header), reinterpret_cast<u8*>(&header)); ASSERT_MSG(header.header_length == sizeof(header), "Header size is incorrect"); diff --git a/src/core/file_sys/layered_fs.h b/src/core/file_sys/layered_fs.h index 956eedcfa..dc71d052f 100644 --- a/src/core/file_sys/layered_fs.h +++ b/src/core/file_sys/layered_fs.h @@ -9,6 +9,10 @@ #include <string> #include <unordered_map> #include <vector> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/export.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "common/swap.h" #include "core/file_sys/romfs_reader.h" @@ -19,6 +23,14 @@ struct RomFSHeader { struct Descriptor { u32_le offset; u32_le length; + + private: + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& offset; + ar& length; + } + friend class boost::serialization::access; }; u32_le header_length; Descriptor directory_hash_table; @@ -92,9 +104,12 @@ private: void RebuildMetadata(); + void Load(); + std::shared_ptr<RomFSReader> romfs; std::string patch_path; std::string patch_ext_path; + bool load_relocations; RomFSHeader header; Directory root; @@ -118,6 +133,23 @@ private: u64 current_file_offset{}; // current file metadata offset std::vector<u8> file_metadata_table; // rebuilt file metadata table u64 current_data_offset{}; // current assigned data offset + + LayeredFS(); + + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object<RomFSReader>(*this); + ar& romfs; + ar& patch_path; + ar& patch_ext_path; + ar& load_relocations; + if (Archive::is_loading::value) { + Load(); + } + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::LayeredFS) diff --git a/src/core/file_sys/romfs_reader.cpp b/src/core/file_sys/romfs_reader.cpp index 64374684a..a1ff38945 100644 --- a/src/core/file_sys/romfs_reader.cpp +++ b/src/core/file_sys/romfs_reader.cpp @@ -1,8 +1,11 @@ #include <algorithm> #include <cryptopp/aes.h> #include <cryptopp/modes.h> +#include "common/archives.h" #include "core/file_sys/romfs_reader.h" +SERIALIZE_EXPORT_IMPL(FileSys::DirectRomFSReader) + namespace FileSys { std::size_t DirectRomFSReader::ReadFile(std::size_t offset, std::size_t length, u8* buffer) { diff --git a/src/core/file_sys/romfs_reader.h b/src/core/file_sys/romfs_reader.h index 1cfaa3b4f..26dcb9857 100644 --- a/src/core/file_sys/romfs_reader.h +++ b/src/core/file_sys/romfs_reader.h @@ -2,6 +2,8 @@ #include <array> #include <boost/serialization/array.hpp> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/export.hpp> #include "common/common_types.h" #include "common/file_util.h" @@ -16,6 +18,11 @@ public: virtual std::size_t GetSize() const = 0; virtual std::size_t ReadFile(std::size_t offset, std::size_t length, u8* buffer) = 0; + +private: + template <class Archive> + void serialize(Archive& ar, const unsigned int file_version) {} + friend class boost::serialization::access; }; /** @@ -54,6 +61,7 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object<RomFSReader>(*this); ar& is_encrypted; ar& file; ar& key; @@ -66,3 +74,5 @@ private: }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::DirectRomFSReader) diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 0870f31bf..b752701fe 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -258,7 +258,7 @@ public: ar& data_path_type; ar& open_mode.raw; ar& path; - ar& file; + // ar& file; } friend class boost::serialization::access; }; From 3d1180ee21603392c32b4d610b6e866a1af0d262 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 27 Mar 2020 22:19:29 +0000 Subject: [PATCH 083/129] DSP now works... committing this!! --- src/audio_core/dsp_interface.cpp | 7 ++++++- src/audio_core/hle/hle.cpp | 11 ++++++++++- src/core/core.cpp | 11 ++++------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/audio_core/dsp_interface.cpp b/src/audio_core/dsp_interface.cpp index b6e74b82c..fc2e231f2 100644 --- a/src/audio_core/dsp_interface.cpp +++ b/src/audio_core/dsp_interface.cpp @@ -1,3 +1,4 @@ +#pragma optimize("", off) // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -14,7 +15,11 @@ namespace AudioCore { DspInterface::DspInterface() = default; -DspInterface::~DspInterface() = default; +DspInterface::~DspInterface() { + LOG_WARNING(Audio_DSP, "c1"); + sink.reset(); + LOG_WARNING(Audio_DSP, "c2"); +} void DspInterface::SetSink(const std::string& sink_id, const std::string& audio_device) { sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id); diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index 87af17ba7..cac8a7df5 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -16,6 +16,7 @@ #elif HAVE_FDK #include "audio_core/hle/fdk_decoder.h" #endif +#include <iostream> #include "audio_core/hle/common.h" #include "audio_core/hle/decoder.h" #include "audio_core/hle/hle.h" @@ -148,8 +149,11 @@ DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(paren } DspHle::Impl::~Impl() { + LOG_WARNING(Audio_DSP, "b1"); Core::Timing& timing = Core::System::GetInstance().CoreTiming(); + LOG_WARNING(Audio_DSP, "b2"); timing.UnscheduleEvent(tick_event, 0); + LOG_WARNING(Audio_DSP, "b3"); } DspState DspHle::Impl::GetDspState() const { @@ -448,7 +452,12 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) { } DspHle::DspHle(Memory::MemorySystem& memory) : impl(std::make_unique<Impl>(*this, memory)) {} -DspHle::~DspHle() = default; +DspHle::~DspHle() { + + LOG_WARNING(Audio_DSP, "a1"); + impl.reset(); + LOG_WARNING(Audio_DSP, "a2"); +} u16 DspHle::RecvData(u32 register_number) { return impl->RecvData(register_number); diff --git a/src/core/core.cpp b/src/core/core.cpp index ca2299920..1c18af202 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -547,13 +547,10 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* service_manager.get(); ar& GPU::g_regs; ar& LCD::g_regs; - if (Archive::is_loading::value) { - dsp_core.reset(); + if (!dynamic_cast<AudioCore::DspHle*>(dsp_core.get())) { + throw std::runtime_error("Only HLE audio supported"); } - if (dsp_core) { - throw "BLEH"; - } - ar& dsp_core; + ar&* dynamic_cast<AudioCore::DspHle*>(dsp_core.get()); ar&* memory.get(); ar&* kernel.get(); @@ -562,7 +559,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { Service::GSP::SetGlobalModule(*this); memory->SetDSP(*dsp_core); - dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id); + // dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id); dsp_core->EnableStretching(Settings::values.enable_audio_stretching); } } From 232b52a27d6d633f8cbed7111310d7aeb82469af Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 09:59:45 +0000 Subject: [PATCH 084/129] Minor cleanup --- src/audio_core/dsp_interface.cpp | 7 +------ src/audio_core/hle/hle.cpp | 11 +--------- src/core/core.cpp | 35 ++++++++++++++++++++------------ src/core/file_sys/layered_fs.cpp | 8 ++++---- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/audio_core/dsp_interface.cpp b/src/audio_core/dsp_interface.cpp index fc2e231f2..b6e74b82c 100644 --- a/src/audio_core/dsp_interface.cpp +++ b/src/audio_core/dsp_interface.cpp @@ -1,4 +1,3 @@ -#pragma optimize("", off) // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -15,11 +14,7 @@ namespace AudioCore { DspInterface::DspInterface() = default; -DspInterface::~DspInterface() { - LOG_WARNING(Audio_DSP, "c1"); - sink.reset(); - LOG_WARNING(Audio_DSP, "c2"); -} +DspInterface::~DspInterface() = default; void DspInterface::SetSink(const std::string& sink_id, const std::string& audio_device) { sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id); diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index cac8a7df5..6f54b75e6 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -1,4 +1,3 @@ -#pragma optimize("", off) // Copyright 2017 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -149,11 +148,8 @@ DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(paren } DspHle::Impl::~Impl() { - LOG_WARNING(Audio_DSP, "b1"); Core::Timing& timing = Core::System::GetInstance().CoreTiming(); - LOG_WARNING(Audio_DSP, "b2"); timing.UnscheduleEvent(tick_event, 0); - LOG_WARNING(Audio_DSP, "b3"); } DspState DspHle::Impl::GetDspState() const { @@ -452,12 +448,7 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) { } DspHle::DspHle(Memory::MemorySystem& memory) : impl(std::make_unique<Impl>(*this, memory)) {} -DspHle::~DspHle() { - - LOG_WARNING(Audio_DSP, "a1"); - impl.reset(); - LOG_WARNING(Audio_DSP, "a2"); -} +DspHle::~DspHle() = default; u16 DspHle::RecvData(u32 register_number) { return impl->RecvData(register_number); diff --git a/src/core/core.cpp b/src/core/core.cpp index 1c18af202..db9fa83c7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,4 +1,3 @@ -#pragma optimize("", off) // Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -313,7 +312,7 @@ void System::Reschedule() { System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mode, u8 n3ds_mode) { LOG_DEBUG(HW_Memory, "initialized OK"); - std::size_t num_cores = 2; + u32 num_cores = 2; if (Settings::values.is_new_3ds) { num_cores = 4; } @@ -327,19 +326,19 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo if (Settings::values.use_cpu_jit) { #ifdef ARCHITECTURE_x86_64 - for (std::size_t i = 0; i < num_cores; ++i) { + for (u32 i = 0; i < num_cores; ++i) { cpu_cores.push_back( std::make_shared<ARM_Dynarmic>(this, *memory, USER32MODE, i, timing->GetTimer(i))); } #else - for (std::size_t i = 0; i < num_cores; ++i) { + for (u32 i = 0; i < num_cores; ++i) { cpu_cores.push_back( std::make_shared<ARM_DynCom>(this, *memory, USER32MODE, i, timing->GetTimer(i))); } LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); #endif } else { - for (std::size_t i = 0; i < num_cores; ++i) { + for (u32 i = 0; i < num_cores; ++i) { cpu_cores.push_back( std::make_shared<ARM_DynCom>(this, *memory, USER32MODE, i, timing->GetTimer(i))); } @@ -541,26 +540,36 @@ void System::serialize(Archive& ar, const unsigned int file_version) { bool should_flush = !Archive::is_loading::value; Memory::RasterizerClearAll(should_flush); ar&* timing.get(); - for (int i = 0; i < num_cores; i++) { + for (u32 i = 0; i < num_cores; i++) { ar&* cpu_cores[i].get(); } ar&* service_manager.get(); ar& GPU::g_regs; ar& LCD::g_regs; - if (!dynamic_cast<AudioCore::DspHle*>(dsp_core.get())) { - throw std::runtime_error("Only HLE audio supported"); + + // NOTE: DSP doesn't like being destroyed and recreated. So instead we do an inline + // serialization; this means that the DSP Settings need to match for loading to work. + bool dsp_type = Settings::values.enable_dsp_lle; + ar& dsp_type; + if (dsp_type != Settings::values.enable_dsp_lle) { + throw std::runtime_error( + "Incorrect DSP type - please change this in Settings before loading"); } - ar&* dynamic_cast<AudioCore::DspHle*>(dsp_core.get()); + auto dsp_hle = dynamic_cast<AudioCore::DspHle*>(dsp_core.get()); + if (dsp_hle) { + ar&* dsp_hle; + } + auto dsp_lle = dynamic_cast<AudioCore::DspLle*>(dsp_core.get()); + if (dsp_lle) { + ar&* dsp_lle; + } + ar&* memory.get(); ar&* kernel.get(); // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); - - memory->SetDSP(*dsp_core); - // dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id); - dsp_core->EnableStretching(Settings::values.enable_audio_stretching); } } diff --git a/src/core/file_sys/layered_fs.cpp b/src/core/file_sys/layered_fs.cpp index c8af6b5b0..a4ef57baf 100644 --- a/src/core/file_sys/layered_fs.cpp +++ b/src/core/file_sys/layered_fs.cpp @@ -281,7 +281,7 @@ std::size_t GetNameSize(const std::string& name) { } void LayeredFS::PrepareBuildDirectory(Directory& current) { - directory_metadata_offset_map.emplace(¤t, current_directory_offset); + directory_metadata_offset_map.emplace(¤t, static_cast<u32>(current_directory_offset)); directory_list.emplace_back(¤t); current_directory_offset += sizeof(DirectoryMetadata) + GetNameSize(current.name); } @@ -290,7 +290,7 @@ void LayeredFS::PrepareBuildFile(File& current) { if (current.relocation.type == 3) { // Deleted files are not counted return; } - file_metadata_offset_map.emplace(¤t, current_file_offset); + file_metadata_offset_map.emplace(¤t, static_cast<u32>(current_file_offset)); file_list.emplace_back(¤t); current_file_offset += sizeof(FileMetadata) + GetNameSize(current.name); } @@ -369,7 +369,7 @@ void LayeredFS::BuildDirectories() { // Write metadata and name std::u16string u16name = Common::UTF8ToUTF16(directory->name); - metadata.name_length = u16name.size() * 2; + metadata.name_length = static_cast<u32_le>(u16name.size() * 2); std::memcpy(directory_metadata_table.data() + written, &metadata, sizeof(metadata)); written += sizeof(metadata); @@ -418,7 +418,7 @@ void LayeredFS::BuildFiles() { // Write metadata and name std::u16string u16name = Common::UTF8ToUTF16(file->name); - metadata.name_length = u16name.size() * 2; + metadata.name_length = static_cast<u32_le>(u16name.size() * 2); std::memcpy(file_metadata_table.data() + written, &metadata, sizeof(metadata)); written += sizeof(metadata); From 5a6093843e63fb9a271b8f04ca5be9e95ab92ee3 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 12:04:00 +0000 Subject: [PATCH 085/129] Remove the TODO (since it's all done now!) --- TODO | 143 ----------------------------------------------------------- 1 file changed, 143 deletions(-) delete mode 100644 TODO diff --git a/TODO b/TODO deleted file mode 100644 index 41fa8503a..000000000 --- a/TODO +++ /dev/null @@ -1,143 +0,0 @@ -☐ Save/load UI - ✔ Basic version @done(20-01-03 15:27) - ☐ Multiple slots etc. -✔ Add 'force flush all' to Rasterizer interface + impls @done(20-03-07 21:54) -☐ Custom texture cache -☐ Review constructor/initialization code -✔ Core timing events @done(20-01-12 15:14) -☐ Serialize codeset with an apploader reference instead -✔ Review base class serialization everywhere @done(20-01-10 23:47) - Make sure that all base/derived relationships are registered -✔ Additional stuff to serialize @done(20-01-11 16:32) - ✔ Self-NCCH archive @done(20-01-11 16:32) - ✔ File backends @done(20-01-11 16:32) - ✘ Directory backends @cancelled(20-01-11 16:32) - Not needed for now - ✔ File/directory 'services' @done(20-01-10 23:46) -✔ CPU @done(19-08-13 15:41) -✔ Memory @done(19-08-13 15:41) - ✔ Page tables @done(20-01-05 16:33) - Need to change uses to shared_ptr - ✔ Skip N3DS RAM if unused @done(20-01-03 23:26) -✔ DSP @done(19-12-28 16:57) - Memory only -✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) - ✔ Fix or ignore inverse map @done(19-12-23 12:46) -✘ App loader @cancelled(20-01-01 22:59) - No relevant state -✔ Archive manager @started(20-01-01 23:03) @done(20-01-03 13:23) @lasted(1d14h20m40s) - NB that 'FileBackend' classes are not persistent - ✔ NCCH @started(20-01-02 22:50) @done(20-01-03 12:35) @lasted(13h45m50s) - ✔ Normal @done(20-01-02 22:50) - ✔ Self @done(20-01-03 12:35) - ✔ SaveData @started(20-01-02 23:03) @done(20-01-02 23:27) @lasted(25m) - ✔ Normal @done(20-01-02 23:03) - ✔ Ext @done(20-01-02 23:26) - ✔ Other @done(20-01-02 23:21) - ✔ Source SD @done(20-01-02 23:03) - ✔ System @done(20-01-02 23:13) - ✔ SDMC @done(20-01-02 23:34) - ✔ Normal @done(20-01-02 23:34) - ✔ Write-only @done(20-01-02 23:34) - ✔ IVFC @done(20-01-11 16:33) - ✔ File refs @done(20-01-11 16:33) - ✘ Replace delay generator with virtual fns @cancelled(20-01-03 13:16) - While they have no state, the extra refactoring here is unneeded -✘ MMIO @cancelled(20-01-01 01:06) - Seems that this whole subsystem is only used in tests -✘ Movie @cancelled(20-01-01 01:07) - Doesn't need to be serialized here -✘ Perf stats @cancelled(20-01-01 01:09) - Doesn't need to be serialized here -✘ Settings @cancelled(20-01-01 01:11) - For now, let the settings just be whatever they are -✘ Telemetry session @cancelled(20-01-01 01:12) - Doesn't need to be serialized here -✔ Replace SERIALIZE_AS_POD with BOOST_IS_BITWISE_SERIALIZABLE @started(20-01-03 13:47) @done(20-01-03 13:58) @lasted(11m22s) -✔ Fix CI @done(19-12-31 21:32) -✔ HW @done(19-08-13 15:41) - ✔ GPU regs @done(19-08-13 15:41) - ✔ LCD regs @done(19-08-13 15:41) -✔ Video core @started(19-08-13 16:43) @done(19-12-22 16:06) - ✔ Geometry pipeline @done(19-12-22 15:52) - Required more use of g_state - ✔ PICA state @done(19-08-13 15:41) - ✔ Primitive assembly @done(19-12-22 16:05) - ✔ Shader @done(19-08-13 16:03) -✔ HLE @started(19-08-13 16:43) @done(20-01-06 20:37) @lasted(20w6d4h54m19s) - ✔ Kernel @started(19-08-13 16:43) @done(20-01-06 20:37) @lasted(20w6d4h54m17s) - Most of these require adding Core::Global - ✔ Address arbiter @done(19-08-13 16:40) - ✔ Client port @done(19-08-13 16:40) - ✔ Client session @done(19-08-13 16:40) - ✔ Config mem @done(20-01-04 21:09) - ✔ Event @done(19-12-22 18:44) - ✔ Handle table @done(19-08-13 16:42) - ✔ HLE IPC @done(19-12-23 00:36) - ✔ IPC @done(19-12-23 00:36) - ✔ Memory @started(19-08-13 16:43) @done(19-12-22 18:34) - ✔ Mutex @done(19-08-13 16:43) - ✔ Object @done(19-08-13 15:41) - ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) - ✔ Code set @started(19-12-22 18:41) @done(20-01-03 15:15) @lasted(1w4d20h34m2s) - Needs a way to reference loaded images (so we don't serialize the entire ROM as well) - ✔ Resource limit @done(19-08-13 16:43) - ✔ Semaphore @done(19-08-13 16:44) - ✔ Server port @done(19-08-13 16:44) - ✔ Server session @done(19-08-13 16:44) - ✔ Mapped buffer context @done(20-01-03 15:25) - This is needed because IPC can take as long as it takes - Changed the unique_ptr<u8[]> to vector<u8> - ✔ Session @done(19-08-13 16:44) - ✔ Shared memory @started(19-12-22 21:20) @done(20-01-04 21:09) @lasted(1w5d23h49m26s) - Need to figure out backing memory (a u8*) - ✔ Shared page @done(20-01-04 21:09) - ✔ SVC @done(19-12-22 21:32) - Nothing to do - all data is constant - ✔ Thread @started(19-08-13 16:45) @done(20-01-06 20:01) @lasted(20w6d4h16m22s) - This requires refactoring wakeup_callback to be an object ref - ✔ Timer @done(19-08-13 16:45) - ✔ VM Manager @started(19-08-13 16:46) @done(20-01-04 21:09) @lasted(20w4d5h23m42s) - Just need to figure out backing_mem (a u8*) - ✔ Wait object @done(19-08-13 16:46) - ✔ Service @started(19-12-23 12:49) @done(20-01-05 16:41) @lasted(1w6d3h52m17s) - ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) - ✔ ACT @done(19-12-24 23:17) - ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) - ✔ APT @done(19-12-25 21:41) - ✔ BOSS @started(19-12-25 21:48) @done(19-12-25 23:18) @lasted(1h30m14s) - ✔ CAM @started(19-12-26 10:37) @done(20-01-03 23:38) @lasted(1w1d13h1m50s) - Need to check capture_result - ✔ CECD @done(20-01-01 23:58) - ✔ CFG @done(20-01-02 00:44) - Also needs archive backend.. - ✔ CSND @started(19-12-26 17:51) @done(19-12-26 17:56) @lasted(5m30s) - ✔ DLP @done(19-12-26 18:02) - ✔ DSP @done(19-12-26 18:10) - ✔ ERR @done(19-12-26 18:14) - ✔ FRD @done(19-12-26 19:09) - ✔ FS @done(19-12-27 11:46) - ✔ GSP @done(19-12-30 12:45) - ✔ Fix the global weak_ptr to gsp @done(20-01-04 00:29) - Didn't quite 'fix' it but worked around it - ✔ HID @done(19-12-30 14:46) - ✔ HTTP @done(19-12-30 15:18) - ✔ IR @done(19-12-30 16:06) - ✔ LDR_RO @done(19-12-30 16:25) - ✔ MIC @done(19-12-30 16:53) - ✔ MVD @done(19-12-31 18:26) - ✔ NDM @done(19-12-31 18:26) - ✔ NEWS @done(19-12-31 18:29) - ✔ NFC @done(19-12-31 20:35) - ✔ NIM @done(19-12-31 21:08) - ✔ NS @done(20-01-01 00:46) - ✔ NWM @done(20-01-01 21:31) - ✔ Fix wifi_packet_received @done(20-01-05 16:41) - ✔ PM @done(20-01-01 22:14) - ✔ PS @done(20-01-01 00:54) - ✔ PTM @done(20-01-01 22:36) - ✔ PXI @done(20-01-01 00:53) - ✔ QTM @done(20-01-01 22:41) - ✔ SOC @done(20-01-01 00:51) - ✔ SSL @done(20-01-01 00:48) - ✔ Y2R @done(20-01-01 22:56) \ No newline at end of file From 025960bcdd486f9747dd25cefa89ff014b414b27 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 15:10:35 +0000 Subject: [PATCH 086/129] Attempt to fix flatpak CI --- .travis/linux-flatpak/generate-data.sh | 2 +- externals/boost | 2 +- src/audio_core/hle/hle.cpp | 1 - src/core/hle/kernel/process.cpp | 5 ++--- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.travis/linux-flatpak/generate-data.sh b/.travis/linux-flatpak/generate-data.sh index aaecd0500..799f0f1b8 100644 --- a/.travis/linux-flatpak/generate-data.sh +++ b/.travis/linux-flatpak/generate-data.sh @@ -43,7 +43,7 @@ cat > /tmp/org.citra.$REPO_NAME.json <<EOF { "app-id": "org.citra.$REPO_NAME", "runtime": "org.kde.Platform", - "runtime-version": "5.12", + "runtime-version": "5.13", "sdk": "org.kde.Sdk", "command": "citra-qt", "rename-desktop-file": "citra.desktop", diff --git a/externals/boost b/externals/boost index 727f616b6..a37867de9 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit 727f616b6e5cafaba072131c077a3b8fea87b8be +Subproject commit a37867de91767e3289068997bc004f842894ce1f diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index 6ced77481..f4e372f85 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -17,7 +17,6 @@ #elif HAVE_FDK #include "audio_core/hle/fdk_decoder.h" #endif -#include <iostream> #include "audio_core/hle/common.h" #include "audio_core/hle/decoder.h" #include "audio_core/hle/hle.h" diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index ea3449c21..b72081ad5 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -33,9 +33,8 @@ void Process::serialize(Archive& ar, const unsigned int file_version) { ar& resource_limit; ar& svc_access_mask; ar& handle_table_size; - ar&(boost::container::vector< - AddressMapping, boost::container::dtl::static_storage_allocator<AddressMapping, 8>>&) - address_mappings; + ar&(boost::container::vector<AddressMapping, boost::container::dtl::static_storage_allocator< + AddressMapping, 8, 0, true>>&)address_mappings; ar& flags.raw; ar& kernel_version; ar& ideal_processor; From 917d651a3c1be4b99a20ad1a2ad193d2ba1251c7 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 15:21:10 +0000 Subject: [PATCH 087/129] Added copyright notices on new files --- src/common/archives.h | 6 ++++++ src/common/construct.h | 5 +++++ src/common/memory_ref.cpp | 4 ++++ src/common/memory_ref.h | 4 ++++ src/core/global.h | 6 ++++++ 5 files changed, 25 insertions(+) diff --git a/src/common/archives.h b/src/common/archives.h index eef292634..993128197 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -1,3 +1,9 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + #include "boost/archive/binary_iarchive.hpp" #include "boost/archive/binary_oarchive.hpp" #include "boost/serialization/export.hpp" diff --git a/src/common/construct.h b/src/common/construct.h index aba4c7e89..4e48ee60d 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -1,4 +1,9 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once + #include <boost/serialization/serialization.hpp> class construct_access { diff --git a/src/common/memory_ref.cpp b/src/common/memory_ref.cpp index 170784ff8..300f87d58 100644 --- a/src/common/memory_ref.cpp +++ b/src/common/memory_ref.cpp @@ -1,3 +1,7 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include "common/archives.h" #include "common/memory_ref.h" diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index ae30b009c..c11beb04d 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -1,3 +1,7 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once #include <memory> diff --git a/src/core/global.h b/src/core/global.h index d2e1cd97d..83bd4fc80 100644 --- a/src/core/global.h +++ b/src/core/global.h @@ -1,3 +1,9 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + namespace Core { template <class T> From 4aab38f133c2a039eb1d619b896c5eaff76cf939 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 15:47:36 +0000 Subject: [PATCH 088/129] Refactored out the horrible static var in CoreTiming --- src/core/core.cpp | 5 +++++ src/core/core_timing.cpp | 2 -- src/core/core_timing.h | 7 ++----- src/core/file_sys/archive_backend.h | 2 +- src/core/file_sys/archive_ncch.h | 4 ++-- src/core/global.h | 6 +++++- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 65c73f03b..ff6da91e7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -61,6 +61,11 @@ Kernel::KernelSystem& Global() { return System::GetInstance().Kernel(); } +template <> +Core::Timing& Global() { + return System::GetInstance().CoreTiming(); +} + System::~System() = default; System::ResultStatus System::RunLoop(bool tight_loop) { diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 67fab0dae..493bb6344 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -11,8 +11,6 @@ namespace Core { -Timing* Timing::deserializing = nullptr; - // Sort by time, unless the times are the same, in which case sort by the order added to the queue bool Timing::Event::operator>(const Timing::Event& right) const { return std::tie(time, fifo_order) > std::tie(right.time, right.fifo_order); diff --git a/src/core/core_timing.h b/src/core/core_timing.h index cbe17b36b..bb34c79b0 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -28,6 +28,7 @@ #include "common/common_types.h" #include "common/logging/log.h" #include "common/threadsafe_queue.h" +#include "core/global.h" // The timing we get from the assembly is 268,111,855.956 Hz // It is possible that this number isn't just an integer because the compiler could have @@ -135,8 +136,6 @@ struct TimingEventType { }; class Timing { -private: - static Timing* deserializing; public: struct Event { @@ -165,7 +164,7 @@ public: ar& userdata; std::string name; ar >> name; - type = Timing::deserializing->RegisterEvent(name, nullptr); + type = Global<Timing>().RegisterEvent(name, nullptr); } friend class boost::serialization::access; @@ -291,11 +290,9 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { // event_types set during initialization of other things - deserializing = this; ar& global_timer; ar& timers; ar& current_timer; - deserializing = nullptr; } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 6468c0630..658e6f20c 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -196,7 +196,7 @@ public: } protected: - std::unique_ptr<DelayGenerator> delay_generator; // TODO: Replace with virtual GetOpenDelayNs + std::unique_ptr<DelayGenerator> delay_generator; private: template <class Archive> diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 2d38f9a2e..76b8d4655 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -68,8 +68,8 @@ protected: Service::FS::MediaType media_type; private: - NCCHArchive() = default; // NOTE: If the public ctor has behaviour, need to replace this with - // *_construct_data + NCCHArchive() = default; + template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<ArchiveBackend>(*this); diff --git a/src/core/global.h b/src/core/global.h index 83bd4fc80..794d71f94 100644 --- a/src/core/global.h +++ b/src/core/global.h @@ -9,9 +9,13 @@ namespace Core { template <class T> T& Global(); -// Declare explicit specialisation to prevent im +// Declare explicit specialisation to prevent automatic instantiation class System; template <> System& Global(); +class Timing; +template <> +Timing& Global(); + } // namespace Core From bbf8e876ab9dfed345968c550ca44cf39237f2c1 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 16:26:24 +0000 Subject: [PATCH 089/129] Apply suggestions from code review Co-Authored-By: Pengfei Zhu <zhupf321@gmail.com> --- src/video_core/pica_state.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 4e5a5f16b..1879528cb 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -5,7 +5,7 @@ #pragma once #include <array> -#include "boost/serialization/split_member.hpp" +#include <boost/serialization/split_member.hpp> #include "common/bit_field.h" #include "common/common_types.h" #include "common/vector_math.h" @@ -239,7 +239,7 @@ private: void load(Archive& ar, const unsigned int file_version) { u32 offset{}; ar >> offset; - cmd_list.head_ptr = (u32*)VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr); + cmd_list.head_ptr = reinterpret_cast<u32*>(VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr)); cmd_list.current_ptr = cmd_list.head_ptr + offset; } }; From 26f936406235c3b215512f4eabf31465f5fe8e9b Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 16:28:07 +0000 Subject: [PATCH 090/129] Apply suggestions from code review Co-Authored-By: Ben <bene_thomas@web.de> --- src/common/memory_ref.h | 4 ++-- src/video_core/shader/shader.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index c11beb04d..f1a3286ab 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -31,11 +31,11 @@ public: BufferMem() = default; BufferMem(u32 size) : data(std::vector<u8>(size)) {} - virtual u8* GetPtr() { + u8* GetPtr() override { return data.data(); } - virtual u32 GetSize() const { + u32 GetSize() const override { return static_cast<u32>(data.size()); } diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 6a5a33419..05a1e8b80 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -70,6 +70,7 @@ private: void serialize(Archive& ar, const unsigned int) { ar& pos; ar& quat; + ar& color; ar& tc0; ar& tc1; ar& tc0_w; From d92b3e9754f635ed956fa11a769f29dab704a388 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 16:29:15 +0000 Subject: [PATCH 091/129] Code review changes - clarified HTTP serialization --- src/core/hle/service/http_c.h | 27 +++++++++------------------ src/core/hle/service/mic_u.cpp | 2 ++ src/video_core/primitive_assembly.h | 4 +--- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h index d94b47a45..490e06648 100644 --- a/src/core/hle/service/http_c.h +++ b/src/core/hle/service/http_c.h @@ -6,6 +6,7 @@ #include <future> #include <memory> +#include <optional> #include <string> #include <unordered_map> #include <vector> @@ -215,24 +216,6 @@ public: #ifdef ENABLE_WEB_SERVICE httplib::Response response; #endif - -private: - template <class Archive> - void serialize(Archive& ar, const unsigned int) { - ar& handle; - ar& session_id; - ar& url; - ar& method; - ar& state; - ar& proxy; - ar& basic_auth; - ar& ssl_config; - ar& socket_buffer_size; - ar& headers; - ar& post_data; - } - friend class boost::serialization::access; - }; struct SessionData : public Kernel::SessionRequestHandler::SessionDataBase { @@ -453,10 +436,18 @@ private: private: template <class Archive> void serialize(Archive& ar, const unsigned int) { + // NOTE: Serialization of the HTTP service is on a 'best effort' basis. + // There is a very good chance that saving/loading during a network connection will break, + // regardless! ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this); ar& ClCertA.certificate; ar& ClCertA.private_key; ar& ClCertA.init; + ar& context_counter; + ar& client_certs_counter; + ar& client_certs; + // NOTE: `contexts` is not serialized because it contains non-serializable data. (i.e. + // handles to ongoing HTTP requests.) Serializing across HTTP contexts will break. } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index bd324ada2..08ef5473f 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -110,6 +110,7 @@ struct State { private: template <class Archive> void serialize(Archive& ar, const unsigned int) { + ar& memory_ref; ar& sharedmem_size; ar& size; ar& offset; @@ -139,6 +140,7 @@ struct MIC_U::Impl { if (shared_memory) { shared_memory->SetName("MIC_U:shared_memory"); + state.memory_ref = shared_memory; state.sharedmem_buffer = shared_memory->GetPointer(); state.sharedmem_size = size; } diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index d6547dddd..404bc5316 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h @@ -5,10 +5,8 @@ #pragma once #include <functional> +#include <boost/serialization/access.hpp> #include "video_core/regs_pipeline.h" -namespace boost::serialization { -class access; -} namespace Pica { From 8f164a16ce9c7b2def438bf998e631c035679f2a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 17:08:27 +0000 Subject: [PATCH 092/129] Review changes --- CMakeLists.txt | 1 + externals/CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- src/citra_qt/main.cpp | 2 +- src/core/core.cpp | 7 +------ src/core/file_sys/archive_ncch.h | 2 +- src/core/file_sys/archive_other_savedata.h | 2 -- src/core/file_sys/archive_savedata.h | 1 - src/core/file_sys/archive_selfncch.h | 4 ++-- src/core/hle/kernel/config_mem.h | 4 ++-- src/core/hle/kernel/hle_ipc.h | 2 +- src/core/hle/service/err_f.cpp | 3 ++- 12 files changed, 13 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index faa41ea54..315bc237d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ # CMake 3.8 required for 17 to be a valid value for CXX_STANDARD cmake_minimum_required(VERSION 3.8) if (${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.15) + # Don't override the warning flags in MSVC: cmake_policy(SET CMP0092 NEW) endif () list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 49cca86a1..7d687a4dc 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -1,7 +1,7 @@ # Definitions for all external bundled libraries # Suppress warnings from external libraries -if (CMAKE_C_COMPILER_ID MATCHES "MSVC") +if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") add_compile_options(/W0) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d46641570..38cd0be79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,7 +42,7 @@ if (MSVC) /Zc:externConstexpr /Zc:inline ) - if (CMAKE_C_COMPILER_ID MATCHES "MSVC") + if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") add_compile_options( /MP /Zc:throwingNew diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 6ceaea57d..a583e903a 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -1438,7 +1438,7 @@ void GMainWindow::OnCIAInstallFinished() { void GMainWindow::OnMenuRecentFile() { QAction* action = qobject_cast<QAction*>(sender()); - assert(action); + ASSERT(action); const QString filename = action->data().toString(); if (QFileInfo::exists(filename)) { diff --git a/src/core/core.cpp b/src/core/core.cpp index ff6da91e7..589744367 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -33,6 +33,7 @@ #include "core/hle/kernel/thread.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/gsp/gsp.h" +#include "core/hle/service/pm/pm_app.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" #include "core/hw/gpu.h" @@ -45,8 +46,6 @@ #include "network/network.h" #include "video_core/video_core.h" -#include "core/hle/service/pm/pm_app.h" - namespace Core { /*static*/ System System::s_instance; @@ -183,15 +182,11 @@ System::ResultStatus System::RunLoop(bool tight_loop) { case Signal::Load: { LOG_INFO(Core, "Begin load"); System::LoadState(param); - // auto stream = std::ifstream("save0.citrasave", std::fstream::binary); - // System::Load(stream, FileUtil::GetSize("save0.citrasave")); LOG_INFO(Core, "Load completed"); } break; case Signal::Save: { LOG_INFO(Core, "Begin save"); System::SaveState(param); - // auto stream = std::ofstream("save0.citrasave", std::fstream::binary); - // System::Save(stream); LOG_INFO(Core, "Save completed"); } break; default: diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 76b8d4655..95fe889ea 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -102,7 +102,7 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<FileBackend>(*this); - ar& file_buffer; // TODO: See about a more efficient way to do this + ar& file_buffer; } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index c5bf98a68..cc0cfe404 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -29,7 +29,6 @@ public: ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; // TODO: Remove, unused? std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; ArchiveFactory_OtherSaveDataPermitted() = default; @@ -57,7 +56,6 @@ public: ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; // TODO: Remove, unused? std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; ArchiveFactory_OtherSaveDataGeneral() = default; diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 6bb22f7a8..3f73adba3 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -28,7 +28,6 @@ public: ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override; private: - std::string mount_point; // TODO: Remove this? seems unused std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; ArchiveFactory_SaveData() = default; diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index d7b1cf301..68b48074f 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -58,12 +58,12 @@ public: private: /// Mapping of ProgramId -> NCCHData - std::unordered_map<u64, NCCHData> - ncch_data; // TODO: Remove this, or actually set the values here + std::unordered_map<u64, NCCHData> ncch_data; template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<ArchiveFactory>(*this); + // NOTE: ncch_data is never written to, so we don't serialize it here } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index 74d934345..c466345ec 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -57,11 +57,11 @@ public: Handler(); ConfigMemDef& GetConfigMem(); - virtual u8* GetPtr() { + u8* GetPtr() override { return static_cast<u8*>(static_cast<void*>(&config_mem)); } - virtual u32 GetSize() const { + u32 GetSize() const override { return sizeof(config_mem); } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 046a31e2e..000486825 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -99,12 +99,12 @@ protected: struct SessionInfo { SessionInfo(std::shared_ptr<ServerSession> session, std::unique_ptr<SessionDataBase> data); - SessionInfo() = default; std::shared_ptr<ServerSession> session; std::unique_ptr<SessionDataBase> data; private: + SessionInfo() = default; template <class Archive> void serialize(Archive& ar, const unsigned int file_version) { ar& session; diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index f88ffef19..85759f9d2 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -15,7 +15,8 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/result.h" #include "core/hle/service/err_f.h" -#undef exception_info +#undef exception_info // We use 'exception_info' as a plain identifier, but MSVC defines this in one + // of its many headers. SERIALIZE_EXPORT_IMPL(Service::ERR::ERR_F) From 570fc45d03173c4ad6217c817fd2e259ab756896 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 17:11:35 +0000 Subject: [PATCH 093/129] Change boost submodule --- .gitmodules | 2 +- externals/boost | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index b0bfcaee8..b247ccdbe 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "boost"] path = externals/boost - url = https://github.com/hamish-milne/ext-boost.git + url = https://github.com/citra-emu/ext-boost.git [submodule "nihstro"] path = externals/nihstro url = https://github.com/neobrain/nihstro.git diff --git a/externals/boost b/externals/boost index a37867de9..36603a1e6 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit a37867de91767e3289068997bc004f842894ce1f +Subproject commit 36603a1e665e849d29b1735a12c0a51284a10dd0 From 38e9eb379d97f8ba0914949a2e8c10b24c077840 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 17:23:54 +0000 Subject: [PATCH 094/129] Update src/CMakeLists.txt --- src/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 38cd0be79..96c7f35cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,7 +37,6 @@ if (MSVC) /Zo /permissive- /EHsc - /std:c++17 /volatile:iso /Zc:externConstexpr /Zc:inline From de9ae140593a67523c71fa3d66bfd02a89d532fb Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 19:29:29 +0000 Subject: [PATCH 095/129] Only serialize wchar paths on windows --- src/core/file_sys/archive_backend.h | 2 ++ src/core/hle/kernel/thread.cpp | 3 +-- src/video_core/pica_state.h | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 658e6f20c..87a42b028 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -77,6 +77,7 @@ private: case LowPathType::Char: ar& string; break; +#ifdef _WIN32 case LowPathType::Wchar: static_assert(sizeof(wchar_t) == sizeof(char16_t)); { @@ -87,6 +88,7 @@ private: } } break; +#endif default: break; } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 465ba46f5..0567ef325 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -63,8 +63,7 @@ void Thread::Acquire(Thread* thread) { } Thread::Thread(KernelSystem& kernel, u32 core_id) - : WaitObject(kernel), context(kernel.GetThreadManager(core_id).NewContext()), - core_id(core_id), + : WaitObject(kernel), context(kernel.GetThreadManager(core_id).NewContext()), core_id(core_id), thread_manager(kernel.GetThreadManager(core_id)) {} Thread::~Thread() {} diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 1879528cb..3a9ec79c5 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -239,7 +239,8 @@ private: void load(Archive& ar, const unsigned int file_version) { u32 offset{}; ar >> offset; - cmd_list.head_ptr = reinterpret_cast<u32*>(VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr)); + cmd_list.head_ptr = + reinterpret_cast<u32*>(VideoCore::g_memory->GetPhysicalPointer(cmd_list.addr)); cmd_list.current_ptr = cmd_list.head_ptr + offset; } }; From 841255cd16f0a9578cd90a860232e34c209c3c3a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 28 Mar 2020 21:40:18 +0000 Subject: [PATCH 096/129] Attempt to fix the linux builds --- src/audio_core/CMakeLists.txt | 2 +- src/core/file_sys/romfs_reader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 3cb9b538d..63a566596 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -35,7 +35,7 @@ add_library(audio_core STATIC create_target_directory_groups(audio_core) -target_link_libraries(audio_core PUBLIC common core) +target_link_libraries(audio_core PUBLIC common) target_link_libraries(audio_core PRIVATE SoundTouch teakra) if(ENABLE_MF) diff --git a/src/core/file_sys/romfs_reader.cpp b/src/core/file_sys/romfs_reader.cpp index a1ff38945..4c83515b3 100644 --- a/src/core/file_sys/romfs_reader.cpp +++ b/src/core/file_sys/romfs_reader.cpp @@ -12,7 +12,7 @@ std::size_t DirectRomFSReader::ReadFile(std::size_t offset, std::size_t length, if (length == 0) return 0; // Crypto++ does not like zero size buffer file.Seek(file_offset + offset, SEEK_SET); - std::size_t read_length = std::min(length, data_size - offset); + std::size_t read_length = std::min(length, static_cast<std::size_t>(data_size) - offset); read_length = file.ReadBytes(buffer, read_length); if (is_encrypted) { CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption d(key.data(), key.size(), ctr.data()); From 8f059ae3982c5b6a1ae9d313ea4229563328423c Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 29 Mar 2020 11:39:46 +0100 Subject: [PATCH 097/129] Apply suggestions from code review Co-Authored-By: Mat M. <mathew1800@gmail.com> --- src/common/archives.h | 2 +- src/common/memory_ref.h | 4 ++-- src/common/serialization/boost_flat_set.h | 2 +- src/common/thread_queue_list.h | 6 +++--- src/core/arm/arm_interface.h | 18 +++++++++--------- src/core/hle/kernel/config_mem.h | 2 +- src/core/hle/kernel/hle_ipc.cpp | 4 ++-- src/core/hle/kernel/kernel.cpp | 3 ++- src/core/hle/kernel/svc.cpp | 4 ++-- 9 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/common/archives.h b/src/common/archives.h index 993128197..4f8b735d3 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -4,7 +4,7 @@ #pragma once -#include "boost/archive/binary_iarchive.hpp" +#include <boost/archive/binary_iarchive.hpp> #include "boost/archive/binary_oarchive.hpp" #include "boost/serialization/export.hpp" diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index f1a3286ab..65946fc58 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -29,7 +29,7 @@ private: class BufferMem : public BackingMem { public: BufferMem() = default; - BufferMem(u32 size) : data(std::vector<u8>(size)) {} + explicit BufferMem(std::size_t size) : data(size) {} u8* GetPtr() override { return data.data(); @@ -77,7 +77,7 @@ public: inline u8* GetPtr() { return cptr; } - inline operator bool() const { + explicit operator bool() const { return cptr != nullptr; } inline const u8* GetPtr() const { diff --git a/src/common/serialization/boost_flat_set.h b/src/common/serialization/boost_flat_set.h index 7fe0fe097..c47e8c1a7 100644 --- a/src/common/serialization/boost_flat_set.h +++ b/src/common/serialization/boost_flat_set.h @@ -19,7 +19,7 @@ void load(Archive& ar, boost::container::flat_set<T>& set, const unsigned int fi u64 count{}; ar >> count; set.clear(); - for (auto i = 0; i < count; i++) { + for (u64 i = 0; i < count; i++) { T value{}; ar >> value; set.insert(value); diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index c25bbe585..abeb465ad 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -167,7 +167,7 @@ private: } else if (q == UnlinkedTag()) { return -1; } else { - return static_cast<s32>(q - &queues[0]); + return q - queues.data(); } } @@ -186,8 +186,8 @@ private: void save(Archive& ar, const unsigned int file_version) const { s32 idx = ToIndex(first); ar << idx; - for (auto i = 0; i < NUM_QUEUES; i++) { - s32 idx1 = ToIndex(queues[i].next_nonempty); + for (size_t i = 0; i < NUM_QUEUES; i++) { + const s32 idx1 = ToIndex(queues[i].next_nonempty); ar << idx1; ar << queues[i].data; } diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index b02e3941f..e39e1b9fa 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -28,12 +28,12 @@ public: template <class Archive> void save(Archive& ar, const unsigned int file_version) const { - for (auto i = 0; i < 16; i++) { - auto r = GetCpuRegister(i); + for (size_t i = 0; i < 16; i++) { + const auto r = GetCpuRegister(i); ar << r; } - for (auto i = 0; i < 16; i++) { - auto r = GetFpuRegister(i); + for (size_t i = 0; i < 16; i++) { + const auto r = GetFpuRegister(i); ar << r; } auto r1 = GetCpsr(); @@ -47,11 +47,11 @@ public: template <class Archive> void load(Archive& ar, const unsigned int file_version) { u32 r; - for (auto i = 0; i < 16; i++) { + for (size_t i = 0; i < 16; i++) { ar >> r; SetCpuRegister(i, r); } - for (auto i = 0; i < 16; i++) { + for (size_t i = 0; i < 16; i++) { ar >> r; SetFpuRegister(i, r); } @@ -247,7 +247,7 @@ private: ar << id; auto page_table = GetPageTable(); ar << page_table; - for (auto i = 0; i < 15; i++) { + for (size_t i = 0; i < 15; i++) { auto r = GetReg(i); ar << r; } @@ -255,7 +255,7 @@ private: ar << pc; auto cpsr = GetCPSR(); ar << cpsr; - for (auto i = 0; i < 32; i++) { + for (size_t i = 0; i < 32; i++) { auto r = GetVFPReg(i); ar << r; } @@ -278,7 +278,7 @@ private: ar >> page_table; SetPageTable(page_table); u32 r; - for (auto i = 0; i < 15; i++) { + for (size_t = 0; i < 15; i++) { ar >> r; SetReg(i, r); } diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index c466345ec..a81a5d291 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -58,7 +58,7 @@ public: ConfigMemDef& GetConfigMem(); u8* GetPtr() override { - return static_cast<u8*>(static_cast<void*>(&config_mem)); + return reinterpret_cast<u8*>(&config_mem)); } u32 GetSize() const override { diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 23f577490..88bd6b71b 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -21,7 +21,7 @@ class HLERequestContext::ThreadCallback : public Kernel::WakeupCallback { public: ThreadCallback(std::shared_ptr<HLERequestContext> context_, std::shared_ptr<HLERequestContext::WakeupCallback> callback_) - : context(context_), callback(callback_) {} + : context(std::move(context_)), callback(std::move(callback_)) {} void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, std::shared_ptr<WaitObject> object) { ASSERT(thread->status == ThreadStatus::WaitHleEvent); @@ -296,7 +296,7 @@ MappedBuffer::MappedBuffer() : memory(&Core::Global<Core::System>().Memory()) {} MappedBuffer::MappedBuffer(Memory::MemorySystem& memory, std::shared_ptr<Process> process, u32 descriptor, VAddr address, u32 id) - : memory(&memory), id(id), address(address), process(process) { + : memory(&memory), id(id), address(address), process(std::move(process)) { IPC::MappedBufferDescInfo desc{descriptor}; size = desc.size; perms = desc.perms; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 8afddb499..11ef90771 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -24,7 +24,8 @@ KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, u32 num_cores, u8 n3ds_mode) : memory(memory), timing(timing), prepare_reschedule_callback(std::move(prepare_reschedule_callback)) { - for (auto i = 0; i < memory_regions.size(); i++) { +std::generate(memory_regions.begin(), memory_regions.end(), + [] { return std::make_shared<MemoryRegionInfo>(); }); memory_regions[i] = std::make_shared<MemoryRegionInfo>(); } MemoryInit(system_mode, n3ds_mode); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9aeeea236..8f1ba5e01 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -409,7 +409,7 @@ static ResultCode ReceiveIPCRequest(Kernel::KernelSystem& kernel, Memory::Memory class SVC_SyncCallback : public Kernel::WakeupCallback { public: - SVC_SyncCallback(bool do_output_) : do_output(do_output_) {} + explicit SVC_SyncCallback(bool do_output_) : do_output(do_output_) {} void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, std::shared_ptr<WaitObject> object) { @@ -442,7 +442,7 @@ private: class SVC_IPCCallback : public Kernel::WakeupCallback { public: - SVC_IPCCallback(Core::System& system_) : system(system_) {} + explicit SVC_IPCCallback(Core::System& system_) : system(system_) {} void WakeUp(ThreadWakeupReason reason, std::shared_ptr<Thread> thread, std::shared_ptr<WaitObject> object) { From 04aa351c40a19c67382da5470a37b79df477367a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 29 Mar 2020 16:14:36 +0100 Subject: [PATCH 098/129] Code review - general gardening --- src/common/construct.h | 15 ++++----- src/common/memory_ref.h | 49 ++++++++++++++++-------------- src/common/thread_queue_list.h | 10 +++--- src/core/arm/arm_interface.h | 38 +++++++++++------------ src/core/hle/kernel/config_mem.h | 8 +++-- src/core/hle/kernel/kernel.cpp | 6 ++-- src/core/hle/kernel/shared_page.h | 10 ++++-- src/core/hle/service/cecd/cecd.cpp | 43 +++++++++++++++----------- src/core/hle/service/http_c.cpp | 4 +-- src/core/memory.cpp | 30 ++++++++++++++---- 10 files changed, 125 insertions(+), 88 deletions(-) diff --git a/src/common/construct.h b/src/common/construct.h index 4e48ee60d..cb47bb46e 100644 --- a/src/common/construct.h +++ b/src/common/construct.h @@ -6,28 +6,29 @@ #include <boost/serialization/serialization.hpp> +/// Allows classes to define `save_construct` and `load_construct` methods for serialization +/// This is used where we don't call the default constructor during deserialization, as a shortcut +/// instead of using load_construct_data directly class construct_access { public: template <class Archive, class T> - static inline void save_construct(Archive& ar, const T* t, const unsigned int file_version) { + static void save_construct(Archive& ar, const T* t, const unsigned int file_version) { t->save_construct(ar, file_version); } template <class Archive, class T> - static inline void load_construct(Archive& ar, T* t, const unsigned int file_version) { + static void load_construct(Archive& ar, T* t, const unsigned int file_version) { T::load_construct(ar, t, file_version); } }; #define BOOST_SERIALIZATION_CONSTRUCT(T) \ - namespace boost { \ - namespace serialization { \ + namespace boost::serialization { \ template <class Archive> \ - inline void save_construct_data(Archive& ar, const T* t, const unsigned int file_version) { \ + void save_construct_data(Archive& ar, const T* t, const unsigned int file_version) { \ construct_access::save_construct(ar, t, file_version); \ } \ template <class Archive> \ - inline void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ + void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ construct_access::load_construct(ar, t, file_version); \ } \ - } \ } diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index 65946fc58..30eabbaee 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -17,7 +17,8 @@ class BackingMem { public: virtual ~BackingMem() = default; virtual u8* GetPtr() = 0; - virtual u32 GetSize() const = 0; + virtual const u8* GetPtr() const = 0; + virtual std::size_t GetSize() const = 0; private: template <class Archive> @@ -35,7 +36,11 @@ public: return data.data(); } - u32 GetSize() const override { + const u8* GetPtr() const override { + return data.data(); + } + + std::size_t GetSize() const override { return static_cast<u32>(data.size()); } @@ -66,51 +71,51 @@ public: : backing_mem(std::move(backing_mem_)), offset(0) { Init(); } - MemoryRef(std::shared_ptr<BackingMem> backing_mem_, u32 offset_) + MemoryRef(std::shared_ptr<BackingMem> backing_mem_, u64 offset_) : backing_mem(std::move(backing_mem_)), offset(offset_) { ASSERT(offset < backing_mem->GetSize()); Init(); } - inline operator u8*() { - return cptr; - } - inline u8* GetPtr() { - return cptr; - } explicit operator bool() const { return cptr != nullptr; } - inline const u8* GetPtr() const { + operator u8*() { return cptr; } - inline u32 GetSize() const { + u8* GetPtr() { + return cptr; + } + operator const u8*() const { + return cptr; + } + const u8* GetPtr() const { + return cptr; + } + std::size_t GetSize() const { return csize; } - inline void operator+=(u32 offset_by) { + MemoryRef& operator+=(u32 offset_by) { ASSERT(offset_by < csize); offset += offset_by; Init(); + return *this; } - inline MemoryRef operator+(u32 offset_by) const { + MemoryRef operator+(u32 offset_by) const { ASSERT(offset_by < csize); return MemoryRef(backing_mem, offset + offset_by); } - inline u8* operator+(std::size_t offset_by) const { - ASSERT(offset_by < csize); - return cptr + offset_by; - } private: - std::shared_ptr<BackingMem> backing_mem = nullptr; - u32 offset = 0; + std::shared_ptr<BackingMem> backing_mem{}; + u64 offset{}; // Cached values for speed - u8* cptr = nullptr; - u32 csize = 0; + u8* cptr{}; + std::size_t csize{}; void Init() { if (backing_mem) { cptr = backing_mem->GetPtr() + offset; - csize = static_cast<u32>(backing_mem->GetSize() - offset); + csize = static_cast<std::size_t>(backing_mem->GetSize() - offset); } else { cptr = nullptr; csize = 0; diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index abeb465ad..1ba68e1e4 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -161,7 +161,7 @@ private: // The priority level queues of thread ids. std::array<Queue, NUM_QUEUES> queues; - s32 ToIndex(Queue* q) const { + s64 ToIndex(const Queue* q) const { if (q == nullptr) { return -2; } else if (q == UnlinkedTag()) { @@ -171,7 +171,7 @@ private: } } - Queue* ToPointer(s32 idx) { + Queue* ToPointer(s64 idx) { if (idx == -1) { return UnlinkedTag(); } else if (idx < 0) { @@ -184,10 +184,10 @@ private: friend class boost::serialization::access; template <class Archive> void save(Archive& ar, const unsigned int file_version) const { - s32 idx = ToIndex(first); + const s64 idx = ToIndex(first); ar << idx; for (size_t i = 0; i < NUM_QUEUES; i++) { - const s32 idx1 = ToIndex(queues[i].next_nonempty); + const s64 idx1 = ToIndex(queues[i].next_nonempty); ar << idx1; ar << queues[i].data; } @@ -195,7 +195,7 @@ private: template <class Archive> void load(Archive& ar, const unsigned int file_version) { - s32 idx; + s64 idx; ar >> idx; first = ToPointer(idx); for (auto i = 0; i < NUM_QUEUES; i++) { diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index e39e1b9fa..fca488586 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -36,11 +36,11 @@ public: const auto r = GetFpuRegister(i); ar << r; } - auto r1 = GetCpsr(); + const auto r1 = GetCpsr(); ar << r1; - auto r2 = GetFpscr(); + const auto r2 = GetFpscr(); ar << r2; - auto r3 = GetFpexc(); + const auto r3 = GetFpexc(); ar << r3; } @@ -245,26 +245,26 @@ private: void save(Archive& ar, const unsigned int file_version) const { ar << timer; ar << id; - auto page_table = GetPageTable(); + const auto page_table = GetPageTable(); ar << page_table; - for (size_t i = 0; i < 15; i++) { - auto r = GetReg(i); + for (int i = 0; i < 15; i++) { + const auto r = GetReg(i); ar << r; } - auto pc = GetPC(); + const auto pc = GetPC(); ar << pc; - auto cpsr = GetCPSR(); + const auto cpsr = GetCPSR(); ar << cpsr; - for (size_t i = 0; i < 32; i++) { - auto r = GetVFPReg(i); + for (int i = 0; i < 32; i++) { + const auto r = GetVFPReg(i); ar << r; } - for (auto i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { - auto r = GetVFPSystemReg(static_cast<VFPSystemRegister>(i)); + for (size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + const auto r = GetVFPSystemReg(static_cast<VFPSystemRegister>(i)); ar << r; } - for (auto i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { - auto r = GetCP15Register(static_cast<CP15Register>(i)); + for (size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + const auto r = GetCP15Register(static_cast<CP15Register>(i)); ar << r; } } @@ -274,11 +274,11 @@ private: PurgeState(); ar >> timer; ar >> id; - std::shared_ptr<Memory::PageTable> page_table = nullptr; + std::shared_ptr<Memory::PageTable> page_table{}; ar >> page_table; SetPageTable(page_table); u32 r; - for (size_t = 0; i < 15; i++) { + for (int i = 0; i < 15; i++) { ar >> r; SetReg(i, r); } @@ -286,15 +286,15 @@ private: SetPC(r); ar >> r; SetCPSR(r); - for (auto i = 0; i < 32; i++) { + for (int i = 0; i < 32; i++) { ar >> r; SetVFPReg(i, r); } - for (auto i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + for (size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { ar >> r; SetVFPSystemReg(static_cast<VFPSystemRegister>(i), r); } - for (auto i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + for (size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { ar >> r; SetCP15Register(static_cast<CP15Register>(i), r); } diff --git a/src/core/hle/kernel/config_mem.h b/src/core/hle/kernel/config_mem.h index a81a5d291..b592aff7a 100644 --- a/src/core/hle/kernel/config_mem.h +++ b/src/core/hle/kernel/config_mem.h @@ -58,10 +58,14 @@ public: ConfigMemDef& GetConfigMem(); u8* GetPtr() override { - return reinterpret_cast<u8*>(&config_mem)); + return reinterpret_cast<u8*>(&config_mem); } - u32 GetSize() const override { + const u8* GetPtr() const override { + return reinterpret_cast<const u8*>(&config_mem); + } + + std::size_t GetSize() const override { return sizeof(config_mem); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 11ef90771..f0974f88a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -24,10 +24,8 @@ KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing, u32 num_cores, u8 n3ds_mode) : memory(memory), timing(timing), prepare_reschedule_callback(std::move(prepare_reschedule_callback)) { -std::generate(memory_regions.begin(), memory_regions.end(), - [] { return std::make_shared<MemoryRegionInfo>(); }); - memory_regions[i] = std::make_shared<MemoryRegionInfo>(); - } + std::generate(memory_regions.begin(), memory_regions.end(), + [] { return std::make_shared<MemoryRegionInfo>(); }); MemoryInit(system_mode, n3ds_mode); resource_limits = std::make_unique<ResourceLimitList>(*this); diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index b74470b4a..c4b174db4 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -99,11 +99,15 @@ public: SharedPageDef& GetSharedPage(); - virtual u8* GetPtr() { - return static_cast<u8*>(static_cast<void*>(&shared_page)); + u8* GetPtr() override { + return reinterpret_cast<u8*>(&shared_page); } - virtual u32 GetSize() const { + const u8* GetPtr() const override { + return reinterpret_cast<const u8*>(&shared_page); + } + + std::size_t GetSize() const override { return sizeof(shared_page); } diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 36263f622..8db49fc82 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -106,7 +106,7 @@ void Module::Interface::Open(Kernel::HLERequestContext& ctx) { } else { session_data->file = std::move(file_result).Unwrap(); rb.Push(RESULT_SUCCESS); - rb.Push<u32>(session_data->file->GetSize()); // Return file size + rb.Push<u32>(static_cast<u32>(session_data->file->GetSize())); // Return file size } if (path_type == CecDataPathType::MboxProgramId) { @@ -154,8 +154,8 @@ void Module::Interface::Read(Kernel::HLERequestContext& ctx) { break; default: // If not directory, then it is a file std::vector<u8> buffer(write_buffer_size); - const u32 bytes_read = - session_data->file->Read(0, write_buffer_size, buffer.data()).Unwrap(); + const u32 bytes_read = static_cast<u32>( + session_data->file->Read(0, write_buffer_size, buffer.data()).Unwrap()); write_buffer.Write(buffer.data(), 0, write_buffer_size); session_data->file->Close(); @@ -197,7 +197,8 @@ void Module::Interface::ReadMessage(Kernel::HLERequestContext& ctx) { auto message = std::move(message_result).Unwrap(); std::vector<u8> buffer(buffer_size); - const u32 bytes_read = message->Read(0, buffer_size, buffer.data()).Unwrap(); + const u32 bytes_read = + static_cast<u32>(message->Read(0, buffer_size, buffer.data()).Unwrap()); write_buffer.Write(buffer.data(), 0, buffer_size); message->Close(); @@ -266,7 +267,8 @@ void Module::Interface::ReadMessageWithHMAC(Kernel::HLERequestContext& ctx) { auto message = std::move(message_result).Unwrap(); std::vector<u8> buffer(buffer_size); - const u32 bytes_read = message->Read(0, buffer_size, buffer.data()).Unwrap(); + const u32 bytes_read = + static_cast<u32>(message->Read(0, buffer_size, buffer.data()).Unwrap()); write_buffer.Write(buffer.data(), 0, buffer_size); message->Close(); @@ -367,8 +369,8 @@ void Module::Interface::Write(Kernel::HLERequestContext& ctx) { buffer); } - const u32 bytes_written = - session_data->file->Write(0, buffer.size(), true, buffer.data()).Unwrap(); + const u32 bytes_written = static_cast<u32>( + session_data->file->Write(0, buffer.size(), true, buffer.data()).Unwrap()); session_data->file->Close(); rb.Push(RESULT_SUCCESS); @@ -429,7 +431,8 @@ void Module::Interface::WriteMessage(Kernel::HLERequestContext& ctx) { msg_header.sender_id, msg_header.sender_id2, msg_header.send_count, msg_header.forward_count, msg_header.user_data); - const u32 bytes_written = message->Write(0, buffer_size, true, buffer.data()).Unwrap(); + const u32 bytes_written = + static_cast<u32>(message->Write(0, buffer_size, true, buffer.data()).Unwrap()); message->Close(); rb.Push(RESULT_SUCCESS); @@ -515,7 +518,8 @@ void Module::Interface::WriteMessageWithHMAC(Kernel::HLERequestContext& ctx) { hmac.CalculateDigest(hmac_digest.data(), message_body.data(), msg_header.body_size); std::memcpy(buffer.data() + hmac_offset, hmac_digest.data(), hmac_size); - const u32 bytes_written = message->Write(0, buffer_size, true, buffer.data()).Unwrap(); + const u32 bytes_written = + static_cast<u32>(message->Write(0, buffer_size, true, buffer.data()).Unwrap()); message->Close(); rb.Push(RESULT_SUCCESS); @@ -757,7 +761,8 @@ void Module::Interface::OpenAndWrite(Kernel::HLERequestContext& ctx) { cecd->CheckAndUpdateFile(path_type, ncch_program_id, buffer); } - const u32 bytes_written = file->Write(0, buffer.size(), true, buffer.data()).Unwrap(); + const u32 bytes_written = + static_cast<u32>(file->Write(0, buffer.size(), true, buffer.data()).Unwrap()); file->Close(); rb.Push(RESULT_SUCCESS); @@ -806,7 +811,8 @@ void Module::Interface::OpenAndRead(Kernel::HLERequestContext& ctx) { auto file = std::move(file_result).Unwrap(); std::vector<u8> buffer(buffer_size); - const u32 bytes_read = file->Read(0, buffer_size, buffer.data()).Unwrap(); + const u32 bytes_read = + static_cast<u32>(file->Read(0, buffer_size, buffer.data()).Unwrap()); write_buffer.Write(buffer.data(), 0, buffer_size); file->Close(); @@ -937,7 +943,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ constexpr u32 max_num_boxes = 24; constexpr u32 name_size = 16; // fixed size 16 characters long constexpr u32 valid_name_size = 8; // 8 characters are valid, the rest are null - const u32 file_size = file_buffer.size(); + const u32 file_size = static_cast<u32>(file_buffer.size()); switch (path_type) { case CecDataPathType::MboxList: { @@ -1021,7 +1027,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ std::u16string u16_filename; // Loop through entries but don't add mboxlist____ to itself. - for (auto i = 0; i < entry_count; i++) { + for (u32 i = 0; i < entry_count; i++) { u16_filename = std::u16string(entries[i].filename); file_name = Common::UTF16ToUTF8(u16_filename); @@ -1212,7 +1218,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ std::string file_name; std::u16string u16_filename; - for (auto i = 0; i < entry_count; i++) { + for (u32 i = 0; i < entry_count; i++) { u16_filename = std::u16string(entries[i].filename); file_name = Common::UTF16ToUTF8(u16_filename); @@ -1230,7 +1236,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ auto message_result = cecd_system_save_data_archive->OpenFile(message_path, mode); auto message = std::move(message_result).Unwrap(); - const u32 message_size = message->GetSize(); + const u32 message_size = static_cast<u32>(message->GetSize()); std::vector<u8> buffer(message_size); message->Read(0, message_size, buffer.data()).Unwrap(); @@ -1304,7 +1310,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ std::string file_name; std::u16string u16_filename; - for (auto i = 0; i < entry_count; i++) { + for (u32 i = 0; i < entry_count; i++) { u16_filename = std::u16string(entries[i].filename); file_name = Common::UTF16ToUTF8(u16_filename); @@ -1320,7 +1326,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ auto message_result = cecd_system_save_data_archive->OpenFile(message_path, mode); auto message = std::move(message_result).Unwrap(); - const u32 message_size = message->GetSize(); + const u32 message_size = static_cast<u32>(message->GetSize()); std::vector<u8> buffer(message_size); message->Read(0, message_size, buffer.data()).Unwrap(); @@ -1353,7 +1359,8 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ case CecDataPathType::MboxData: case CecDataPathType::MboxIcon: case CecDataPathType::MboxTitle: - default: {} + default: { + } } } diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index af639e493..4879ab371 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -83,10 +83,10 @@ void Context::MakeRequest() { client = std::move(ssl_client); if (auto client_cert = ssl_config.client_cert_ctx.lock()) { - SSL_CTX_use_certificate_ASN1(ctx, client_cert->certificate.size(), + SSL_CTX_use_certificate_ASN1(ctx, static_cast<int>(client_cert->certificate.size()), client_cert->certificate.data()); SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, ctx, client_cert->private_key.data(), - client_cert->private_key.size()); + static_cast<long>(client_cert->private_key.size())); } // TODO(B3N30): Check for SSLOptions-Bits and set the verify method accordingly diff --git a/src/core/memory.cpp b/src/core/memory.cpp index a0fa2a738..c0c030de1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -100,7 +100,7 @@ public: Impl(); - virtual u8* GetPtr(Region r) { + const u8* GetPtr(Region r) const { switch (r) { case Region::VRAM: return vram.get(); @@ -115,7 +115,22 @@ public: } } - virtual u32 GetSize(Region r) const { + u8* GetPtr(Region r) { + switch (r) { + case Region::VRAM: + return vram.get(); + case Region::DSP: + return dsp->GetDspMemory().data(); + case Region::FCRAM: + return fcram.get(); + case Region::N3DS: + return n3ds_extra_ram.get(); + default: + UNREACHABLE(); + } + } + + u32 GetSize(Region r) const { switch (r) { case Region::VRAM: return VRAM_SIZE; @@ -158,11 +173,14 @@ template <Region R> class MemorySystem::BackingMemImpl : public BackingMem { public: BackingMemImpl() : impl(*Core::Global<Core::System>().Memory().impl) {} - BackingMemImpl(MemorySystem::Impl& impl_) : impl(impl_) {} - virtual u8* GetPtr() { + explicit BackingMemImpl(MemorySystem::Impl& impl_) : impl(impl_) {} + u8* GetPtr() override { return impl.GetPtr(R); } - virtual u32 GetSize() const { + const u8* GetPtr() const override { + return impl.GetPtr(R); + } + std::size_t GetSize() const override { return impl.GetSize(R); } @@ -884,7 +902,7 @@ void WriteMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr, const u64 data) u32 MemorySystem::GetFCRAMOffset(const u8* pointer) { ASSERT(pointer >= impl->fcram.get() && pointer <= impl->fcram.get() + Memory::FCRAM_N3DS_SIZE); - return pointer - impl->fcram.get(); + return static_cast<u32>(pointer - impl->fcram.get()); } u8* MemorySystem::GetFCRAMPointer(u32 offset) { From 6760ea18b6a63ae9e0afecffcecd081890991b88 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 29 Mar 2020 18:56:25 +0100 Subject: [PATCH 099/129] Serialize ArchiveManager and other code review actions --- src/core/core.cpp | 2 ++ src/core/file_sys/archive_backend.h | 22 ++++++++++------------ src/core/file_sys/archive_extsavedata.cpp | 9 +++++++++ src/core/file_sys/archive_other_savedata.h | 1 + src/core/file_sys/archive_savedata.h | 1 + src/core/file_sys/archive_selfncch.h | 3 ++- src/core/file_sys/file_backend.h | 1 - src/core/file_sys/layered_fs.h | 9 +-------- src/core/file_sys/savedata_archive.h | 5 +++-- src/core/hle/kernel/hle_ipc.h | 3 --- src/core/hle/kernel/process.cpp | 2 +- src/core/hle/kernel/process.h | 1 + src/core/hle/service/ac/ac.h | 2 -- src/core/hle/service/act/act.h | 2 +- src/core/hle/service/am/am.h | 21 ++++++++++++++------- src/core/hle/service/apt/applet_manager.h | 1 + src/core/hle/service/apt/apt.cpp | 2 ++ src/core/hle/service/apt/apt.h | 7 +------ src/core/hle/service/boss/boss.h | 2 +- src/core/hle/service/cam/cam.h | 7 ++++++- src/core/hle/service/cecd/cecd.cpp | 2 ++ src/core/hle/service/cecd/cecd.h | 2 +- src/core/hle/service/cfg/cfg.cpp | 2 ++ src/core/hle/service/csnd/csnd_snd.h | 6 +----- src/core/hle/service/dsp/dsp_dsp.h | 9 ++++----- src/core/hle/service/fs/archive.h | 6 ++++-- src/core/hle/service/fs/directory.cpp | 2 ++ src/core/hle/service/fs/file.cpp | 1 + src/core/hle/service/fs/file.h | 1 + src/core/hle/service/fs/fs_user.h | 1 + src/core/hle/service/gsp/gsp_gpu.h | 2 ++ src/core/hle/service/hid/hid.cpp | 7 +++++-- src/core/hle/service/ir/extra_hid.h | 1 - src/core/hle/service/ir/ir_rst.cpp | 2 ++ src/core/hle/service/ir/ir_user.cpp | 1 + src/core/hle/service/ndm/ndm_u.h | 1 + src/core/hle/service/nfc/nfc.cpp | 2 ++ src/core/hle/service/nfc/nfc.h | 8 ++++++++ src/core/hle/service/nwm/nwm_uds.cpp | 2 +- src/core/hle/service/service.h | 1 - src/core/hle/service/sm/srv.cpp | 3 ++- src/network/CMakeLists.txt | 2 +- src/network/room_member.h | 2 +- 43 files changed, 102 insertions(+), 67 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 589744367..2928d50e7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,3 +1,4 @@ +#pragma optimize("", off) // Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -544,6 +545,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* cpu_cores[i].get(); } ar&* service_manager.get(); + ar&* archive_manager.get(); ar& GPU::g_regs; ar& LCD::g_regs; diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 87a42b028..0c5b14dc5 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -65,7 +65,7 @@ private: LowPathType type; std::vector<u8> binary; std::string string; - std::u16string u16str{}; + std::u16string u16str; template <class Archive> void serialize(Archive& ar, const unsigned int) { @@ -77,18 +77,16 @@ private: case LowPathType::Char: ar& string; break; -#ifdef _WIN32 - case LowPathType::Wchar: - static_assert(sizeof(wchar_t) == sizeof(char16_t)); - { - std::wstring wstring(reinterpret_cast<wchar_t*>(u16str.data())); - ar& wstring; - if (!Archive::is_saving::value) { - u16str = std::u16string(reinterpret_cast<char16_t*>(wstring.data())); - } + case LowPathType::Wchar: { + std::vector<char16_t> data; + if (Archive::is_saving::value) { + std::copy(u16str.begin(), u16str.end(), std::back_inserter(data)); } - break; -#endif + ar& data; + if (Archive::is_loading::value) { + u16str = std::u16string(data.data(), data.size()); + } + } break; default: break; } diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 59973b8c5..8326122f5 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -167,6 +167,14 @@ public: } return SaveDataArchive::CreateFile(path, size); } + +private: + ExtSaveDataArchive() = default; + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object<SaveDataArchive>(*this); + } + friend class boost::serialization::access; }; struct ExtSaveDataArchivePath { @@ -304,3 +312,4 @@ void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data } // namespace FileSys SERIALIZE_EXPORT_IMPL(FileSys::ExtSaveDataDelayGenerator) +SERIALIZE_EXPORT_IMPL(FileSys::ExtSaveDataArchive) diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index cc0cfe404..f002fec7f 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -4,6 +4,7 @@ #pragma once +#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> #include "core/file_sys/archive_source_sd_savedata.h" diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 3f73adba3..5bc4b8ecd 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -4,6 +4,7 @@ #pragma once +#include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> #include "core/file_sys/archive_source_sd_savedata.h" diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index 68b48074f..9f5b353b3 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -10,6 +10,7 @@ #include <vector> #include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unordered_map.hpp> #include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "core/file_sys/archive_backend.h" @@ -63,7 +64,7 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<ArchiveFactory>(*this); - // NOTE: ncch_data is never written to, so we don't serialize it here + ar& ncch_data; } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index 04f03a77d..d56fc4c1c 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -7,7 +7,6 @@ #include <algorithm> #include <cstddef> #include <memory> -#include <boost/serialization/base_object.hpp> #include <boost/serialization/unique_ptr.hpp> #include "common/common_types.h" #include "core/hle/result.h" diff --git a/src/core/file_sys/layered_fs.h b/src/core/file_sys/layered_fs.h index dc71d052f..2a494bd8e 100644 --- a/src/core/file_sys/layered_fs.h +++ b/src/core/file_sys/layered_fs.h @@ -23,14 +23,6 @@ struct RomFSHeader { struct Descriptor { u32_le offset; u32_le length; - - private: - template <class Archive> - void serialize(Archive& ar, const unsigned int) { - ar& offset; - ar& length; - } - friend class boost::serialization::access; }; u32_le header_length; Descriptor directory_hash_table; @@ -146,6 +138,7 @@ private: if (Archive::is_loading::value) { Load(); } + // NOTE: Everything else is essentially cached, updated when we call Load } friend class boost::serialization::access; }; diff --git a/src/core/file_sys/savedata_archive.h b/src/core/file_sys/savedata_archive.h index c9956e135..38b9653d7 100644 --- a/src/core/file_sys/savedata_archive.h +++ b/src/core/file_sys/savedata_archive.h @@ -38,10 +38,9 @@ public: protected: std::string mount_point; - -private: SaveDataArchive() = default; +private: template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<ArchiveBackend>(*this); @@ -51,8 +50,10 @@ private: }; class SaveDataDelayGenerator; +class ExtSaveDataArchive; } // namespace FileSys BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataArchive) BOOST_CLASS_EXPORT_KEY(FileSys::SaveDataDelayGenerator) +BOOST_CLASS_EXPORT_KEY(FileSys::ExtSaveDataArchive) diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 000486825..47d98af2c 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -22,8 +22,6 @@ #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_session.h" -BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::SessionRequestHandler) - namespace Service { class ServiceFrameworkBase; } @@ -320,5 +318,4 @@ private: } // namespace Kernel -BOOST_CLASS_EXPORT_KEY(Kernel::SessionRequestHandler::SessionDataBase) BOOST_CLASS_EXPORT_KEY(Kernel::HLERequestContext::ThreadCallback) diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index b72081ad5..9b03f30f9 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -6,12 +6,12 @@ #include <memory> #include <boost/serialization/array.hpp> #include <boost/serialization/bitset.hpp> +#include <boost/serialization/shared_ptr.hpp> #include "common/archives.h" #include "common/assert.h" #include "common/common_funcs.h" #include "common/logging/log.h" #include "common/serialization/boost_vector.hpp" -#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 6eb79d227..d9af80cd0 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -13,6 +13,7 @@ #include <boost/container/static_vector.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/vector.hpp> +#include <boost/serialization/string.hpp> #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/handle_table.h" diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h index 0f31ca1b4..e4342bde9 100644 --- a/src/core/hle/service/ac/ac.h +++ b/src/core/hle/service/ac/ac.h @@ -16,8 +16,6 @@ namespace Kernel { class Event; } -BOOST_SERIALIZATION_ASSUME_ABSTRACT(Service::AC::Module::Interface) - namespace Service::AC { class Module final { public: diff --git a/src/core/hle/service/act/act.h b/src/core/hle/service/act/act.h index 11812bcfe..e5c2cf7ae 100644 --- a/src/core/hle/service/act/act.h +++ b/src/core/hle/service/act/act.h @@ -26,7 +26,7 @@ public: private: template <class Archive> - inline void serialize(Archive& ar, const unsigned int file_version) {} + void serialize(Archive& ar, const unsigned int file_version) {} friend class boost::serialization::access; }; diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 22481179e..deff326b7 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -13,6 +13,7 @@ #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/vector.hpp> #include "common/common_types.h" +#include "common/construct.h" #include "core/file_sys/cia_container.h" #include "core/file_sys/file_backend.h" #include "core/global.h" @@ -154,7 +155,6 @@ std::string GetMediaTitlePath(Service::FS::MediaType media_type); class Module final { public: explicit Module(Core::System& system); - explicit Module(Kernel::KernelSystem& kernel); Module() = default; ~Module(); @@ -568,6 +568,8 @@ public: }; private: + explicit Module(Kernel::KernelSystem& kernel); + /** * Scans the for titles in a storage medium for listing. * @param media_type the storage medium to scan @@ -590,6 +592,16 @@ private: ar& am_title_list; ar& system_updater_mutex; } + + template <class Archive> + static void load_construct(Archive& ar, Module* t, const unsigned int file_version) { + ::new (t) Module(Core::Global<Kernel::KernelSystem>()); + } + + template <class Archive> + void save_construct(Archive& ar, const unsigned int file_version) const {} + + friend class ::construct_access; friend class boost::serialization::access; }; @@ -597,9 +609,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::AM -namespace boost::serialization { -template <class Archive> -inline void load_construct_data(Archive& ar, Service::AM::Module* t, const unsigned int) { - ::new (t) Service::AM::Module(Core::Global<Kernel::KernelSystem>()); -} -} // namespace boost::serialization +BOOST_SERIALIZATION_CONSTRUCT(Service::AM::Module); diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 7260fb2d3..0f1a46a8b 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -10,6 +10,7 @@ #include <boost/serialization/array.hpp> #include <boost/serialization/optional.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/vector.hpp> #include "core/global.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 8780f67e0..d93b4bcb2 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/vector.hpp> #include "common/archives.h" #include "common/common_paths.h" #include "common/file_util.h" diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index aa480331c..8b01d3b8e 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -6,8 +6,6 @@ #include <memory> #include <vector> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/vector.hpp> #include "common/archives.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -651,7 +649,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::APT -namespace boost::serialization { -template <class Archive> -void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); -} +SERVICE_CONSTRUCT(Service::APT::Module) diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h index 4dae148f9..e4000e851 100644 --- a/src/core/hle/service/boss/boss.h +++ b/src/core/hle/service/boss/boss.h @@ -989,7 +989,7 @@ void InstallInterfaces(Core::System& system); namespace boost::serialization { template <class Archive> -inline void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) { +void load_construct_data(Archive& ar, Service::BOSS::Module* t, const unsigned int) { ::new (t) Service::BOSS::Module(Core::Global<Core::System>()); } } // namespace boost::serialization diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 85501e8de..375df2b20 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -9,6 +9,10 @@ #include <future> #include <memory> #include <vector> +#include <boost/serialization/array.hpp> +#include <boost/serialization/deque.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unique_ptr.hpp> #include "common/common_types.h" #include "common/swap.h" #include "core/global.h" @@ -849,6 +853,7 @@ private: ar& completion_event; ar& buffer_error_interrupt_event; ar& vsync_interrupt_event; + ar& vsync_timings; // Ignore capture_result. In-progress captures might be affected but this is OK. ar& dest_process; ar& dest; @@ -879,7 +884,7 @@ void InstallInterfaces(Core::System& system); namespace boost::serialization { template <class Archive> -inline void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) { +void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) { ::new (t) Service::CAM::Module(Core::Global<Core::System>()); } } // namespace boost::serialization diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 8db49fc82..31ecd990b 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/unique_ptr.hpp> +#include <boost/serialization/shared_ptr.hpp> #include <cryptopp/base64.h> #include <cryptopp/hmac.h> #include <cryptopp/sha.h> diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index b752701fe..0870f31bf 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -258,7 +258,7 @@ public: ar& data_path_type; ar& open_mode.raw; ar& path; - // ar& file; + ar& file; } friend class boost::serialization::access; }; diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 98feea8f7..fc285f662 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -4,6 +4,8 @@ #include <algorithm> #include <tuple> +#include <boost/serialization/array.hpp> +#include <boost/serialization/unique_ptr.hpp> #include <cryptopp/osrng.h> #include <cryptopp/sha.h> #include "common/archives.h" diff --git a/src/core/hle/service/csnd/csnd_snd.h b/src/core/hle/service/csnd/csnd_snd.h index 6ac5d6876..0b4cd4331 100644 --- a/src/core/hle/service/csnd/csnd_snd.h +++ b/src/core/hle/service/csnd/csnd_snd.h @@ -277,8 +277,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::CSND BOOST_CLASS_EXPORT_KEY(Service::CSND::CSND_SND) - -namespace boost::serialization { -template <class Archive> -void load_construct_data(Archive& ar, Service::CSND::CSND_SND* t, const unsigned int); -} +SERVICE_CONSTRUCT(Service::CSND::CSND_SND) diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h index 90dd17f65..d580b3d00 100644 --- a/src/core/hle/service/dsp/dsp_dsp.h +++ b/src/core/hle/service/dsp/dsp_dsp.h @@ -5,6 +5,9 @@ #pragma once #include <memory> +#include <boost/serialization/array.hpp> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> #include "audio_core/dsp_interface.h" #include "core/hle/kernel/event.h" #include "core/hle/result.h" @@ -282,8 +285,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::DSP BOOST_CLASS_EXPORT_KEY(Service::DSP::DSP_DSP) - -namespace boost::serialization { -template <class Archive> -void load_construct_data(Archive& ar, Service::DSP::DSP_DSP* t, const unsigned int); -} +SERVICE_CONSTRUCT(Service::DSP::DSP_DSP) diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 29965491b..aba06ac6f 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -8,7 +8,8 @@ #include <string> #include <unordered_map> #include <vector> -#include <boost/container/flat_map.hpp> +#include <boost/serialization/unique_ptr.hpp> +#include <boost/serialization/unordered_map.hpp> #include "common/common_types.h" #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -253,7 +254,7 @@ private: * Map of registered archives, identified by id code. Once an archive is registered here, it is * never removed until UnregisterArchiveTypes is called. */ - boost::container::flat_map<ArchiveIdCode, std::unique_ptr<ArchiveFactory>> id_code_map; + std::unordered_map<ArchiveIdCode, std::unique_ptr<ArchiveFactory>> id_code_map; /** * Map of active archive handles to archive objects @@ -267,6 +268,7 @@ private: ar& handle_map; ar& next_handle; } + friend class boost::serialization::access; }; } // namespace Service::FS diff --git a/src/core/hle/service/fs/directory.cpp b/src/core/hle/service/fs/directory.cpp index c7fb085ea..655c5602e 100644 --- a/src/core/hle/service/fs/directory.cpp +++ b/src/core/hle/service/fs/directory.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/unique_ptr.hpp> #include "common/archives.h" #include "common/logging/log.h" #include "core/file_sys/directory_backend.h" diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index 3664f238d..3d9eee594 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/unique_ptr.hpp> #include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 6aa301a7b..a6ef69304 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <boost/serialization/base_object.hpp> #include "core/file_sys/archive_backend.h" #include "core/global.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 83183ecf6..e972d0dae 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -4,6 +4,7 @@ #pragma once +#include <boost/serialization/base_object.hpp> #include "common/common_types.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/gsp/gsp_gpu.h b/src/core/hle/service/gsp/gsp_gpu.h index 82ecf2480..c8914ef72 100644 --- a/src/core/hle/service/gsp/gsp_gpu.h +++ b/src/core/hle/service/gsp/gsp_gpu.h @@ -7,6 +7,8 @@ #include <cstddef> #include <memory> #include <string> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/event.h" diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 6898c1024..845319f62 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -4,6 +4,9 @@ #include <algorithm> #include <cmath> +#include <boost/serialization/array.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unique_ptr.hpp> #include "common/archives.h" #include "common/logging/log.h" #include "core/3ds.h" @@ -208,7 +211,7 @@ void Module::UpdateAccelerometerCallback(u64 userdata, s64 cycles_late) { Common::Vec3<float> accel; if (!motion_device) { - is_device_reload_pending.exchange(true); + is_device_reload_pending.store(true); return; } std::tie(accel, std::ignore) = motion_device->GetStatus(); @@ -259,7 +262,7 @@ void Module::UpdateGyroscopeCallback(u64 userdata, s64 cycles_late) { Common::Vec3<float> gyro; if (!motion_device) { - is_device_reload_pending.exchange(true); + is_device_reload_pending.store(true); return; } std::tie(std::ignore, gyro) = motion_device->GetStatus(); diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index 1be403167..46c0fdca4 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -7,7 +7,6 @@ #include <array> #include <atomic> #include <boost/serialization/array.hpp> -#include <boost/serialization/export.hpp> #include "common/bit_field.h" #include "common/swap.h" #include "core/frontend/input.h" diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 751460a04..bd6c64af3 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> #include "common/archives.h" #include "core/core.h" #include "core/core_timing.h" diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index 4bf6e7499..0cc77c928 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -4,6 +4,7 @@ #include <memory> #include <boost/crc.hpp> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/unique_ptr.hpp> #include "common/string_util.h" diff --git a/src/core/hle/service/ndm/ndm_u.h b/src/core/hle/service/ndm/ndm_u.h index 3339478d1..aebc6fa8b 100644 --- a/src/core/hle/service/ndm/ndm_u.h +++ b/src/core/hle/service/ndm/ndm_u.h @@ -5,6 +5,7 @@ #pragma once #include <array> +#include <boost/serialization/array.hpp> #include "core/hle/service/service.h" namespace Core { diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index 0bd6121a2..7213b79a7 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp @@ -22,6 +22,8 @@ void Module::serialize(Archive& ar, const unsigned int) { ar& tag_out_of_range_event; ar& nfc_tag_state; ar& nfc_status; + ar& amiibo_data; + ar& amiibo_in_range; } SERIALIZE_IMPL(Module) diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h index 2d6b26d83..51fe20b76 100644 --- a/src/core/hle/service/nfc/nfc.h +++ b/src/core/hle/service/nfc/nfc.h @@ -6,6 +6,7 @@ #include <atomic> #include <memory> +#include <boost/serialization/binary_object.hpp> #include "common/common_types.h" #include "core/hle/service/service.h" @@ -35,6 +36,13 @@ struct AmiiboData { u16_be model_number; u8 series; INSERT_PADDING_BYTES(0x1C1); + +private: + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::make_binary_object(this, sizeof(AmiiboData)); + } + friend class boost::serialization::access; }; static_assert(sizeof(AmiiboData) == 0x21C, "AmiiboData is an invalid size"); diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index b2793285f..1a95d2295 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -1175,7 +1175,7 @@ void NWM_UDS::GetChannel(Kernel::HLERequestContext& ctx) { class NWM_UDS::ThreadCallback : public Kernel::HLERequestContext::WakeupCallback { public: - ThreadCallback(u16 command_id_) : command_id(command_id_) {} + explicit ThreadCallback(u16 command_id_) : command_id(command_id_) {} void WakeUp(std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 0261d061f..83b0a5fb1 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -10,7 +10,6 @@ #include <memory> #include <string> #include <boost/container/flat_map.hpp> -#include <boost/serialization/assume_abstract.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> #include "common/common_types.h" diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index f9c62e9ad..da6d57df7 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -88,7 +88,8 @@ void SRV::EnableNotification(Kernel::HLERequestContext& ctx) { class SRV::ThreadCallback : public Kernel::HLERequestContext::WakeupCallback { public: - ThreadCallback(Core::System& system_, std::string name_) : system(system_), name(name_) {} + explicit ThreadCallback(Core::System& system_, std::string name_) + : system(system_), name(name_) {} void WakeUp(std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, Kernel::ThreadWakeupReason reason) { diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 382a69e2f..1e0eb4bc9 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -13,4 +13,4 @@ add_library(network STATIC create_target_directory_groups(network) -target_link_libraries(network PRIVATE common enet Boost::boost) +target_link_libraries(network PRIVATE common enet Boost::serialization) diff --git a/src/network/room_member.h b/src/network/room_member.h index d582a8552..ee1c921d4 100644 --- a/src/network/room_member.h +++ b/src/network/room_member.h @@ -8,7 +8,7 @@ #include <memory> #include <string> #include <vector> -#include <boost/serialization/access.hpp> +#include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "network/room.h" From 9bd189a1550a94b30faa72416a8e1a72edfdeae2 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 29 Mar 2020 19:07:56 +0100 Subject: [PATCH 100/129] More cleaning up --- src/core/hle/kernel/process.h | 3 ++- src/core/hle/service/am/am.h | 1 - src/core/hle/service/cam/cam.cpp | 2 ++ src/core/hle/service/cam/cam.h | 7 +------ src/tests/core/hle/kernel/hle_ipc.cpp | 8 ++++---- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index d9af80cd0..4eca568d9 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -11,9 +11,10 @@ #include <string> #include <vector> #include <boost/container/static_vector.hpp> +#include <boost/serialization/array.hpp> #include <boost/serialization/base_object.hpp> -#include <boost/serialization/vector.hpp> #include <boost/serialization/string.hpp> +#include <boost/serialization/vector.hpp> #include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/handle_table.h" diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index deff326b7..25bd58265 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -155,7 +155,6 @@ std::string GetMediaTitlePath(Service::FS::MediaType media_type); class Module final { public: explicit Module(Core::System& system); - Module() = default; ~Module(); class Interface : public ServiceFramework<Interface> { diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index bf4bdd9c5..e247d998f 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -21,6 +21,8 @@ #include "core/memory.h" #include "core/settings.h" +SERVICE_CONSTRUCT_IMPL(Service::CAM::Module) + namespace Service::CAM { template <class Archive> diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 375df2b20..04dc0e2ea 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -882,9 +882,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::CAM -namespace boost::serialization { -template <class Archive> -void load_construct_data(Archive& ar, Service::CAM::Module* t, const unsigned int) { - ::new (t) Service::CAM::Module(Core::Global<Core::System>()); -} -} // namespace boost::serialization +SERVICE_CONSTRUCT(Service::CAM::Module) diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 6c2a493bb..890343cd8 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -15,8 +15,6 @@ #include "core/hle/kernel/process.h" #include "core/hle/kernel/server_session.h" -SERIALIZE_EXPORT_IMPL(Kernel::SessionRequestHandler::SessionDataBase) - namespace Kernel { static std::shared_ptr<Object> MakeObject(Kernel::KernelSystem& kernel) { @@ -26,7 +24,8 @@ static std::shared_ptr<Object> MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { Core::Timing timing(1, 100); Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, timing, [] {}, 0, 1, 0); + Kernel::KernelSystem kernel( + memory, timing, [] {}, 0, 1, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); @@ -241,7 +240,8 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Core::Timing timing(1, 100); Memory::MemorySystem memory; - Kernel::KernelSystem kernel(memory, timing, [] {}, 0, 1, 0); + Kernel::KernelSystem kernel( + memory, timing, [] {}, 0, 1, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); From 92640fc29c6fee66b6c110ce7631f8e5b3e74e72 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Tue, 31 Mar 2020 17:54:28 +0100 Subject: [PATCH 101/129] Code review actions (plus hopefully fix the linux CI) --- src/CMakeLists.txt | 17 +++++------- src/audio_core/hle/hle.cpp | 1 + src/common/archives.h | 4 +-- src/common/memory_ref.h | 6 ++++- src/common/serialization/atomic.h | 4 +++ .../serialization/boost_discrete_interval.hpp | 22 ++++++++------- src/common/serialization/boost_flat_set.h | 4 +++ .../serialization/boost_interval_set.hpp | 20 ++++++++++++++ src/common/thread_queue_list.h | 4 +-- src/core/arm/arm_interface.h | 27 +++++++++---------- src/core/arm/dynarmic/arm_dynarmic.h | 4 ++- src/core/arm/dyncom/arm_dyncom.h | 4 ++- src/core/core.cpp | 19 +++++-------- src/core/core.h | 1 - src/core/core_timing.cpp | 5 ++-- src/core/hle/kernel/address_arbiter.h | 1 + src/core/hle/kernel/client_port.h | 2 ++ src/core/hle/kernel/client_session.h | 1 + src/core/hle/kernel/event.h | 2 ++ src/core/hle/kernel/kernel.cpp | 3 +++ src/core/hle/kernel/kernel.h | 3 --- src/core/hle/kernel/memory.h | 6 ++--- src/core/hle/kernel/mutex.h | 3 +++ src/core/hle/kernel/object.h | 2 +- src/core/hle/kernel/resource_limit.h | 2 ++ src/core/hle/kernel/semaphore.h | 2 ++ src/core/hle/kernel/server_port.cpp | 4 +++ src/core/hle/kernel/server_port.h | 3 --- src/core/hle/kernel/server_session.cpp | 16 ++++++++++- src/core/hle/kernel/server_session.h | 12 +-------- src/core/hle/kernel/session.cpp | 1 - src/core/hle/kernel/shared_memory.cpp | 1 - src/core/hle/kernel/shared_memory.h | 4 ++- src/core/hle/kernel/shared_page.h | 1 + src/core/hle/kernel/thread.cpp | 2 +- src/core/hle/kernel/timer.cpp | 1 - src/core/hle/kernel/timer.h | 1 + src/core/hle/kernel/vm_manager.h | 1 + src/core/hle/kernel/wait_object.cpp | 10 +++++++ src/core/hle/kernel/wait_object.h | 7 +---- src/core/hle/service/hid/hid.cpp | 8 ------ src/core/hle/service/ir/extra_hid.h | 4 ++- src/core/memory.cpp | 4 +-- src/core/memory.h | 13 +++++---- src/video_core/geometry_pipeline.cpp | 1 - src/video_core/pica_state.h | 1 + 46 files changed, 155 insertions(+), 109 deletions(-) create mode 100644 src/common/serialization/boost_interval_set.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 96c7f35cd..1ada1b3eb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,8 +31,10 @@ if (MSVC) # /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates # /Zc:inline - Let codegen omit inline functions in object files # /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null + # /external:* - Suppress warnings from external headers add_compile_options( /W3 + /MP /Zi /Zo /permissive- @@ -40,17 +42,12 @@ if (MSVC) /volatile:iso /Zc:externConstexpr /Zc:inline + /Zc:throwingNew + /experimental:external + /external:I "${CMAKE_SOURCE_DIR}/externals" + /external:anglebrackets + /external:W0 ) - if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - add_compile_options( - /MP - /Zc:throwingNew - /experimental:external - /external:I "${CMAKE_SOURCE_DIR}/externals" - /external:anglebrackets - /external:W0 - ) - endif() # /GS- - No stack buffer overflow checks add_compile_options("$<$<CONFIG:Release>:/GS->") diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index f4e372f85..3a761dcfa 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -45,6 +45,7 @@ void DspHle::serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<DspInterface>(*this); ar&* impl.get(); } +SERIALIZE_IMPL(DspHle) static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles diff --git a/src/common/archives.h b/src/common/archives.h index 4f8b735d3..b9f4330bd 100644 --- a/src/common/archives.h +++ b/src/common/archives.h @@ -5,8 +5,8 @@ #pragma once #include <boost/archive/binary_iarchive.hpp> -#include "boost/archive/binary_oarchive.hpp" -#include "boost/serialization/export.hpp" +#include <boost/archive/binary_oarchive.hpp> +#include <boost/serialization/export.hpp> using iarchive = boost::archive::binary_iarchive; using oarchive = boost::archive::binary_oarchive; diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index 30eabbaee..0a50c7be9 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -41,13 +41,17 @@ public: } std::size_t GetSize() const override { - return static_cast<u32>(data.size()); + return data.size(); } std::vector<u8>& Vector() { return data; } + const std::vector<u8>& Vector() const { + return data; + } + private: std::vector<u8> data; diff --git a/src/common/serialization/atomic.h b/src/common/serialization/atomic.h index dbc4c0dec..0cf0f20bc 100644 --- a/src/common/serialization/atomic.h +++ b/src/common/serialization/atomic.h @@ -1,3 +1,7 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once #include <atomic> diff --git a/src/common/serialization/boost_discrete_interval.hpp b/src/common/serialization/boost_discrete_interval.hpp index dc920e439..961a9a7ef 100644 --- a/src/common/serialization/boost_discrete_interval.hpp +++ b/src/common/serialization/boost_discrete_interval.hpp @@ -1,33 +1,37 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once -#include "common/common_types.h" #include <boost/icl/discrete_interval.hpp> +#include "common/common_types.h" namespace boost::serialization { template <class Archive, class DomainT, ICL_COMPARE Compare> -void save(Archive& ar, const boost::icl::discrete_interval<DomainT, Compare>& obj, const unsigned int file_version) -{ +void save(Archive& ar, const boost::icl::discrete_interval<DomainT, Compare>& obj, + const unsigned int file_version) { ar << obj.lower(); ar << obj.upper(); ar << obj.bounds()._bits; } template <class Archive, class DomainT, ICL_COMPARE Compare> -void load(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, const unsigned int file_version) -{ +void load(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, + const unsigned int file_version) { DomainT upper, lower; boost::icl::bound_type bounds; - ar >> upper; ar >> lower; + ar >> upper; ar >> bounds; obj = boost::icl::discrete_interval(upper, lower, boost::icl::interval_bounds(bounds)); } template <class Archive, class DomainT, ICL_COMPARE Compare> -void serialize(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, const unsigned int file_version) -{ +void serialize(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, + const unsigned int file_version) { boost::serialization::split_free(ar, obj, file_version); } -} +} // namespace boost::serialization diff --git a/src/common/serialization/boost_flat_set.h b/src/common/serialization/boost_flat_set.h index c47e8c1a7..703bd28b3 100644 --- a/src/common/serialization/boost_flat_set.h +++ b/src/common/serialization/boost_flat_set.h @@ -1,3 +1,7 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once #include <boost/container/flat_set.hpp> diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp new file mode 100644 index 000000000..08e6a14f1 --- /dev/null +++ b/src/common/serialization/boost_interval_set.hpp @@ -0,0 +1,20 @@ +// Copyright 2020 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <boost/icl/interval_set.hpp> +#include "common/serialization/boost_discrete_interval.hpp" + +namespace boost::serialization { + +template <class Archive, class T> +void serialize(Archive& ar, boost::icl::interval_set<T>& obj, const unsigned int file_version) { + using IntervalSet = boost::icl::interval_set<T>; + // This works because interval_set has exactly one member of type ImplSetT + static_assert(std::is_standard_layout_v<IntervalSet>); + ar&*(reinterpret_cast<typename IntervalSet::ImplSetT*>(&obj)); +} + +} // namespace boost::serialization diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 1ba68e1e4..af40bf09b 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -186,7 +186,7 @@ private: void save(Archive& ar, const unsigned int file_version) const { const s64 idx = ToIndex(first); ar << idx; - for (size_t i = 0; i < NUM_QUEUES; i++) { + for (std::size_t i = 0; i < NUM_QUEUES; i++) { const s64 idx1 = ToIndex(queues[i].next_nonempty); ar << idx1; ar << queues[i].data; @@ -198,7 +198,7 @@ private: s64 idx; ar >> idx; first = ToPointer(idx); - for (auto i = 0; i < NUM_QUEUES; i++) { + for (std::size_t i = 0; i < NUM_QUEUES; i++) { ar >> idx; queues[i].next_nonempty = ToPointer(idx); ar >> queues[i].data; diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index fca488586..a6b8a279a 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -6,15 +6,13 @@ #include <cstddef> #include <memory> +#include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/split_member.hpp> #include "common/common_types.h" #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" #include "core/core_timing.h" - -namespace Memory { -struct PageTable; -} +#include "core/memory.h" /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { @@ -28,11 +26,11 @@ public: template <class Archive> void save(Archive& ar, const unsigned int file_version) const { - for (size_t i = 0; i < 16; i++) { + for (std::size_t i = 0; i < 16; i++) { const auto r = GetCpuRegister(i); ar << r; } - for (size_t i = 0; i < 16; i++) { + for (std::size_t i = 0; i < 16; i++) { const auto r = GetFpuRegister(i); ar << r; } @@ -47,11 +45,11 @@ public: template <class Archive> void load(Archive& ar, const unsigned int file_version) { u32 r; - for (size_t i = 0; i < 16; i++) { + for (std::size_t i = 0; i < 16; i++) { ar >> r; SetCpuRegister(i, r); } - for (size_t i = 0; i < 16; i++) { + for (std::size_t i = 0; i < 16; i++) { ar >> r; SetFpuRegister(i, r); } @@ -120,8 +118,6 @@ public: /// Notify CPU emulation that page tables have changed virtual void SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) = 0; - virtual std::shared_ptr<Memory::PageTable> GetPageTable() const = 0; - /** * Set the Program Counter to an address * @param addr Address to set PC to @@ -234,6 +230,9 @@ public: } protected: + // This us used for serialization. Returning nullptr is valid if page tables are not used. + virtual std::shared_ptr<Memory::PageTable> GetPageTable() const = 0; + std::shared_ptr<Core::Timing::Timer> timer; private: @@ -259,11 +258,11 @@ private: const auto r = GetVFPReg(i); ar << r; } - for (size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + for (std::size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { const auto r = GetVFPSystemReg(static_cast<VFPSystemRegister>(i)); ar << r; } - for (size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + for (std::size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { const auto r = GetCP15Register(static_cast<CP15Register>(i)); ar << r; } @@ -290,11 +289,11 @@ private: ar >> r; SetVFPReg(i, r); } - for (size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { + for (std::size_t i = 0; i < VFPSystemRegister::VFP_SYSTEM_REGISTER_COUNT; i++) { ar >> r; SetVFPSystemReg(static_cast<VFPSystemRegister>(i), r); } - for (size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { + for (std::size_t i = 0; i < CP15Register::CP15_REGISTER_COUNT; i++) { ar >> r; SetCP15Register(static_cast<CP15Register>(i), r); } diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index a8f224083..a5b4893a6 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -53,9 +53,11 @@ public: void ClearInstructionCache() override; void InvalidateCacheRange(u32 start_address, std::size_t length) override; void SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) override; - std::shared_ptr<Memory::PageTable> GetPageTable() const override; void PurgeState() override; +protected: + std::shared_ptr<Memory::PageTable> GetPageTable() const override; + private: friend class DynarmicUserCallbacks; Core::System& system; diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 91cbcded0..1452216c2 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -49,10 +49,12 @@ public: void LoadContext(const std::unique_ptr<ThreadContext>& arg) override; void SetPageTable(const std::shared_ptr<Memory::PageTable>& page_table) override; - std::shared_ptr<Memory::PageTable> GetPageTable() const override; void PrepareReschedule() override; void PurgeState() override; +protected: + std::shared_ptr<Memory::PageTable> GetPageTable() const override; + private: void ExecuteInstructions(u64 num_instructions); diff --git a/src/core/core.cpp b/src/core/core.cpp index 2928d50e7..69223a05e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,4 +1,3 @@ -#pragma optimize("", off) // Copyright 2014 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -184,12 +183,14 @@ System::ResultStatus System::RunLoop(bool tight_loop) { LOG_INFO(Core, "Begin load"); System::LoadState(param); LOG_INFO(Core, "Load completed"); - } break; + break; + } case Signal::Save: { LOG_INFO(Core, "Begin save"); System::SaveState(param); LOG_INFO(Core, "Save completed"); - } break; + break; + } default: break; } @@ -551,19 +552,11 @@ void System::serialize(Archive& ar, const unsigned int file_version) { // NOTE: DSP doesn't like being destroyed and recreated. So instead we do an inline // serialization; this means that the DSP Settings need to match for loading to work. - bool dsp_type = Settings::values.enable_dsp_lle; - ar& dsp_type; - if (dsp_type != Settings::values.enable_dsp_lle) { - throw std::runtime_error( - "Incorrect DSP type - please change this in Settings before loading"); - } auto dsp_hle = dynamic_cast<AudioCore::DspHle*>(dsp_core.get()); if (dsp_hle) { ar&* dsp_hle; - } - auto dsp_lle = dynamic_cast<AudioCore::DspLle*>(dsp_core.get()); - if (dsp_lle) { - ar&* dsp_lle; + } else { + throw std::runtime_error("LLE audio not supported for save states"); } ar&* memory.get(); diff --git a/src/core/core.h b/src/core/core.h index 66e880fd1..dfb6aee3e 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -7,7 +7,6 @@ #include <memory> #include <mutex> #include <string> -#include "boost/serialization/access.hpp" #include "common/common_types.h" #include "core/custom_tex_cache.h" #include "core/frontend/applets/mii_selector.h" diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 493bb6344..963926596 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -183,11 +183,10 @@ void Timing::Timer::Advance(s64 max_slice_length) { Event evt = std::move(event_queue.front()); std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); event_queue.pop_back(); - if (evt.type->callback == nullptr) { - LOG_ERROR(Core, "Event '{}' has no callback", *evt.type->name); - } if (evt.type->callback != nullptr) { evt.type->callback(evt.userdata, executed_ticks - evt.time); + } else { + LOG_ERROR(Core, "Event '{}' has no callback", *evt.type->name); } } diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 85a2a065a..059ff1400 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -9,6 +9,7 @@ #include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 1d0f5c024..8d0f50520 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -7,6 +7,8 @@ #include <memory> #include <string> #include <boost/serialization/export.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_port.h" diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 38f39c299..1943db8e6 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h @@ -9,6 +9,7 @@ #include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/result.h" diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 892718533..02eabd750 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -4,7 +4,9 @@ #pragma once +#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index f0974f88a..ef9856363 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -2,6 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unordered_map.hpp> +#include <boost/serialization/vector.hpp> #include "common/archives.h" #include "common/serialization/atomic.h" #include "core/hle/kernel/client_port.h" diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 828843afc..f0a8368d9 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -11,9 +11,6 @@ #include <string> #include <unordered_map> #include <vector> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/unordered_map.hpp> -#include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "core/hle/kernel/memory.h" #include "core/hle/result.h" diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index f4b0a6d98..0560b0bec 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -5,10 +5,11 @@ #pragma once #include <optional> +#include <type_traits> #include <boost/icl/interval_set.hpp> #include <boost/serialization/set.hpp> #include "common/common_types.h" -#include "common/serialization/boost_discrete_interval.hpp" +#include "common/serialization/boost_interval_set.hpp" namespace Kernel { @@ -70,8 +71,7 @@ private: ar& base; ar& size; ar& used; - // This works because interval_set has exactly one member of type ImplSetT - ar&*(reinterpret_cast<IntervalSet::ImplSetT*>(&free_blocks)); + ar& free_blocks; } }; diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 4adf674c3..73ee2a0e6 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -7,6 +7,9 @@ #include <memory> #include <string> #include <boost/serialization/export.hpp> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/wait_object.h" diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 57b208dc1..b272366d7 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -104,7 +104,7 @@ BOOST_SERIALIZATION_ASSUME_ABSTRACT(Kernel::Object) #define CONSTRUCT_KERNEL_OBJECT(T) \ namespace boost::serialization { \ template <class Archive> \ - inline void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ + void load_construct_data(Archive& ar, T* t, const unsigned int file_version) { \ ::new (t) T(Core::Global<Kernel::KernelSystem>()); \ } \ } diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 8593a03a3..cb1c8c78e 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -7,7 +7,9 @@ #include <array> #include <memory> #include <boost/serialization/array.hpp> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index a7ab192a6..b9863a838 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -5,7 +5,9 @@ #pragma once #include <string> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> +#include <boost/serialization/string.hpp> #include <queue> #include "common/common_types.h" #include "core/hle/kernel/object.h" diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 077150222..4d293be34 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -3,6 +3,10 @@ // Refer to the license.txt file included. #include <tuple> +#include <boost/serialization/base_object.hpp> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/vector.hpp> +#include <boost/serialization/string.hpp> #include "common/archives.h" #include "common/assert.h" #include "core/hle/kernel/client_port.h" diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 2f00e586e..00eb10100 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -7,10 +7,7 @@ #include <memory> #include <string> #include <tuple> -#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/server_session.h" diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 3dc20e9a7..61ade5b70 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -3,8 +3,10 @@ // Refer to the license.txt file included. #include <tuple> +#include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/string.hpp> +#include <boost/serialization/vector.hpp> #include "common/archives.h" -#include "core/global.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" @@ -16,6 +18,18 @@ SERIALIZE_EXPORT_IMPL(Kernel::ServerSession) namespace Kernel { +template <class Archive> +void ServerSession::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object<WaitObject>(*this); + ar& name; + ar& parent; + ar& hle_handler; + ar& pending_requesting_threads; + ar& currently_handling; + ar& mapped_buffer_context; +} +SERIALIZE_IMPL(ServerSession) + ServerSession::ServerSession(KernelSystem& kernel) : WaitObject(kernel), kernel(kernel) {} ServerSession::~ServerSession() { // This destructor will be called automatically when the last ServerSession handle is closed by diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 74dbef624..b91accce5 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -7,8 +7,6 @@ #include <memory> #include <string> #include <boost/serialization/export.hpp> -#include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/vector.hpp> #include "common/assert.h" #include "common/common_types.h" #include "core/hle/kernel/ipc.h" @@ -110,15 +108,7 @@ private: friend class boost::serialization::access; template <class Archive> - void serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::base_object<WaitObject>(*this); - ar& name; - ar& parent; - ar& hle_handler; - ar& pending_requesting_threads; - ar& currently_handling; - ar& mapped_buffer_context; - } + void serialize(Archive& ar, const unsigned int file_version); }; } // namespace Kernel diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index 1ec1039dc..8bb846c52 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -6,7 +6,6 @@ #include "common/archives.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" -#include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/session.h" diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 47c966fec..e8f792ee8 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -5,7 +5,6 @@ #include <cstring> #include "common/archives.h" #include "common/logging/log.h" -#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/shared_memory.h" diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index cb2dee685..0e500a1dd 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -6,7 +6,9 @@ #include <string> #include <utility> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> +#include <boost/serialization/string.hpp> #include "common/common_types.h" #include "common/memory_ref.h" #include "core/hle/kernel/object.h" @@ -118,7 +120,7 @@ private: ar& owner_process; ar& base_address; ar& name; - ar&*(reinterpret_cast<MemoryRegionInfo::IntervalSet::ImplSetT*>(&holding_memory)); + ar& holding_memory; } friend class boost::serialization::access; }; diff --git a/src/core/hle/kernel/shared_page.h b/src/core/hle/kernel/shared_page.h index c4b174db4..9cd579d52 100644 --- a/src/core/hle/kernel/shared_page.h +++ b/src/core/hle/kernel/shared_page.h @@ -13,6 +13,7 @@ #include <chrono> #include <ctime> #include <memory> +#include <boost/serialization/base_object.hpp> #include <boost/serialization/binary_object.hpp> #include <boost/serialization/export.hpp> #include "common/bit_field.h" diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 0567ef325..cdd908b4e 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -6,6 +6,7 @@ #include <list> #include <unordered_map> #include <vector> +#include <boost/serialization/string.hpp> #include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" @@ -15,7 +16,6 @@ #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" -#include "core/global.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index d29b25986..d2a12ade1 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -8,7 +8,6 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" -#include "core/global.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index b591c1b03..d5af5e654 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -4,6 +4,7 @@ #pragma once +#include <boost/serialization/string.hpp> #include <boost/serialization/unordered_map.hpp> #include "common/common_types.h" #include "core/core_timing.h" diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 3ca46d069..06fbb8672 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -9,6 +9,7 @@ #include <utility> #include <vector> #include <boost/serialization/map.hpp> +#include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/split_member.hpp> #include "common/common_types.h" #include "common/memory_ref.h" diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 6fe75b6d8..2cd4331c5 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp @@ -4,6 +4,7 @@ #include <algorithm> #include <utility> +#include "common/archives.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/kernel/errors.h" @@ -16,6 +17,15 @@ namespace Kernel { +template <class Archive> +void WaitObject::serialize(Archive& ar, const unsigned int file_version) { + ar& boost::serialization::base_object<Object>(*this); + ar& waiting_threads; + // NB: hle_notifier *not* serialized since it's a callback! + // Fortunately it's only used in one place (DSP) so we can reconstruct it there +} +SERIALIZE_IMPL(WaitObject) + void WaitObject::AddWaitingThread(std::shared_ptr<Thread> thread) { auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); if (itr == waiting_threads.end()) diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index c07290e8a..7f73eab9f 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h @@ -69,12 +69,7 @@ private: private: friend class boost::serialization::access; template <class Archive> - void serialize(Archive& ar, const unsigned int file_version) { - ar& boost::serialization::base_object<Object>(*this); - ar& waiting_threads; - // NB: hle_notifier *not* serialized since it's a callback! - // Fortunately it's only used in one place (DSP) so we can reconstruct it there - } + void serialize(Archive& ar, const unsigned int file_version); }; // Specialization of DynamicObjectCast for WaitObjects diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 845319f62..981a4aa63 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -210,10 +210,6 @@ void Module::UpdateAccelerometerCallback(u64 userdata, s64 cycles_late) { next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); Common::Vec3<float> accel; - if (!motion_device) { - is_device_reload_pending.store(true); - return; - } std::tie(accel, std::ignore) = motion_device->GetStatus(); accel *= accelerometer_coef; // TODO(wwylele): do a time stretch like the one in UpdateGyroscopeCallback @@ -261,10 +257,6 @@ void Module::UpdateGyroscopeCallback(u64 userdata, s64 cycles_late) { GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; Common::Vec3<float> gyro; - if (!motion_device) { - is_device_reload_pending.store(true); - return; - } std::tie(std::ignore, gyro) = motion_device->GetStatus(); double stretch = system.perf_stats->GetLastFrameTimeScale(); gyro *= gyroscope_coef * static_cast<float>(stretch); diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index 46c0fdca4..4b27fba9b 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -71,7 +71,9 @@ private: void serialize(Archive& ar, const unsigned int) { ar& hid_period; ar& calibration_data; // This isn't writeable for now, but might be in future - RequestInputDevicesReload(); // zl, zr, c_stick are loaded here + if (Archive::is_loading::value) { + LoadInputDevices(); // zl, zr, c_stick are loaded here + } } friend class boost::serialization::access; }; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index c0c030de1..184b7f9bd 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,9 +4,9 @@ #include <array> #include <cstring> +#include <boost/serialization/array.hpp> +#include <boost/serialization/binary_object.hpp> #include "audio_core/dsp_interface.h" -#include "boost/serialization/array.hpp" -#include "boost/serialization/binary_object.hpp" #include "common/archives.h" #include "common/assert.h" #include "common/common_types.h" diff --git a/src/core/memory.h b/src/core/memory.h index eb5b6d69c..66b28d87d 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -9,7 +9,6 @@ #include <memory> #include <string> #include <vector> -#include <boost/serialization/access.hpp> #include <boost/serialization/array.hpp> #include <boost/serialization/vector.hpp> #include "common/common_types.h" @@ -86,12 +85,12 @@ struct PageTable { struct Entry { Entry(Pointers& pointers_, VAddr idx_) : pointers(pointers_), idx(idx_) {} - inline void operator=(MemoryRef value) { + void operator=(MemoryRef value) { pointers.refs[idx] = value; pointers.raw[idx] = value.GetPtr(); } - inline operator u8*() { + operator u8*() { return pointers.raw[idx]; } @@ -100,15 +99,15 @@ struct PageTable { VAddr idx; }; - inline Entry operator[](VAddr idx) { + Entry operator[](VAddr idx) { return Entry(*this, idx); } - inline u8* operator[](VAddr idx) const { + u8* operator[](VAddr idx) const { return raw[idx]; } - inline Entry operator[](std::size_t idx) { + Entry operator[](std::size_t idx) { return Entry(*this, static_cast<VAddr>(idx)); } @@ -133,7 +132,7 @@ struct PageTable { */ std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; - inline std::array<u8*, PAGE_TABLE_NUM_ENTRIES>& GetPointerArray() { + std::array<u8*, PAGE_TABLE_NUM_ENTRIES>& GetPointerArray() { return pointers.raw; } diff --git a/src/video_core/geometry_pipeline.cpp b/src/video_core/geometry_pipeline.cpp index 7e002d55d..0ddbda943 100644 --- a/src/video_core/geometry_pipeline.cpp +++ b/src/video_core/geometry_pipeline.cpp @@ -385,7 +385,6 @@ void GeometryPipeline::serialize(Archive& ar, const unsigned int version) { } // namespace Pica -BOOST_SERIALIZATION_ASSUME_ABSTRACT(Pica::GeometryPipelineBackend) SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_Point) SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_VariablePrimitive) SERIALIZE_EXPORT_IMPL(Pica::GeometryPipeline_FixedPrimitive) diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 3a9ec79c5..3c29ff84e 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -5,6 +5,7 @@ #pragma once #include <array> +#include <boost/serialization/array.hpp> #include <boost/serialization/split_member.hpp> #include "common/bit_field.h" #include "common/common_types.h" From f156fdd332f7f1089ec827e5ed756ae6b6e5548a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Tue, 31 Mar 2020 18:27:33 +0100 Subject: [PATCH 102/129] clang format fixes etc. --- .../serialization/boost_interval_set.hpp | 28 +++++++++++++++---- src/core/hle/kernel/memory.h | 1 - src/core/hle/kernel/mutex.h | 2 +- src/core/hle/kernel/server_port.cpp | 2 +- src/core/hle/service/cecd/cecd.cpp | 5 ++-- src/core/hle/service/ir/extra_hid.h | 2 +- src/tests/core/hle/kernel/hle_ipc.cpp | 6 ++-- 7 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp index 08e6a14f1..905e3f145 100644 --- a/src/common/serialization/boost_interval_set.hpp +++ b/src/common/serialization/boost_interval_set.hpp @@ -5,16 +5,34 @@ #pragma once #include <boost/icl/interval_set.hpp> +#include <boost/serialization/split_free.hpp> #include "common/serialization/boost_discrete_interval.hpp" namespace boost::serialization { template <class Archive, class T> -void serialize(Archive& ar, boost::icl::interval_set<T>& obj, const unsigned int file_version) { - using IntervalSet = boost::icl::interval_set<T>; - // This works because interval_set has exactly one member of type ImplSetT - static_assert(std::is_standard_layout_v<IntervalSet>); - ar&*(reinterpret_cast<typename IntervalSet::ImplSetT*>(&obj)); +void save(Archive& ar, const boost::icl::interval_set<T>& set, const unsigned int file_version) { + ar << static_cast<u64>(set.size()); + for (auto& v : set) { + ar << v; + } +} + +template <class Archive, class T> +void load(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file_version) { + u64 count{}; + ar >> count; + set.clear(); + for (u64 i = 0; i < count; i++) { + T value{}; + ar >> value; + set.insert(value); + } +} + +template <class Archive, class T> +void serialize(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file_version) { + boost::serialization::split_free(ar, set, file_version); } } // namespace boost::serialization diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index 0560b0bec..739369a9c 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -5,7 +5,6 @@ #pragma once #include <optional> -#include <type_traits> #include <boost/icl/interval_set.hpp> #include <boost/serialization/set.hpp> #include "common/common_types.h" diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 73ee2a0e6..db98aa8c9 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -6,8 +6,8 @@ #include <memory> #include <string> -#include <boost/serialization/export.hpp> #include <boost/serialization/base_object.hpp> +#include <boost/serialization/export.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/string.hpp> #include "common/common_types.h" diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 4d293be34..006403925 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -5,8 +5,8 @@ #include <tuple> #include <boost/serialization/base_object.hpp> #include <boost/serialization/shared_ptr.hpp> -#include <boost/serialization/vector.hpp> #include <boost/serialization/string.hpp> +#include <boost/serialization/vector.hpp> #include "common/archives.h" #include "common/assert.h" #include "core/hle/kernel/client_port.h" diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 31ecd990b..977a47842 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <boost/serialization/unique_ptr.hpp> #include <boost/serialization/shared_ptr.hpp> +#include <boost/serialization/unique_ptr.hpp> #include <cryptopp/base64.h> #include <cryptopp/hmac.h> #include <cryptopp/sha.h> @@ -1361,8 +1361,7 @@ void Module::CheckAndUpdateFile(const CecDataPathType path_type, const u32 ncch_ case CecDataPathType::MboxData: case CecDataPathType::MboxIcon: case CecDataPathType::MboxTitle: - default: { - } + default: {} } } diff --git a/src/core/hle/service/ir/extra_hid.h b/src/core/hle/service/ir/extra_hid.h index 4b27fba9b..d498c471f 100644 --- a/src/core/hle/service/ir/extra_hid.h +++ b/src/core/hle/service/ir/extra_hid.h @@ -70,7 +70,7 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& hid_period; - ar& calibration_data; // This isn't writeable for now, but might be in future + ar& calibration_data; // This isn't writeable for now, but might be in future if (Archive::is_loading::value) { LoadInputDevices(); // zl, zr, c_stick are loaded here } diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 890343cd8..f5623c8c1 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -24,8 +24,7 @@ static std::shared_ptr<Object> MakeObject(Kernel::KernelSystem& kernel) { TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel]") { Core::Timing timing(1, 100); Memory::MemorySystem memory; - Kernel::KernelSystem kernel( - memory, timing, [] {}, 0, 1, 0); + Kernel::KernelSystem kernel(memory, timing, [] {}, 0, 1, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); @@ -240,8 +239,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { Core::Timing timing(1, 100); Memory::MemorySystem memory; - Kernel::KernelSystem kernel( - memory, timing, [] {}, 0, 1, 0); + Kernel::KernelSystem kernel(memory, timing, [] {}, 0, 1, 0); auto [server, client] = kernel.CreateSessionPair(); HLERequestContext context(kernel, std::move(server), nullptr); From 5b6ee9a6abdf5546ad8d3a92101c8ee1059e5018 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Wed, 1 Apr 2020 22:06:22 +0100 Subject: [PATCH 103/129] Clear out state before deserialization - fixes many crashes. --- src/citra_qt/bootmanager.cpp | 4 +++- src/common/serialization/boost_interval_set.hpp | 6 +++--- src/core/core.cpp | 11 +++++++---- src/core/core.h | 2 +- src/core/savestate.cpp | 10 ++++++++++ 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 78541e880..feab64906 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -132,7 +132,9 @@ void OpenGLWindow::Present() { return; context->makeCurrent(this); - VideoCore::g_renderer->TryPresent(100); + if (VideoCore::g_renderer) { + VideoCore::g_renderer->TryPresent(100); + } context->swapBuffers(this); auto f = context->versionFunctions<QOpenGLFunctions_3_3_Core>(); f->glFinish(); diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp index 905e3f145..d4e48e62a 100644 --- a/src/common/serialization/boost_interval_set.hpp +++ b/src/common/serialization/boost_interval_set.hpp @@ -12,7 +12,7 @@ namespace boost::serialization { template <class Archive, class T> void save(Archive& ar, const boost::icl::interval_set<T>& set, const unsigned int file_version) { - ar << static_cast<u64>(set.size()); + ar << static_cast<u64>(set.iterative_size()); for (auto& v : set) { ar << v; } @@ -24,9 +24,9 @@ void load(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file ar >> count; set.clear(); for (u64 i = 0; i < count; i++) { - T value{}; + typename boost::icl::interval_set<T>::interval_type value{}; ar >> value; - set.insert(value); + set.add(value); } } diff --git a/src/core/core.cpp b/src/core/core.cpp index 69223a05e..1e48c0c62 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -478,7 +478,7 @@ void System::RegisterImageInterface(std::shared_ptr<Frontend::ImageInterface> im registered_image_interface = std::move(image_interface); } -void System::Shutdown() { +void System::Shutdown(bool is_deserializing) { // Log last frame performance stats const auto perf_results = GetAndResetPerfStats(); telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed", @@ -494,17 +494,19 @@ void System::Shutdown() { GDBStub::Shutdown(); VideoCore::Shutdown(); HW::Shutdown(); + if (!is_deserializing) { + perf_stats.reset(); + cheat_engine.reset(); + app_loader.reset(); + } telemetry_session.reset(); - perf_stats.reset(); rpc_server.reset(); - cheat_engine.reset(); archive_manager.reset(); service_manager.reset(); dsp_core.reset(); cpu_cores.clear(); kernel.reset(); timing.reset(); - app_loader.reset(); if (video_dumper->IsDumping()) { video_dumper->StopDumping(); @@ -565,6 +567,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); + memory->SetDSP(*dsp_core); } } diff --git a/src/core/core.h b/src/core/core.h index dfb6aee3e..9fe98f723 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -113,7 +113,7 @@ public: ResultStatus SingleStep(); /// Shutdown the emulated system. - void Shutdown(); + void Shutdown(bool is_deserializing = false); /// Shutdown and then load again void Reset(); diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index d52789b2c..ae5ba11a8 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -8,6 +8,7 @@ #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/zstd_compression.h" +#include "core/cheats/cheats.h" #include "core/core.h" #include "core/savestate.h" #include "video_core/video_core.h" @@ -158,6 +159,15 @@ void System::LoadState(u32 slot) { std::ios_base::binary}; decompressed.clear(); + // When loading, we want to make sure any lingering state gets cleared out before we begin. + // Shutdown, but persist a few things between loads... + Shutdown(true); + + // Re-initialize everything like it was before + auto system_mode = this->app_loader->LoadKernelSystemMode(); + auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); + Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); + try { { From 714a85119dbfb4858fd8138ca4b8506c5807fe1b Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Wed, 1 Apr 2020 22:50:19 +0100 Subject: [PATCH 104/129] Don't crash when getting perf stats --- src/core/core.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 1e48c0c62..2a99d3ccc 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -296,7 +296,8 @@ void System::PrepareReschedule() { } PerfStats::Results System::GetAndResetPerfStats() { - return perf_stats->GetAndResetStats(timing->GetGlobalTimeUs()); + return (perf_stats && timing) ? perf_stats->GetAndResetStats(timing->GetGlobalTimeUs()) + : PerfStats::Results{}; } void System::Reschedule() { From d4ccce13657da93eee49cb125766f368f3e9e266 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Thu, 2 Apr 2020 00:14:00 +0100 Subject: [PATCH 105/129] Add some member initializers in thread --- src/core/hle/kernel/thread.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 09179c0e9..233381f67 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -303,25 +303,25 @@ public: VAddr tls_address; ///< Virtual address of the Thread Local Storage of the thread /// Mutexes currently held by this thread, which will be released when it exits. - boost::container::flat_set<std::shared_ptr<Mutex>> held_mutexes; + boost::container::flat_set<std::shared_ptr<Mutex>> held_mutexes{}; /// Mutexes that this thread is currently waiting for. - boost::container::flat_set<std::shared_ptr<Mutex>> pending_mutexes; + boost::container::flat_set<std::shared_ptr<Mutex>> pending_mutexes{}; - std::shared_ptr<Process> owner_process; ///< Process that owns this thread + std::shared_ptr<Process> owner_process{}; ///< Process that owns this thread /// Objects that the thread is waiting on, in the same order as they were // passed to WaitSynchronization1/N. - std::vector<std::shared_ptr<WaitObject>> wait_objects; + std::vector<std::shared_ptr<WaitObject>> wait_objects{}; VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address - std::string name; + std::string name{}; // Callback that will be invoked when the thread is resumed from a waiting state. If the thread // was waiting via WaitSynchronizationN then the object will be the last object that became // available. In case of a timeout, the object will be nullptr. - std::shared_ptr<WakeupCallback> wakeup_callback; + std::shared_ptr<WakeupCallback> wakeup_callback{}; const u32 core_id; From 74c06bd13e8e2bb11a26ec224b5fb5f3d1193b5c Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Thu, 2 Apr 2020 01:43:27 +0100 Subject: [PATCH 106/129] Attempt to fix crashes with LLE applets --- src/core/memory.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 184b7f9bd..c6a213ff0 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -284,8 +284,10 @@ void MemorySystem::RegisterPageTable(std::shared_ptr<PageTable> page_table) { } void MemorySystem::UnregisterPageTable(std::shared_ptr<PageTable> page_table) { - impl->page_table_list.erase( - std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table)); + auto it = std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table); + if (it != impl->page_table_list.end()) { + impl->page_table_list.erase(it); + } } /** From b5f394dd129e67058c87d86bc7fb33fa63356a1b Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 5 Apr 2020 00:20:59 +0100 Subject: [PATCH 107/129] Use placeholders for serialized paths --- src/common/file_util.cpp | 27 +++++++++++++++++++++++++++ src/common/file_util.h | 9 ++++++++- src/core/core.cpp | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index af4d18288..fd1a3fd30 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -729,6 +729,33 @@ void SetUserPath(const std::string& path) { g_paths.emplace(UserPath::StatesDir, user_path + STATES_DIR DIR_SEP); } +std::string g_currentRomPath{}; + +void SetCurrentRomPath(const std::string& path) { + g_currentRomPath = path; +} + +bool StringReplace(std::string& haystack, const std::string& a, const std::string& b, bool swap) { + const auto& needle = swap ? b : a; + const auto& replacement = swap ? a : b; + if (needle.empty()) { + return false; + } + auto index = haystack.find(needle, 0); + if (index == std::string::npos) { + return false; + } + haystack.replace(index, needle.size(), replacement); + return true; +} + +std::string SerializePath(const std::string& input, bool is_saving) { + auto result = input; + StringReplace(result, "%CITRA_ROM_FILE%", g_currentRomPath, is_saving); + StringReplace(result, "%CITRA_USER_DIR%", GetUserPath(UserPath::UserDir), is_saving); + return result; +} + const std::string& GetUserPath(UserPath path) { // Set up all paths and files on the first run if (g_paths.empty()) diff --git a/src/common/file_util.h b/src/common/file_util.h index 1b1e65609..9eafa2416 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -140,10 +140,15 @@ bool SetCurrentDir(const std::string& directory); void SetUserPath(const std::string& path = ""); +void SetCurrentRomPath(const std::string& path); + // Returns a pointer to a string with a Citra data dir in the user's home // directory. To be used in "multi-user" mode (that is, installed). const std::string& GetUserPath(UserPath path); +// Replaces install-specific paths with standard placeholders, and back again +std::string SerializePath(const std::string& input, bool is_saving); + // Returns the path to where the sys file are std::string GetSysDirectory(); @@ -318,7 +323,8 @@ private: template <class Archive> void save(Archive& ar, const unsigned int) const { - ar << filename; + auto s_filename = SerializePath(filename, true); + ar << s_filename; ar << openmode; ar << flags; ar << Tell(); @@ -327,6 +333,7 @@ private: template <class Archive> void load(Archive& ar, const unsigned int) { ar >> filename; + filename = SerializePath(filename, false); ar >> openmode; ar >> flags; u64 pos; diff --git a/src/core/core.cpp b/src/core/core.cpp index 2a99d3ccc..41fcb6855 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -214,6 +214,7 @@ System::ResultStatus System::SingleStep() { } System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath) { + FileUtil::SetCurrentRomPath(filepath); app_loader = Loader::GetLoader(filepath); if (!app_loader) { LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); From ac37de10fc63a93838be270ec09e0e4c6df460ce Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 6 Apr 2020 20:26:41 +0100 Subject: [PATCH 108/129] Reconnect cheat_engine during load --- src/core/cheats/cheats.cpp | 4 ++++ src/core/cheats/cheats.h | 1 + src/core/savestate.cpp | 1 + 3 files changed, 6 insertions(+) diff --git a/src/core/cheats/cheats.cpp b/src/core/cheats/cheats.cpp index 8b4a30ca6..9053b5ca6 100644 --- a/src/core/cheats/cheats.cpp +++ b/src/core/cheats/cheats.cpp @@ -18,6 +18,10 @@ constexpr u64 run_interval_ticks = BASE_CLOCK_RATE_ARM11 / 60; CheatEngine::CheatEngine(Core::System& system_) : system(system_) { LoadCheatFile(); + Connect(); +} + +void CheatEngine::Connect() { event = system.CoreTiming().RegisterEvent( "CheatCore::run_event", [this](u64 thread_id, s64 cycle_late) { RunCallback(thread_id, cycle_late); }); diff --git a/src/core/cheats/cheats.h b/src/core/cheats/cheats.h index a8d373038..1dfed7ab8 100644 --- a/src/core/cheats/cheats.h +++ b/src/core/cheats/cheats.h @@ -26,6 +26,7 @@ class CheatEngine { public: explicit CheatEngine(Core::System& system); ~CheatEngine(); + void Connect(); std::vector<std::shared_ptr<CheatBase>> GetCheats() const; void AddCheat(const std::shared_ptr<CheatBase>& cheat); void RemoveCheat(int index); diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index ae5ba11a8..6a87569c7 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -167,6 +167,7 @@ void System::LoadState(u32 slot) { auto system_mode = this->app_loader->LoadKernelSystemMode(); auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); + cheat_engine->Connect(); try { From 7ff985cef9602f85af170095d9ce69b662dd71a7 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 6 Apr 2020 21:23:39 +0100 Subject: [PATCH 109/129] Fixed TAS movie serialization --- src/core/core.cpp | 14 ++++++++++++++ src/core/movie.h | 16 ++++++++++++++-- src/core/savestate.cpp | 28 ++++------------------------ src/video_core/video_core.cpp | 14 +++++--------- src/video_core/video_core.h | 4 ++-- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 41fcb6855..fa6d0c30d 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -534,6 +534,17 @@ void System::Reset() { template <class Archive> void System::serialize(Archive& ar, const unsigned int file_version) { + if (Archive::is_loading::value) { + // When loading, we want to make sure any lingering state gets cleared out before we begin. + // Shutdown, but persist a few things between loads... + Shutdown(true); + + // Re-initialize everything like it was before + auto system_mode = this->app_loader->LoadKernelSystemMode(); + auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); + Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); + } + u32 num_cores; if (Archive::is_saving::value) { num_cores = this->GetNumCores(); @@ -565,11 +576,14 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* memory.get(); ar&* kernel.get(); + VideoCore::serialize(ar, file_version); + ar& Movie::GetInstance(); // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { Service::GSP::SetGlobalModule(*this); memory->SetDSP(*dsp_core); + cheat_engine->Connect(); } } diff --git a/src/core/movie.h b/src/core/movie.h index f1be86946..e578b909c 100644 --- a/src/core/movie.h +++ b/src/core/movie.h @@ -5,6 +5,7 @@ #pragma once #include <functional> +#include <boost/serialization/vector.hpp> #include "common/common_types.h" namespace Service { @@ -41,8 +42,8 @@ public: return s_instance; } - void StartPlayback(const std::string& movie_file, - std::function<void()> completion_callback = [] {}); + void StartPlayback( + const std::string& movie_file, std::function<void()> completion_callback = [] {}); void StartRecording(const std::string& movie_file); /// Prepare to override the clock before playing back movies @@ -132,5 +133,16 @@ private: u64 init_time; std::function<void()> playback_completion_callback; std::size_t current_byte = 0; + + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + // Only serialize what's needed to make savestates useful for TAS: + u64 _current_byte = static_cast<u64>(current_byte); + ar& _current_byte; + current_byte = static_cast<std::size_t>(_current_byte); + ar& recorded_input; + ar& init_time; + } + friend class boost::serialization::access; }; } // namespace Core \ No newline at end of file diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index 6a87569c7..ece6406a1 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -84,13 +84,8 @@ std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { void System::SaveState(u32 slot) const { std::ostringstream sstream{std::ios_base::binary}; try { - - { - oarchive oa{sstream}; - oa&* this; - } - VideoCore::Save(sstream); - + oarchive oa{sstream}; + oa&* this; } catch (const std::exception& e) { LOG_ERROR(Core, "Error saving: {}", e.what()); } @@ -159,24 +154,9 @@ void System::LoadState(u32 slot) { std::ios_base::binary}; decompressed.clear(); - // When loading, we want to make sure any lingering state gets cleared out before we begin. - // Shutdown, but persist a few things between loads... - Shutdown(true); - - // Re-initialize everything like it was before - auto system_mode = this->app_loader->LoadKernelSystemMode(); - auto n3ds_mode = this->app_loader->LoadKernelN3dsMode(); - Init(*m_emu_window, *system_mode.first, *n3ds_mode.first); - cheat_engine->Connect(); - try { - - { - iarchive ia{sstream}; - ia&* this; - } - VideoCore::Load(sstream); - + iarchive ia{sstream}; + ia&* this; } catch (const std::exception& e) { LOG_ERROR(Core, "Error loading: {}", e.what()); } diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 5eccd8c7e..f33ec7d57 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -88,15 +88,11 @@ u16 GetResolutionScaleFactor() { } } -void Save(std::ostream& stream) { - oarchive oa{stream}; - oa& Pica::g_state; -} - -void Load(std::istream& stream) { - iarchive ia{stream}; - ia& Pica::g_state; - // TODO: Flush/reset things +template <class Archive> +void serialize(Archive& ar, const unsigned int) { + ar& Pica::g_state; } } // namespace VideoCore + +SERIALIZE_IMPL(VideoCore) diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 10b0d39b6..46cf1e86d 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -62,7 +62,7 @@ void RequestScreenshot(void* data, std::function<void()> callback, u16 GetResolutionScaleFactor(); -void Save(std::ostream& stream); -void Load(std::istream& stream); +template <class Archive> +void serialize(Archive& ar, const unsigned int file_version); } // namespace VideoCore From e74b44042b0af4b130d016f8c2023719fa08ba4a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 6 Apr 2020 22:47:52 +0100 Subject: [PATCH 110/129] Added save + load hotkeys --- src/citra_qt/configuration/config.cpp | 4 +++- src/citra_qt/main.cpp | 6 +++++- src/core/core.cpp | 4 +++- src/core/core.h | 3 +++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index d139a89e9..d815c99f5 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -57,7 +57,7 @@ const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config: // This must be in alphabetical order according to action name as it must have the same order as // UISetting::values.shortcuts, which is alphabetically ordered. // clang-format off -const std::array<UISettings::Shortcut, 21> default_hotkeys{ +const std::array<UISettings::Shortcut, 23> default_hotkeys{ {{QStringLiteral("Advance Frame"), QStringLiteral("Main Window"), {QStringLiteral("\\"), Qt::ApplicationShortcut}}, {QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::ApplicationShortcut}}, {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}}, @@ -73,6 +73,8 @@ const std::array<UISettings::Shortcut, 21> default_hotkeys{ {QStringLiteral("Rotate Screens Upright"), QStringLiteral("Main Window"), {QStringLiteral("F8"), Qt::WindowShortcut}}, {QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}}, {QStringLiteral("Swap Screens"), QStringLiteral("Main Window"), {QStringLiteral("F9"), Qt::WindowShortcut}}, + {QStringLiteral("Save to Oldest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+C"), Qt::WindowShortcut}}, + {QStringLiteral("Load from Newest Slot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+V"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, {QStringLiteral("Toggle Frame Advancing"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+A"), Qt::ApplicationShortcut}}, {QStringLiteral("Toggle Screen Layout"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::WindowShortcut}}, diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index a583e903a..0ef1e5bb1 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -524,6 +524,10 @@ void GMainWindow::InitializeHotkeys() { OnCaptureScreenshot(); } }); + connect(hotkey_registry.GetHotkey(main_window, ui.action_Load_from_Newest_Slot->text(), this), + &QShortcut::activated, ui.action_Load_from_Newest_Slot, &QAction::trigger); + connect(hotkey_registry.GetHotkey(main_window, ui.action_Save_to_Oldest_Slot->text(), this), + &QShortcut::activated, ui.action_Save_to_Oldest_Slot, &QAction::trigger); } void GMainWindow::ShowUpdaterWidgets() { @@ -1636,7 +1640,7 @@ void GMainWindow::OnSaveState() { assert(action); Core::System::GetInstance().SendSignal(Core::System::Signal::Save, action->data().toUInt()); - UpdateSaveStates(); + newest_slot = action->data().toUInt(); } void GMainWindow::OnLoadState() { diff --git a/src/core/core.cpp b/src/core/core.cpp index fa6d0c30d..3d915b764 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -577,7 +577,9 @@ void System::serialize(Archive& ar, const unsigned int file_version) { ar&* memory.get(); ar&* kernel.get(); VideoCore::serialize(ar, file_version); - ar& Movie::GetInstance(); + if (file_version >= 1) { + ar& Movie::GetInstance(); + } // This needs to be set from somewhere - might as well be here! if (Archive::is_loading::value) { diff --git a/src/core/core.h b/src/core/core.h index 9fe98f723..ee66ff5bf 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -7,6 +7,7 @@ #include <memory> #include <mutex> #include <string> +#include <boost/serialization/version.hpp> #include "common/common_types.h" #include "core/custom_tex_cache.h" #include "core/frontend/applets/mii_selector.h" @@ -401,3 +402,5 @@ inline AudioCore::DspInterface& DSP() { } } // namespace Core + +BOOST_CLASS_VERSION(Core::System, 1) From 3278a4d7ef255e90626a9dd7b321e4a0bf0bafea Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 14:02:18 +0100 Subject: [PATCH 111/129] Fix crashes when loading with cameras active --- src/core/hle/service/cam/cam.cpp | 13 +++++++++++++ src/core/hle/service/cam/cam.h | 10 ++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index e247d998f..c093ed7e5 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -30,6 +30,19 @@ void Module::serialize(Archive& ar, const unsigned int) { ar& cameras; ar& ports; ar& is_camera_reload_pending; + if (Archive::is_loading::value) { + for (int i = 0; i < NumCameras; i++) { + LoadCameraImplementation(cameras[i], i); + } + for (std::size_t i = 0; i < ports.size(); i++) { + if (ports[i].is_busy) { + cameras[ports[i].camera_id].impl->StartCapture(); + } + if (ports[i].is_receiving) { + StartReceiving(static_cast<int>(i)); + } + } + } } SERIALIZE_IMPL(Module) diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 04dc0e2ea..7c36e02c5 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -13,6 +13,7 @@ #include <boost/serialization/deque.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/unique_ptr.hpp> +#include <boost/serialization/version.hpp> #include "common/common_types.h" #include "common/swap.h" #include "core/global.h" @@ -792,8 +793,12 @@ private: private: template <class Archive> - void serialize(Archive& ar, const unsigned int) { - ar& impl; + void serialize(Archive& ar, const unsigned int file_version) { + // For compatibility: put a nullptr here + if (file_version == 0) { + std::unique_ptr<Camera::CameraInterface> x; + ar& x; + } ar& contexts; ar& current_context; ar& frame_rate; @@ -883,3 +888,4 @@ void InstallInterfaces(Core::System& system); } // namespace Service::CAM SERVICE_CONSTRUCT(Service::CAM::Module) +BOOST_CLASS_VERSION(Service::CAM::Module::CameraConfig, 1) From 432ac24503082b2ec718b6364555bea05ab336f8 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 16:51:01 +0100 Subject: [PATCH 112/129] Fix memory region serialization (OSK crash) --- src/common/serialization/boost_discrete_interval.hpp | 3 ++- src/common/serialization/boost_interval_set.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/serialization/boost_discrete_interval.hpp b/src/common/serialization/boost_discrete_interval.hpp index 961a9a7ef..f04e3cabc 100644 --- a/src/common/serialization/boost_discrete_interval.hpp +++ b/src/common/serialization/boost_discrete_interval.hpp @@ -6,6 +6,7 @@ #include <boost/icl/discrete_interval.hpp> #include "common/common_types.h" +#include "common/logging/log.h" namespace boost::serialization { @@ -25,7 +26,7 @@ void load(Archive& ar, boost::icl::discrete_interval<DomainT, Compare>& obj, ar >> lower; ar >> upper; ar >> bounds; - obj = boost::icl::discrete_interval(upper, lower, boost::icl::interval_bounds(bounds)); + obj = boost::icl::discrete_interval(lower, upper, boost::icl::interval_bounds(bounds)); } template <class Archive, class DomainT, ICL_COMPARE Compare> diff --git a/src/common/serialization/boost_interval_set.hpp b/src/common/serialization/boost_interval_set.hpp index d4e48e62a..73a560360 100644 --- a/src/common/serialization/boost_interval_set.hpp +++ b/src/common/serialization/boost_interval_set.hpp @@ -26,7 +26,7 @@ void load(Archive& ar, boost::icl::interval_set<T>& set, const unsigned int file for (u64 i = 0; i < count; i++) { typename boost::icl::interval_set<T>::interval_type value{}; ar >> value; - set.add(value); + set += value; } } From 79889786615fb5d37237b368341fa58998a24e3c Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 19:36:38 +0100 Subject: [PATCH 113/129] Fix VFP registers serialization (0 fps when loading etc.) --- src/citra_qt/debugger/wait_tree.cpp | 1 + src/core/arm/arm_interface.h | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/citra_qt/debugger/wait_tree.cpp b/src/citra_qt/debugger/wait_tree.cpp index 15a7ada03..30c1b00b5 100644 --- a/src/citra_qt/debugger/wait_tree.cpp +++ b/src/citra_qt/debugger/wait_tree.cpp @@ -236,6 +236,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { break; } + list.push_back(std::make_unique<WaitTreeText>(tr("object id = %1").arg(thread.GetObjectId()))); list.push_back(std::make_unique<WaitTreeText>(tr("processor = %1").arg(processor))); list.push_back(std::make_unique<WaitTreeText>(tr("thread id = %1").arg(thread.GetThreadId()))); list.push_back(std::make_unique<WaitTreeText>(tr("priority = %1(current) / %2(normal)") diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index a6b8a279a..967c672e6 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -8,6 +8,7 @@ #include <memory> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/split_member.hpp> +#include <boost/serialization/version.hpp> #include "common/common_types.h" #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" @@ -30,7 +31,8 @@ public: const auto r = GetCpuRegister(i); ar << r; } - for (std::size_t i = 0; i < 16; i++) { + std::size_t fpu_reg_count = file_version == 0 ? 16 : 64; + for (std::size_t i = 0; i < fpu_reg_count; i++) { const auto r = GetFpuRegister(i); ar << r; } @@ -49,7 +51,8 @@ public: ar >> r; SetCpuRegister(i, r); } - for (std::size_t i = 0; i < 16; i++) { + std::size_t fpu_reg_count = file_version == 0 ? 16 : 64; + for (std::size_t i = 0; i < fpu_reg_count; i++) { ar >> r; SetFpuRegister(i, r); } @@ -254,7 +257,8 @@ private: ar << pc; const auto cpsr = GetCPSR(); ar << cpsr; - for (int i = 0; i < 32; i++) { + int vfp_reg_count = file_version == 0 ? 32 : 64; + for (int i = 0; i < vfp_reg_count; i++) { const auto r = GetVFPReg(i); ar << r; } @@ -285,7 +289,8 @@ private: SetPC(r); ar >> r; SetCPSR(r); - for (int i = 0; i < 32; i++) { + int vfp_reg_count = file_version == 0 ? 32 : 64; + for (int i = 0; i < vfp_reg_count; i++) { ar >> r; SetVFPReg(i, r); } @@ -301,3 +306,6 @@ private: BOOST_SERIALIZATION_SPLIT_MEMBER() }; + +BOOST_CLASS_VERSION(ARM_Interface, 1) +BOOST_CLASS_VERSION(ARM_Interface::ThreadContext, 1) From 701cd8378623ea99b21c18e5eed8519fe9b78f4a Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 20:20:54 +0100 Subject: [PATCH 114/129] Attempt to fix mac and linux builds --- .travis/linux/upload.sh | 6 +++--- .travis/macos/upload.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis/linux/upload.sh b/.travis/linux/upload.sh index 548ee4905..c40c0d71e 100755 --- a/.travis/linux/upload.sh +++ b/.travis/linux/upload.sh @@ -8,9 +8,9 @@ COMPRESSION_FLAGS="-cJvf" mkdir "$REV_NAME" -cp build/bin/citra "$REV_NAME" -cp build/bin/citra-room "$REV_NAME" -cp build/bin/citra-qt "$REV_NAME" +cp build/bin/Release/citra "$REV_NAME" +cp build/bin/Release/citra-room "$REV_NAME" +cp build/bin/Release/citra-qt "$REV_NAME" # We need icons on Linux for .desktop entries mkdir "$REV_NAME/dist" diff --git a/.travis/macos/upload.sh b/.travis/macos/upload.sh index bdd7d7da7..05760c0b4 100755 --- a/.travis/macos/upload.sh +++ b/.travis/macos/upload.sh @@ -8,9 +8,9 @@ COMPRESSION_FLAGS="-czvf" mkdir "$REV_NAME" -cp build/bin/citra "$REV_NAME" -cp -r build/bin/citra-qt.app "$REV_NAME" -cp build/bin/citra-room "$REV_NAME" +cp build/bin/Release/citra "$REV_NAME" +cp -r build/bin/Release/citra-qt.app "$REV_NAME" +cp build/bin/Release/citra-room "$REV_NAME" # move libs into folder for deployment macpack "${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt" -d "../Frameworks" From 7b3a8e9bf53eadf1c111db8b657a6dd236c04bd9 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 10 Apr 2020 20:22:40 +0100 Subject: [PATCH 115/129] Fix clang format --- src/core/movie.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/movie.h b/src/core/movie.h index e578b909c..eff148090 100644 --- a/src/core/movie.h +++ b/src/core/movie.h @@ -42,8 +42,8 @@ public: return s_instance; } - void StartPlayback( - const std::string& movie_file, std::function<void()> completion_callback = [] {}); + void StartPlayback(const std::string& movie_file, + std::function<void()> completion_callback = [] {}); void StartRecording(const std::string& movie_file); /// Prepare to override the clock before playing back movies From a210e7e2bd9ad3bb296c3882aede790df8c77246 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 10:28:52 +0100 Subject: [PATCH 116/129] Sync GPU state after loading (fix FE terrain bug) --- src/core/core.cpp | 2 ++ src/video_core/rasterizer_interface.h | 2 ++ src/video_core/renderer_base.cpp | 4 ++++ src/video_core/renderer_base.h | 1 + src/video_core/renderer_opengl/gl_rasterizer.h | 6 +++--- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 3d915b764..bdcee4ebd 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -44,6 +44,7 @@ #include "core/rpc/rpc_server.h" #include "core/settings.h" #include "network/network.h" +#include "video_core/renderer_base.h" #include "video_core/video_core.h" namespace Core { @@ -586,6 +587,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) { Service::GSP::SetGlobalModule(*this); memory->SetDSP(*dsp_core); cheat_engine->Connect(); + VideoCore::g_renderer->Sync(); } } diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index a2510292e..873e4273e 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -87,5 +87,7 @@ public: virtual void LoadDiskResources(const std::atomic_bool& stop_loading, const DiskResourceLoadCallback& callback) {} + + virtual void SyncEntireState() {} }; } // namespace VideoCore diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index 4065d1a7d..8d18b6800 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -28,3 +28,7 @@ void RendererBase::RefreshRasterizerSetting() { } } } + +void RendererBase::Sync() { + rasterizer->SyncEntireState(); +} diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 7fcaf5370..578939a6e 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -68,6 +68,7 @@ public: } void RefreshRasterizerSetting(); + void Sync(); protected: Frontend::EmuWindow& render_window; ///< Reference to the render window handle. diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 92cca2e4e..fee8363b6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -61,6 +61,9 @@ public: u32 pixel_stride, ScreenInfo& screen_info) override; bool AccelerateDrawBatch(bool is_indexed) override; + /// Syncs entire status to match PICA registers + void SyncEntireState() override; + private: struct SamplerInfo { using TextureConfig = Pica::TexturingRegs::TextureConfig; @@ -132,9 +135,6 @@ private: GLvec3 view; }; - /// Syncs entire status to match PICA registers - void SyncEntireState(); - /// Syncs the clip enabled status to match the PICA register void SyncClipEnabled(); From e9ab8f82d4e4057889340cc45431de4f8b75ee2b Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 11:52:11 +0100 Subject: [PATCH 117/129] Add disk archive serialization (fix crash in driver renegade etc.) --- src/common/file_util.h | 74 +++++++++++++++++++++--------- src/core/file_sys/disk_archive.cpp | 4 ++ src/core/file_sys/disk_archive.h | 28 ++++++++++- 3 files changed, 83 insertions(+), 23 deletions(-) diff --git a/src/common/file_util.h b/src/common/file_util.h index 9eafa2416..d5915b8b7 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -16,6 +16,7 @@ #include <vector> #include <boost/serialization/split_member.hpp> #include <boost/serialization/string.hpp> +#include <boost/serialization/wrapper.hpp> #include "common/common_types.h" #ifdef _MSC_VER #include "common/string_util.h" @@ -41,6 +42,34 @@ enum class UserPath { UserDir, }; +// Replaces install-specific paths with standard placeholders, and back again +std::string SerializePath(const std::string& input, bool is_saving); + +// A serializable path string +struct Path : public boost::serialization::wrapper_traits<const Path> { + std::string& str; + + explicit Path(std::string& _str) : str(_str) {} + + static const Path make(std::string& str) { + return Path(str); + } + + template <class Archive> + void save(Archive& ar, const unsigned int) const { + auto s_path = SerializePath(str, true); + ar << s_path; + } + template <class Archive> + void load(Archive& ar, const unsigned int) const { + ar >> str; + str = SerializePath(str, false); + } + + BOOST_SERIALIZATION_SPLIT_MEMBER(); + friend class boost::serialization::access; +}; + // FileSystem tree node/ struct FSTEntry { bool isDirectory; @@ -48,6 +77,17 @@ struct FSTEntry { std::string physicalName; // name on disk std::string virtualName; // name in FST names table std::vector<FSTEntry> children; + +private: + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& isDirectory; + ar& size; + ar& Path::make(physicalName); + ar& Path::make(virtualName); + ar& children; + } + friend class boost::serialization::access; }; // Returns true if file filename exists @@ -146,9 +186,6 @@ void SetCurrentRomPath(const std::string& path); // directory. To be used in "multi-user" mode (that is, installed). const std::string& GetUserPath(UserPath path); -// Replaces install-specific paths with standard placeholders, and back again -std::string SerializePath(const std::string& input, bool is_saving); - // Returns the path to where the sys file are std::string GetSysDirectory(); @@ -322,27 +359,20 @@ private: u32 flags; template <class Archive> - void save(Archive& ar, const unsigned int) const { - auto s_filename = SerializePath(filename, true); - ar << s_filename; - ar << openmode; - ar << flags; - ar << Tell(); - } - - template <class Archive> - void load(Archive& ar, const unsigned int) { - ar >> filename; - filename = SerializePath(filename, false); - ar >> openmode; - ar >> flags; + void serialize(Archive& ar, const unsigned int) { + ar& Path::make(filename); + ar& openmode; + ar& flags; u64 pos; - ar >> pos; - Open(); - Seek(pos, SEEK_SET); + if (Archive::is_saving::value) { + pos = Tell(); + } + ar& pos; + if (Archive::is_loading::value) { + Open(); + Seek(pos, SEEK_SET); + } } - - BOOST_SERIALIZATION_SPLIT_MEMBER() friend class boost::serialization::access; }; diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index 061460546..6ace314bf 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -5,6 +5,7 @@ #include <algorithm> #include <cstdio> #include <memory> +#include "common/archives.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" @@ -14,6 +15,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace +SERIALIZE_EXPORT_IMPL(FileSys::DiskFile) +SERIALIZE_EXPORT_IMPL(FileSys::DiskDirectory) + namespace FileSys { ResultVal<std::size_t> DiskFile::Read(const u64 offset, const std::size_t length, diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h index 9251749ce..2f0e5691a 100644 --- a/src/core/file_sys/disk_archive.h +++ b/src/core/file_sys/disk_archive.h @@ -10,6 +10,7 @@ #include <vector> #include <boost/serialization/base_object.hpp> #include <boost/serialization/unique_ptr.hpp> +#include <boost/serialization/vector.hpp> #include "common/common_types.h" #include "common/file_util.h" #include "core/file_sys/archive_backend.h" @@ -46,12 +47,16 @@ protected: Mode mode; std::unique_ptr<FileUtil::IOFile> file; +private: + DiskFile() = default; + template <class Archive> void serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object<FileBackend>(*this); - ar& mode; + ar& mode.hex; ar& file; } + friend class boost::serialization::access; }; class DiskDirectory : public DirectoryBackend { @@ -74,6 +79,27 @@ protected: // We need to remember the last entry we returned, so a subsequent call to Read will continue // from the next one. This iterator will always point to the next unread entry. std::vector<FileUtil::FSTEntry>::iterator children_iterator; + +private: + DiskDirectory() = default; + + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object<DirectoryBackend>(*this); + ar& directory; + u64 child_index; + if (Archive::is_saving::value) { + child_index = children_iterator - directory.children.begin(); + } + ar& child_index; + if (Archive::is_loading::value) { + children_iterator = directory.children.begin() + child_index; + } + } + friend class boost::serialization::access; }; } // namespace FileSys + +BOOST_CLASS_EXPORT_KEY(FileSys::DiskFile) +BOOST_CLASS_EXPORT_KEY(FileSys::DiskDirectory) From 3871d74bc213e8fd8ef712ef4724df3fe629ad7f Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 19:33:21 +0100 Subject: [PATCH 118/129] Fix mic sharedmemory not being deallocated --- src/core/hle/service/mic_u.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 08ef5473f..f0017ac4c 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <boost/serialization/weak_ptr.hpp> #ifdef HAVE_CUBEB #include "audio_core/cubeb_input.h" #endif @@ -69,7 +70,7 @@ constexpr u64 GetBufferUpdateRate(SampleRate sample_rate) { // Variables holding the current mic buffer writing state struct State { - std::shared_ptr<Kernel::SharedMemory> memory_ref = nullptr; + std::weak_ptr<Kernel::SharedMemory> memory_ref{}; u8* sharedmem_buffer = nullptr; u32 sharedmem_size = 0; std::size_t size = 0; @@ -110,7 +111,9 @@ struct State { private: template <class Archive> void serialize(Archive& ar, const unsigned int) { - ar& memory_ref; + std::shared_ptr<Kernel::SharedMemory> _memory_ref = memory_ref.lock(); + ar& _memory_ref; + memory_ref = _memory_ref; ar& sharedmem_size; ar& size; ar& offset; @@ -118,7 +121,7 @@ private: ar& looped_buffer; ar& sample_size; ar& sample_rate; - sharedmem_buffer = memory_ref ? memory_ref->GetPointer() : nullptr; + sharedmem_buffer = _memory_ref ? _memory_ref->GetPointer() : nullptr; } friend class boost::serialization::access; }; From e6b40486c52142adfa7c4bd9e471280c1c600c60 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 19:47:06 +0100 Subject: [PATCH 119/129] Add a couple of useful SVC logs --- src/core/hle/kernel/svc.cpp | 1 + src/core/hle/kernel/svc_wrapper.h | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 8f1ba5e01..25eb9bb4e 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1607,6 +1607,7 @@ void SVC::CallSVC(u32 immediate) { "Running threads from exiting processes is unimplemented"); const FunctionDef* info = GetSVCInfo(immediate); + LOG_TRACE(Kernel_SVC, "calling {}", info->name); if (info) { if (info->func) { (this->*(info->func))(); diff --git a/src/core/hle/kernel/svc_wrapper.h b/src/core/hle/kernel/svc_wrapper.h index b4fbbe0de..77334152d 100644 --- a/src/core/hle/kernel/svc_wrapper.h +++ b/src/core/hle/kernel/svc_wrapper.h @@ -280,6 +280,26 @@ private: } }; + template <typename SVCT> + struct WrapPass<SVCT, ResultCode /*empty for T, Ts...*/> { + // Call function R(Context::svc)(Us...) and transfer the return value to registers + template <typename... Us> + static void Call(Context& context, SVCT svc, Us... u) { + static_assert(std::is_same_v<SVCT, ResultCode (Context::*)(Us...)>); + if constexpr (std::is_void_v<ResultCode>) { + (context.*svc)(u...); + } else { + ResultCode r = (context.*svc)(u...); + if (r.IsError()) { + LOG_ERROR(Kernel_SVC, "level={} summary={} module={} description={}", + r.level.ExtractValue(r.raw), r.summary.ExtractValue(r.raw), + r.module.ExtractValue(r.raw), r.description.ExtractValue(r.raw)); + } + SetParam<INDEX_RETURN, ResultCode, ResultCode, Us...>(context, r); + } + } + }; + template <typename T> struct WrapHelper; From 4be752dd980a18b922939acbd92a12f599cedf04 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 19:47:31 +0100 Subject: [PATCH 120/129] Allow GDB debugging through loads --- src/core/core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index bdcee4ebd..8768ba3e6 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -494,10 +494,10 @@ void System::Shutdown(bool is_deserializing) { perf_stats->GetMeanFrametime()); // Shutdown emulation session - GDBStub::Shutdown(); VideoCore::Shutdown(); HW::Shutdown(); if (!is_deserializing) { + GDBStub::Shutdown(); perf_stats.reset(); cheat_engine.reset(); app_loader.reset(); From 34af0d3452192a5d880a0b305d7fd31e9375da52 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 20:33:38 +0100 Subject: [PATCH 121/129] Attempt to fix network bug --- src/core/hle/service/nwm/nwm_uds.cpp | 3 +++ src/core/savestate.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 1a95d2295..8ebb8a6e3 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -504,6 +504,9 @@ void NWM_UDS::HandleDataFrame(const Network::WifiPacket& packet) { /// Callback to parse and handle a received wifi packet. void NWM_UDS::OnWifiPacketReceived(const Network::WifiPacket& packet) { + if (!initialized) { + return; + } switch (packet.type) { case Network::WifiPacket::PacketType::Beacon: HandleBeaconFrame(packet); diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index ece6406a1..2a6fb92cb 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include <chrono> +#include <boost/serialization/binary_object.hpp> #include <cryptopp/hex.h> #include "common/archives.h" #include "common/logging/log.h" @@ -11,6 +12,7 @@ #include "core/cheats/cheats.h" #include "core/core.h" #include "core/savestate.h" +#include "network/network.h" #include "video_core/video_core.h" namespace Core { @@ -23,6 +25,11 @@ struct CSTHeader { u64_le time; /// The time when this save state was created std::array<u8, 216> reserved; /// Make heading 256 bytes so it has consistent size + + template <class Archive> + void serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::binary_object(this, sizeof(CSTHeader)); + } }; static_assert(sizeof(CSTHeader) == 256, "CSTHeader should be 256 bytes"); #pragma pack(pop) @@ -127,6 +134,11 @@ void System::SaveState(u32 slot) const { } void System::LoadState(u32 slot) { + if (Network::GetRoomMember().lock()->IsConnected()) { + LOG_ERROR(Core, "Unable to load while connected to multiplayer"); + return; + } + const auto path = GetSaveStatePath(title_id, slot); if (!FileUtil::Exists(path)) { LOG_ERROR(Core, "File not exist {}", path); From 19872b599baa824ff26716a502a4c6ca441c1347 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 20:47:14 +0100 Subject: [PATCH 122/129] Fix button state not persisting between loads --- src/core/hle/service/hid/hid.cpp | 6 ++++-- src/core/hle/service/hid/hid.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 981a4aa63..4c8718276 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -30,7 +30,7 @@ SERIALIZE_EXPORT_IMPL(Service::HID::Module) namespace Service::HID { template <class Archive> -void Module::serialize(Archive& ar, const unsigned int) { +void Module::serialize(Archive& ar, const unsigned int file_version) { ar& shared_mem; ar& event_pad_or_touch_1; ar& event_pad_or_touch_2; @@ -46,7 +46,9 @@ void Module::serialize(Archive& ar, const unsigned int) { if (Archive::is_loading::value) { LoadInputDevices(); } - // Pad state not needed as it's always updated + if (file_version >= 1) { + ar& state.hex; + } // Update events are set in the constructor // Devices are set from the implementation (and are stateless afaik) } diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index ad526ac6f..58a3c68a5 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -8,6 +8,7 @@ #include <atomic> #include <cstddef> #include <memory> +#include <boost/serialization/version.hpp> #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -348,3 +349,4 @@ void InstallInterfaces(Core::System& system); SERVICE_CONSTRUCT(Service::HID::Module) BOOST_CLASS_EXPORT_KEY(Service::HID::Module) +BOOST_CLASS_VERSION(Service::HID::Module, 1) From 77c4b26e6ce4d4c35b0789c361a9dda69c5a0d06 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sat, 11 Apr 2020 22:25:57 +0100 Subject: [PATCH 123/129] Attempt to improve save/load during frame advance --- src/citra_qt/main.cpp | 3 ++ src/core/core.cpp | 67 +++++++++++++++++++++-------------------- src/core/perf_stats.cpp | 12 +++++--- src/core/perf_stats.h | 1 + 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 0ef1e5bb1..bd1c95c52 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -706,6 +706,7 @@ void GMainWindow::ConnectMenuEvents() { if (emulation_running) { ui.action_Enable_Frame_Advancing->setChecked(true); ui.action_Advance_Frame->setEnabled(true); + Core::System::GetInstance().frame_limiter.SetFrameAdvancing(true); Core::System::GetInstance().frame_limiter.AdvanceFrame(); } }); @@ -1640,6 +1641,7 @@ void GMainWindow::OnSaveState() { assert(action); Core::System::GetInstance().SendSignal(Core::System::Signal::Save, action->data().toUInt()); + Core::System::GetInstance().frame_limiter.AdvanceFrame(); newest_slot = action->data().toUInt(); } @@ -1648,6 +1650,7 @@ void GMainWindow::OnLoadState() { assert(action); Core::System::GetInstance().SendSignal(Core::System::Signal::Load, action->data().toUInt()); + Core::System::GetInstance().frame_limiter.AdvanceFrame(); } void GMainWindow::OnConfigure() { diff --git a/src/core/core.cpp b/src/core/core.cpp index 8768ba3e6..58f1ddefe 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -89,6 +89,40 @@ System::ResultStatus System::RunLoop(bool tight_loop) { } } + Signal signal{Signal::None}; + u32 param{}; + { + std::lock_guard lock{signal_mutex}; + if (current_signal != Signal::None) { + signal = current_signal; + param = signal_param; + current_signal = Signal::None; + } + } + switch (signal) { + case Signal::Reset: + Reset(); + return ResultStatus::Success; + case Signal::Shutdown: + return ResultStatus::ShutdownRequested; + case Signal::Load: { + LOG_INFO(Core, "Begin load"); + System::LoadState(param); + LOG_INFO(Core, "Load completed"); + frame_limiter.WaitOnce(); + return ResultStatus::Success; + } + case Signal::Save: { + LOG_INFO(Core, "Begin save"); + System::SaveState(param); + LOG_INFO(Core, "Save completed"); + frame_limiter.WaitOnce(); + return ResultStatus::Success; + } + default: + break; + } + // All cores should have executed the same amount of ticks. If this is not the case an event was // scheduled with a cycles_into_future smaller then the current downcount. // So we have to get those cores to the same global time first @@ -163,39 +197,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) { HW::Update(); Reschedule(); - Signal signal{Signal::None}; - u32 param{}; - { - std::lock_guard lock{signal_mutex}; - if (current_signal != Signal::None) { - signal = current_signal; - param = signal_param; - current_signal = Signal::None; - } - } - switch (signal) { - case Signal::Reset: - Reset(); - break; - case Signal::Shutdown: - return ResultStatus::ShutdownRequested; - break; - case Signal::Load: { - LOG_INFO(Core, "Begin load"); - System::LoadState(param); - LOG_INFO(Core, "Load completed"); - break; - } - case Signal::Save: { - LOG_INFO(Core, "Begin save"); - System::SaveState(param); - LOG_INFO(Core, "Save completed"); - break; - } - default: - break; - } - return status; } diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 94d6c17ca..00ab24dbc 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -117,6 +117,14 @@ double PerfStats::GetLastFrameTimeScale() { return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH; } +void FrameLimiter::WaitOnce() { + if (frame_advancing_enabled) { + // Frame advancing is enabled: wait on event instead of doing framelimiting + frame_advance_event.Wait(); + frame_advance_event.Reset(); + } +} + void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) { if (frame_advancing_enabled) { // Frame advancing is enabled: wait on event instead of doing framelimiting @@ -164,10 +172,6 @@ void FrameLimiter::SetFrameAdvancing(bool value) { } void FrameLimiter::AdvanceFrame() { - if (!frame_advancing_enabled) { - // Start frame advancing - frame_advancing_enabled = true; - } frame_advance_event.Set(); } diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index 0ef5168fa..c7d22ef8e 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -98,6 +98,7 @@ public: */ void SetFrameAdvancing(bool value); void AdvanceFrame(); + void WaitOnce(); private: /// Emulated system time (in microseconds) at the last limiter invocation From d53e94db88d18178ed73a5bc48b8df8e2fa4c992 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Sun, 12 Apr 2020 23:12:15 +0100 Subject: [PATCH 124/129] Show save/load errors to the user --- src/citra_qt/main.cpp | 3 +++ src/core/core.cpp | 20 +++++++++++++---- src/core/core.h | 1 + src/core/savestate.cpp | 49 ++++++++++++------------------------------ 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index f6dc3f2ef..7389b8c23 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -2079,6 +2079,9 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det title = tr("System Archive Not Found"); status_message = tr("System Archive Missing"); + } else if (result == Core::System::ResultStatus::ErrorSavestate) { + title = tr("Save/load Error"); + message = QString::fromStdString(details); } else { title = tr("Fatal Error"); message = diff --git a/src/core/core.cpp b/src/core/core.cpp index 1421d7f70..14b41207a 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -107,15 +107,27 @@ System::ResultStatus System::RunLoop(bool tight_loop) { return ResultStatus::ShutdownRequested; case Signal::Load: { LOG_INFO(Core, "Begin load"); - System::LoadState(param); - LOG_INFO(Core, "Load completed"); + try { + System::LoadState(param); + LOG_INFO(Core, "Load completed"); + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error loading: {}", e.what()); + status_details = e.what(); + return ResultStatus::ErrorSavestate; + } frame_limiter.WaitOnce(); return ResultStatus::Success; } case Signal::Save: { LOG_INFO(Core, "Begin save"); - System::SaveState(param); - LOG_INFO(Core, "Save completed"); + try { + System::SaveState(param); + LOG_INFO(Core, "Save completed"); + } catch (const std::exception& e) { + LOG_ERROR(Core, "Error saving: {}", e.what()); + status_details = e.what(); + return ResultStatus::ErrorSavestate; + } frame_limiter.WaitOnce(); return ResultStatus::Success; } diff --git a/src/core/core.h b/src/core/core.h index eb3dc01b3..dca6a6888 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -89,6 +89,7 @@ public: /// generic drivers installed ErrorVideoCore_ErrorBelowGL33, ///< Error in the video core due to the user not having /// OpenGL 3.3 or higher + ErrorSavestate, ///< Error saving or loading ShutdownRequested, ///< Emulated program requested a system shutdown ErrorUnknown ///< Any other error }; diff --git a/src/core/savestate.cpp b/src/core/savestate.cpp index 2a6fb92cb..26fc0cbed 100644 --- a/src/core/savestate.cpp +++ b/src/core/savestate.cpp @@ -90,26 +90,22 @@ std::vector<SaveStateInfo> ListSaveStates(u64 program_id) { void System::SaveState(u32 slot) const { std::ostringstream sstream{std::ios_base::binary}; - try { - oarchive oa{sstream}; - oa&* this; - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error saving: {}", e.what()); - } + // Serialize + oarchive oa{sstream}; + oa&* this; + const std::string& str{sstream.str()}; auto buffer = Common::Compression::CompressDataZSTDDefault( reinterpret_cast<const u8*>(str.data()), str.size()); const auto path = GetSaveStatePath(title_id, slot); if (!FileUtil::CreateFullPath(path)) { - LOG_ERROR(Core, "Could not create path {}", path); - return; + throw std::runtime_error("Could not create path " + path); } FileUtil::IOFile file(path, "wb"); if (!file) { - LOG_ERROR(Core, "Could not open file {}", path); - return; + throw std::runtime_error("Could not open file " + path); } CSTHeader header{}; @@ -123,41 +119,27 @@ void System::SaveState(u32 slot) const { std::chrono::system_clock::now().time_since_epoch()) .count(); - if (file.WriteBytes(&header, sizeof(header)) != sizeof(header)) { - LOG_ERROR(Core, "Could not write to file {}", path); - return; - } - if (file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { - LOG_ERROR(Core, "Could not write to file {}", path); - return; + if (file.WriteBytes(&header, sizeof(header)) != sizeof(header) || + file.WriteBytes(buffer.data(), buffer.size()) != buffer.size()) { + throw std::runtime_error("Could not write to file " + path); } } void System::LoadState(u32 slot) { if (Network::GetRoomMember().lock()->IsConnected()) { - LOG_ERROR(Core, "Unable to load while connected to multiplayer"); - return; + throw std::runtime_error("Unable to load while connected to multiplayer"); } const auto path = GetSaveStatePath(title_id, slot); - if (!FileUtil::Exists(path)) { - LOG_ERROR(Core, "File not exist {}", path); - return; - } std::vector<u8> decompressed; { std::vector<u8> buffer(FileUtil::GetSize(path) - sizeof(CSTHeader)); FileUtil::IOFile file(path, "rb"); - if (!file) { - LOG_ERROR(Core, "Could not open file {}", path); - return; - } file.Seek(sizeof(CSTHeader), SEEK_SET); // Skip header if (file.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { - LOG_ERROR(Core, "Could not read from file {}", path); - return; + throw std::runtime_error("Could not read from file at " + path); } decompressed = Common::Compression::DecompressDataZSTD(buffer); } @@ -166,12 +148,9 @@ void System::LoadState(u32 slot) { std::ios_base::binary}; decompressed.clear(); - try { - iarchive ia{sstream}; - ia&* this; - } catch (const std::exception& e) { - LOG_ERROR(Core, "Error loading: {}", e.what()); - } + // Deserialize + iarchive ia{sstream}; + ia&* this; } } // namespace Core From 4d6bd9b569fca16325d6c3968bd68d4a6290c172 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 13 Apr 2020 11:50:27 +0100 Subject: [PATCH 125/129] Fix the merge --- src/citra_qt/debugger/wait_tree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/citra_qt/debugger/wait_tree.cpp b/src/citra_qt/debugger/wait_tree.cpp index 66b047e75..32ee7a1df 100644 --- a/src/citra_qt/debugger/wait_tree.cpp +++ b/src/citra_qt/debugger/wait_tree.cpp @@ -216,7 +216,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren()); const auto& thread = static_cast<const Kernel::Thread&>(object); - const auto* process = thread.owner_process; + const auto& process = thread.owner_process; QString processor; switch (thread.processor_id) { From 3a651ac9fcb1630ebedc7668b43612815f078f11 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Mon, 13 Apr 2020 18:08:15 +0100 Subject: [PATCH 126/129] Fix clang format --- src/core/core.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/core.h b/src/core/core.h index dca6a6888..e7fbd8ee3 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -316,7 +316,8 @@ private: * @param system_mode The system mode. * @return ResultStatus code, indicating if the operation succeeded. */ - ResultStatus Init(Frontend::EmuWindow& emu_window, u32 system_mode, u8 n3ds_mode, u32 num_cores); + ResultStatus Init(Frontend::EmuWindow& emu_window, u32 system_mode, u8 n3ds_mode, + u32 num_cores); /// Reschedule the core emulation void Reschedule(); From 824453b133f1873a1113c2c6f7fdc901116ebbad Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Thu, 16 Apr 2020 19:04:04 +0100 Subject: [PATCH 127/129] Remove the build type from the bin path --- .travis/linux/upload.sh | 6 +++--- .travis/macos/upload.sh | 6 +++--- CMakeLists.txt | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis/linux/upload.sh b/.travis/linux/upload.sh index c40c0d71e..548ee4905 100755 --- a/.travis/linux/upload.sh +++ b/.travis/linux/upload.sh @@ -8,9 +8,9 @@ COMPRESSION_FLAGS="-cJvf" mkdir "$REV_NAME" -cp build/bin/Release/citra "$REV_NAME" -cp build/bin/Release/citra-room "$REV_NAME" -cp build/bin/Release/citra-qt "$REV_NAME" +cp build/bin/citra "$REV_NAME" +cp build/bin/citra-room "$REV_NAME" +cp build/bin/citra-qt "$REV_NAME" # We need icons on Linux for .desktop entries mkdir "$REV_NAME/dist" diff --git a/.travis/macos/upload.sh b/.travis/macos/upload.sh index 05760c0b4..bdd7d7da7 100755 --- a/.travis/macos/upload.sh +++ b/.travis/macos/upload.sh @@ -8,9 +8,9 @@ COMPRESSION_FLAGS="-czvf" mkdir "$REV_NAME" -cp build/bin/Release/citra "$REV_NAME" -cp -r build/bin/Release/citra-qt.app "$REV_NAME" -cp build/bin/Release/citra-room "$REV_NAME" +cp build/bin/citra "$REV_NAME" +cp -r build/bin/citra-qt.app "$REV_NAME" +cp build/bin/citra-room "$REV_NAME" # move libs into folder for deployment macpack "${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt" -d "../Frameworks" diff --git a/CMakeLists.txt b/CMakeLists.txt index 50153c808..e85534e8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,7 +126,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # set up output paths for executable binaries -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) # System imported libraries From d6c84227d85a9a2935c991b49513e26379c24600 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Thu, 16 Apr 2020 20:44:25 +0100 Subject: [PATCH 128/129] Fixed NWM not responding --- src/core/hle/service/nwm/nwm_uds.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/hle/service/nwm/nwm_uds.cpp b/src/core/hle/service/nwm/nwm_uds.cpp index 8ebb8a6e3..cba699f25 100644 --- a/src/core/hle/service/nwm/nwm_uds.cpp +++ b/src/core/hle/service/nwm/nwm_uds.cpp @@ -552,8 +552,7 @@ boost::optional<Network::MacAddress> NWM_UDS::GetNodeMacAddress(u16 dest_node_id void NWM_UDS::Shutdown(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x03, 0, 0); - if (auto room_member = Network::GetRoomMember().lock()) - room_member->Unbind(wifi_packet_received); + initialized = false; for (auto bind_node : channel_data) { bind_node.second.event->Signal(); From f5b23eff4b9593f3212b16b964ec481565cf7fe9 Mon Sep 17 00:00:00 2001 From: Hamish Milne <hamishmilne83@gmail.com> Date: Fri, 17 Apr 2020 14:11:58 +0100 Subject: [PATCH 129/129] Correctly register AddressArbiter as a type of WakeupCallback --- src/core/hle/kernel/address_arbiter.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 059ff1400..c7a263d9e 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -11,6 +11,7 @@ #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/vector.hpp> +#include <boost/serialization/version.hpp> #include "common/common_types.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" @@ -81,6 +82,9 @@ private: template <class Archive> void serialize(Archive& ar, const unsigned int file_version) { ar& boost::serialization::base_object<Object>(*this); + if (file_version > 0) { + ar& boost::serialization::base_object<WakeupCallback>(*this); + } ar& name; ar& waiting_threads; } @@ -89,4 +93,5 @@ private: } // namespace Kernel BOOST_CLASS_EXPORT_KEY(Kernel::AddressArbiter) +BOOST_CLASS_VERSION(Kernel::AddressArbiter, 1) CONSTRUCT_KERNEL_OBJECT(Kernel::AddressArbiter)