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 000000000..578174ec6 Binary files /dev/null and b/save0.citrasave differ 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}; }