From bb6b3b1645a582b8d9305f221375da9d3563ee60 Mon Sep 17 00:00:00 2001 From: Wiseguy <68165316+Mr-Wiseguy@users.noreply.github.com> Date: Wed, 9 Apr 2025 01:15:10 -0400 Subject: [PATCH] Add mod API export to get the save file path (#102) --- librecomp/src/mod_config_api.cpp | 49 ++++++++++++------- librecomp/src/pi.cpp | 8 +-- .../include/ultramodern/ultramodern.hpp | 2 + 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/librecomp/src/mod_config_api.cpp b/librecomp/src/mod_config_api.cpp index 9878a7a..36574cd 100644 --- a/librecomp/src/mod_config_api.cpp +++ b/librecomp/src/mod_config_api.cpp @@ -28,29 +28,40 @@ void recomp_get_config_double(uint8_t* rdram, recomp_context* ctx, size_t mod_in } } +template +void return_string(uint8_t* rdram, recomp_context* ctx, const StringType& str) { + // Allocate space in the recomp heap to hold the string, including the null terminator. + size_t alloc_size = (str.size() + 1 + 15) & ~15; + gpr offset = reinterpret_cast(recomp::alloc(rdram, alloc_size)) - rdram; + gpr addr = offset + 0xFFFFFFFF80000000ULL; + + // Copy the string's data into the allocated memory and null terminate it. + for (size_t i = 0; i < str.size(); i++) { + MEM_B(i, addr) = str[i]; + } + MEM_B(str.size(), addr) = 0; + + // Return the allocated memory. + ctx->r2 = addr; +} + void recomp_get_config_string(uint8_t* rdram, recomp_context* ctx, size_t mod_index) { recomp::mods::ConfigValueVariant val = recomp::mods::get_mod_config_value(mod_index, _arg_string<0>(rdram, ctx)); if (std::string* as_string = std::get_if(&val)) { - const std::string& str = *as_string; - // Allocate space in the recomp heap to hold the string, including the null terminator. - size_t alloc_size = (str.size() + 1 + 15) & ~15; - gpr offset = reinterpret_cast(recomp::alloc(rdram, alloc_size)) - rdram; - gpr addr = offset + 0xFFFFFFFF80000000ULL; - - // Copy the string's data into the allocated memory and null terminate it. - for (size_t i = 0; i < str.size(); i++) { - MEM_B(i, addr) = str[i]; - } - MEM_B(str.size(), addr) = 0; - - // Return the allocated memory. - ctx->r2 = addr; + return_string(rdram, ctx, *as_string); } else { _return(ctx, NULLPTR); } } +void recomp_free_config_string(uint8_t* rdram, recomp_context* ctx) { + gpr str_rdram = (gpr)_arg<0, PTR(char)>(rdram, ctx); + gpr offset = str_rdram - 0xFFFFFFFF80000000ULL; + + recomp::free(rdram, rdram + offset); +} + void recomp_get_mod_version(uint8_t* rdram, recomp_context* ctx, size_t mod_index) { uint32_t* major_out = _arg<0, uint32_t*>(rdram, ctx); uint32_t* minor_out = _arg<1, uint32_t*>(rdram, ctx); @@ -73,18 +84,18 @@ void recomp_change_save_file(uint8_t* rdram, recomp_context* ctx, size_t mod_ind ultramodern::change_save_file(mod_id_u8, name_u8); } -void recomp_free_config_string(uint8_t* rdram, recomp_context* ctx) { - gpr str_rdram = (gpr)_arg<0, PTR(char)>(rdram, ctx); - gpr offset = str_rdram - 0xFFFFFFFF80000000ULL; +void recomp_get_save_file_path(uint8_t* rdram, recomp_context* ctx) { + std::filesystem::path save_file_path = ultramodern::get_save_file_path(); - recomp::free(rdram, rdram + offset); + return_string(rdram, ctx, std::filesystem::absolute(save_file_path).u8string()); } void recomp::mods::register_config_exports() { recomp::overlays::register_ext_base_export("recomp_get_config_u32", recomp_get_config_u32); recomp::overlays::register_ext_base_export("recomp_get_config_double", recomp_get_config_double); recomp::overlays::register_ext_base_export("recomp_get_config_string", recomp_get_config_string); + recomp::overlays::register_base_export("recomp_free_config_string", recomp_free_config_string); recomp::overlays::register_ext_base_export("recomp_get_mod_version", recomp_get_mod_version); recomp::overlays::register_ext_base_export("recomp_change_save_file", recomp_change_save_file); - recomp::overlays::register_base_export("recomp_free_config_string", recomp_free_config_string); + recomp::overlays::register_base_export("recomp_get_save_file_path", recomp_get_save_file_path); } diff --git a/librecomp/src/pi.cpp b/librecomp/src/pi.cpp index aa5b17f..dcfed71 100644 --- a/librecomp/src/pi.cpp +++ b/librecomp/src/pi.cpp @@ -101,7 +101,7 @@ const std::u8string save_folder = u8"saves"; extern std::filesystem::path config_path; -std::filesystem::path get_save_file_path() { +std::filesystem::path ultramodern::get_save_file_path() { return save_context.save_file_path; } @@ -116,7 +116,7 @@ void set_save_file_path(const std::u8string& subfolder, const std::u8string& nam void update_save_file() { bool saving_failed = false; { - std::ofstream save_file = recomp::open_output_file_with_backup(get_save_file_path(), std::ios_base::binary); + std::ofstream save_file = recomp::open_output_file_with_backup(ultramodern::get_save_file_path(), std::ios_base::binary); if (save_file.good()) { std::lock_guard lock{ save_context.save_buffer_mutex }; @@ -127,7 +127,7 @@ void update_save_file() { } } if (!saving_failed) { - saving_failed = !recomp::finalize_output_file_with_backup(get_save_file_path()); + saving_failed = !recomp::finalize_output_file_with_backup(ultramodern::get_save_file_path()); } if (saving_failed) { ultramodern::error_handling::message_box("Failed to write to the save file. Check your file permissions and whether the save folder has been moved to Dropbox or similar, as this can cause issues."); @@ -225,7 +225,7 @@ size_t get_save_size(recomp::SaveType save_type) { } void read_save_file() { - std::filesystem::path save_file_path = get_save_file_path(); + std::filesystem::path save_file_path = ultramodern::get_save_file_path(); // Ensure the save file directory exists. std::filesystem::create_directories(save_file_path.parent_path()); diff --git a/ultramodern/include/ultramodern/ultramodern.hpp b/ultramodern/include/ultramodern/ultramodern.hpp index 838a8ca..db45ee4 100644 --- a/ultramodern/include/ultramodern/ultramodern.hpp +++ b/ultramodern/include/ultramodern/ultramodern.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #undef MOODYCAMEL_DELETE_FUNCTION #define MOODYCAMEL_DELETE_FUNCTION = delete @@ -39,6 +40,7 @@ void init_thread_cleanup(); // Saving void change_save_file(const std::u8string& subfolder, const std::u8string& name); +std::filesystem::path get_save_file_path(); // Thread queues. constexpr PTR(PTR(OSThread)) running_queue = (PTR(PTR(OSThread)))-1;