@@ -28,29 +28,40 @@ void recomp_get_config_double(uint8_t* rdram, recomp_context* ctx, size_t mod_in
2828 }
2929}
3030
31+ template <typename StringType>
32+ void return_string (uint8_t * rdram, recomp_context* ctx, const StringType& str) {
33+ // Allocate space in the recomp heap to hold the string, including the null terminator.
34+ size_t alloc_size = (str.size () + 1 + 15 ) & ~15 ;
35+ gpr offset = reinterpret_cast <uint8_t *>(recomp::alloc (rdram, alloc_size)) - rdram;
36+ gpr addr = offset + 0xFFFFFFFF80000000ULL ;
37+
38+ // Copy the string's data into the allocated memory and null terminate it.
39+ for (size_t i = 0 ; i < str.size (); i++) {
40+ MEM_B (i, addr) = str[i];
41+ }
42+ MEM_B (str.size (), addr) = 0 ;
43+
44+ // Return the allocated memory.
45+ ctx->r2 = addr;
46+ }
47+
3148void recomp_get_config_string (uint8_t * rdram, recomp_context* ctx, size_t mod_index) {
3249 recomp::mods::ConfigValueVariant val = recomp::mods::get_mod_config_value (mod_index, _arg_string<0 >(rdram, ctx));
3350 if (std::string* as_string = std::get_if<std::string>(&val)) {
34- const std::string& str = *as_string;
35- // Allocate space in the recomp heap to hold the string, including the null terminator.
36- size_t alloc_size = (str.size () + 1 + 15 ) & ~15 ;
37- gpr offset = reinterpret_cast <uint8_t *>(recomp::alloc (rdram, alloc_size)) - rdram;
38- gpr addr = offset + 0xFFFFFFFF80000000ULL ;
39-
40- // Copy the string's data into the allocated memory and null terminate it.
41- for (size_t i = 0 ; i < str.size (); i++) {
42- MEM_B (i, addr) = str[i];
43- }
44- MEM_B (str.size (), addr) = 0 ;
45-
46- // Return the allocated memory.
47- ctx->r2 = addr;
51+ return_string (rdram, ctx, *as_string);
4852 }
4953 else {
5054 _return (ctx, NULLPTR);
5155 }
5256}
5357
58+ void recomp_free_config_string (uint8_t * rdram, recomp_context* ctx) {
59+ gpr str_rdram = (gpr)_arg<0 , PTR (char )>(rdram, ctx);
60+ gpr offset = str_rdram - 0xFFFFFFFF80000000ULL ;
61+
62+ recomp::free (rdram, rdram + offset);
63+ }
64+
5465void recomp_get_mod_version (uint8_t * rdram, recomp_context* ctx, size_t mod_index) {
5566 uint32_t * major_out = _arg<0 , uint32_t *>(rdram, ctx);
5667 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
7384 ultramodern::change_save_file (mod_id_u8, name_u8);
7485}
7586
76- void recomp_free_config_string (uint8_t * rdram, recomp_context* ctx) {
77- gpr str_rdram = (gpr)_arg<0 , PTR (char )>(rdram, ctx);
78- gpr offset = str_rdram - 0xFFFFFFFF80000000ULL ;
87+ void recomp_get_save_file_path (uint8_t * rdram, recomp_context* ctx) {
88+ std::filesystem::path save_file_path = ultramodern::get_save_file_path ();
7989
80- recomp::free (rdram, rdram + offset);
90+ return_string (rdram, ctx, std::filesystem::absolute (save_file_path). u8string ());
8191}
8292
8393void recomp::mods::register_config_exports () {
8494 recomp::overlays::register_ext_base_export (" recomp_get_config_u32" , recomp_get_config_u32);
8595 recomp::overlays::register_ext_base_export (" recomp_get_config_double" , recomp_get_config_double);
8696 recomp::overlays::register_ext_base_export (" recomp_get_config_string" , recomp_get_config_string);
97+ recomp::overlays::register_base_export (" recomp_free_config_string" , recomp_free_config_string);
8798 recomp::overlays::register_ext_base_export (" recomp_get_mod_version" , recomp_get_mod_version);
8899 recomp::overlays::register_ext_base_export (" recomp_change_save_file" , recomp_change_save_file);
89- recomp::overlays::register_base_export (" recomp_free_config_string " , recomp_free_config_string );
100+ recomp::overlays::register_base_export (" recomp_get_save_file_path " , recomp_get_save_file_path );
90101}
0 commit comments