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); \ } \