diff --git a/src/common/assert.h b/src/common/assert.h index c056066a64..0d4eddc194 100644 --- a/src/common/assert.h +++ b/src/common/assert.h @@ -28,17 +28,18 @@ __declspec(noinline, noreturn) } #define ASSERT(_a_) \ - if (!(_a_)) { \ - } + do \ + if (!(_a_)) { \ + assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \ + } \ + while (0) #define ASSERT_MSG(_a_, ...) \ - if (!(_a_)) { \ - } -/*do \ - if (!(_a_)) { \ - assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \ - } \ -while (0)*/ + do \ + if (!(_a_)) { \ + assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \ + } \ + while (0) #define UNREACHABLE() ASSERT_MSG(false, "Unreachable code!") #define UNREACHABLE_MSG(...) ASSERT_MSG(false, __VA_ARGS__) diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 66b74047d2..c12092eb0f 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma optimize("", off) - #include #include "common/common_types.h" #include "common/logging/log.h" @@ -56,6 +54,9 @@ ResultVal> SaveDataFactory::Open(SaveDataSpac std::string save_directory = GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); + // TODO(DarkLordZach): Try to not create when opening, there are dedicated create save methods. + // But, user_ids don't match so this works for now. + if (!FileUtil::Exists(save_directory)) { // TODO(bunnei): This is a work-around to always create a save data directory if it does not // already exist. This is a hack, as we do not understand yet how this works on hardware. @@ -64,6 +65,8 @@ ResultVal> SaveDataFactory::Open(SaveDataSpac FileUtil::CreateFullPath(save_directory); } + // TODO(DarkLordZach): For some reason, CreateFullPath dosen't create the last bit. Should be + // fixed with VFS. if (!FileUtil::IsDirectory(save_directory)) { FileUtil::CreateDir(save_directory); } @@ -81,10 +84,27 @@ ResultVal> SaveDataFactory::Open(SaveDataSpac ResultCode SaveDataFactory::Format(SaveDataSpaceId space, SaveStruct meta) { LOG_WARNING(Service_FS, "Formatting save data of space={:01X}, meta={}", static_cast(space), SaveStructDebugInfo(meta)); + std::string save_directory = + GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); + // Create the save data directory. - if (!FileUtil::CreateFullPath( - GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id))) { - // TODO(Subv): Find the correct error code. + if (!FileUtil::Exists(save_directory)) { + // TODO(bunnei): This is a work-around to always create a save data directory if it does not + // already exist. This is a hack, as we do not understand yet how this works on hardware. + // Without a save data directory, many games will assert on boot. This should not have any + // bad side-effects. + FileUtil::CreateFullPath(save_directory); + } + + // TODO(DarkLordZach): For some reason, CreateFullPath dosen't create the last bit. Should be + // fixed with VFS. + if (!FileUtil::IsDirectory(save_directory)) { + FileUtil::CreateDir(save_directory); + } + + // Return an error if the save data doesn't actually exist. + if (!FileUtil::IsDirectory(save_directory)) { + // TODO(Subv): Find out correct error code. return ResultCode(-1); } diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index ec6dc22b72..ee6b160b38 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -4,9 +4,11 @@ #include #include +#include "core/core.h" #include "core/file_sys/filesystem.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" @@ -614,20 +616,37 @@ void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest( void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - u128 uid = rp.PopRaw(); + u128 uid = rp.PopRaw(); // What does this do? - FileSys::SaveDataSpaceId space = FileSys::SaveDataSpaceId::NandUser; - FileSys::SaveStruct save_struct = {}; + // TODO(DarkLordZach): So the next bit is a huge assumption. I don't think this method is + // supposed to do this, as there is no savestruct provided. + + FileSys::SaveDataSpaceId space = FileSys::SaveDataSpaceId::NandUser; // Default space + FileSys::SaveStruct save_struct = { + 0, // Default title id (ends up as current process) + {0, 0}, // Default user id + 0, // Default save id + FileSys::SaveDataType::SaveData, // User save data + 0, // Begin Padding + 0, // | + 0, // | + 0, // | + 0, // | + 0, // | + 0, // End Padding + 0, // Unknown field - should be zero + 0, // Unknown field - should be zero + 0 // Unknown field - should be zero + }; LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); IPC::ResponseBuilder rb{ctx, 4}; - FileSys::Path unused; - // auto savedata = FileSystem::OpenSaveData(space, save_struct); - if (true) { + auto savedata = FileSystem::OpenSaveData(space, save_struct); + if (savedata.Failed()) { // Create the save data and return an error indicating that the operation was performed. - // FileSystem::FormatSaveData(space, save_struct); + FileSystem::FormatSaveData(space, save_struct); // TODO(Subv): Find out the correct error code for this. rb.Push(ResultCode(ErrorModule::FS, 40)); } else { @@ -635,7 +654,7 @@ void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { } rb.Push(0); -} +} // namespace Service::AM void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) { // Takes an input u32 Result, no output. diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 6502e20356..0eb0ac5d89 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -520,12 +520,12 @@ void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - auto save_struct = rp.PopRaw>(); + auto save_struct = rp.PopRaw(); auto save_create_struct = rp.PopRaw>(); u128 uid = rp.PopRaw(); - FileSys::SaveStruct structs = *reinterpret_cast(save_struct.data()); - LOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]); + LOG_WARNING(Service_FS, "(STUBBED) called save_struct = {}, uid = {:016X}{:016X}", + FileSys::SaveStructDebugInfo(save_struct), uid[1], uid[0]); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS);