diff --git a/librecomp/CMakeLists.txt b/librecomp/CMakeLists.txt index 2445453..745769a 100644 --- a/librecomp/CMakeLists.txt +++ b/librecomp/CMakeLists.txt @@ -29,7 +29,15 @@ add_library(librecomp STATIC "${CMAKE_CURRENT_SOURCE_DIR}/src/ultra_translation.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/vi.cpp") -target_include_directories(librecomp PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_include_directories(librecomp PRIVATE "${CMAKE_SOURCE_DIR}/rt64/src/contrib") +target_include_directories(librecomp PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_SOURCE_DIR}/ultramodern/include" + "${CMAKE_SOURCE_DIR}/thirdparty/concurrentqueue" +) +target_include_directories(librecomp PRIVATE + "${CMAKE_SOURCE_DIR}/rt64/src/contrib" +) + target_compile_options(librecomp PRIVATE -Wno-deprecated-declarations) + target_link_libraries(librecomp PRIVATE ultramodern) diff --git a/librecomp/include/recomp.h b/librecomp/include/recomp.h index 57eb7da..87bd054 100644 --- a/librecomp/include/recomp.h +++ b/librecomp/include/recomp.h @@ -256,7 +256,7 @@ recomp_func_t* get_function(int32_t vram); #define LOOKUP_FUNC(val) \ get_function((int32_t)(val)) -extern int32_t section_addresses[]; +extern int32_t* section_addresses; #define LO16(x) \ ((x) & 0xFFFF) diff --git a/librecomp/include/recomp_game.h b/librecomp/include/recomp_game.h index 39b2828..fccbfc9 100644 --- a/librecomp/include/recomp_game.h +++ b/librecomp/include/recomp_game.h @@ -43,6 +43,10 @@ namespace recomp { void message_box(const char* message); std::filesystem::path get_app_folder_path(); std::u8string current_game_id(); + + // TODO: implement both + const std::u8string& get_program_id(); + void set_program_id(const std::u8string& program_id); } #endif diff --git a/librecomp/include/recomp_overlays.h b/librecomp/include/recomp_overlays.h index cf1f8a1..1589e30 100644 --- a/librecomp/include/recomp_overlays.h +++ b/librecomp/include/recomp_overlays.h @@ -2,9 +2,26 @@ #define __RECOMP_OVERLAYS_H__ #include +#include "sections.h" + +namespace recomp { + struct overlay_section_table_data_t { + SectionTableEntry* code_sections; + size_t num_code_sections; + size_t total_num_sections; + }; + + struct overlays_by_index_t { + int* table; + size_t len; + }; + + extern void register_overlays(const overlay_section_table_data_t& sections, const overlays_by_index_t& overlays); + extern void register_patch_section(SectionTableEntry* code_sections); +}; extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size); extern "C" void unload_overlays(int32_t ram_addr, uint32_t size); void init_overlays(); -#endif \ No newline at end of file +#endif diff --git a/librecomp/src/overlays.cpp b/librecomp/src/overlays.cpp index 3295552..a091470 100644 --- a/librecomp/src/overlays.cpp +++ b/librecomp/src/overlays.cpp @@ -1,13 +1,19 @@ -#include #include +#include +#include #include + #include "recomp.h" #include "recomp_overlays.h" -#include "../RecompiledFuncs/recomp_overlays.inl" +#include "sections.h" -constexpr size_t num_code_sections = ARRLEN(section_table); +static recomp::overlay_section_table_data_t sections_info {}; +static recomp::overlays_by_index_t overlays_info {}; -// SectionTableEntry sections[] defined in recomp_overlays.inl +void recomp::register_overlays(const recomp::overlay_section_table_data_t& sections, const recomp::overlays_by_index_t& overlays) { + sections_info = sections; + overlays_info = overlays; +} struct LoadedSection { int32_t loaded_ram_addr; @@ -27,11 +33,13 @@ std::vector loaded_sections{}; std::unordered_map func_map{}; void load_overlay(size_t section_table_index, int32_t ram) { - const SectionTableEntry& section = section_table[section_table_index]; + const SectionTableEntry& section = sections_info.code_sections[section_table_index]; + for (size_t function_index = 0; function_index < section.num_funcs; function_index++) { const FuncEntry& func = section.funcs[function_index]; func_map[ram + func.offset] = func.func; } + loaded_sections.emplace_back(ram, section_table_index); section_addresses[section.index] = ram; } @@ -45,33 +53,31 @@ void load_special_overlay(const SectionTableEntry& section, int32_t ram) { extern "C" { -int32_t section_addresses[num_sections]; +int32_t* section_addresses = nullptr; } extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size) { // Search for the first section that's included in the loaded rom range // Sections were sorted by `init_overlays` so we can use the bounds functions - auto lower = std::lower_bound(§ion_table[0], §ion_table[num_code_sections], rom, + auto lower = std::lower_bound(§ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], rom, [](const SectionTableEntry& entry, uint32_t addr) { return entry.rom_addr < addr; } ); - auto upper = std::upper_bound(§ion_table[0], §ion_table[num_code_sections], (uint32_t)(rom + size), + auto upper = std::upper_bound(§ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], (uint32_t)(rom + size), [](uint32_t addr, const SectionTableEntry& entry) { return addr < entry.size + entry.rom_addr; } ); // Load the overlays that were found for (auto it = lower; it != upper; ++it) { - load_overlay(std::distance(§ion_table[0], it), it->rom_addr - rom + ram_addr); + load_overlay(std::distance(§ions_info.code_sections[0], it), it->rom_addr - rom + ram_addr); } } -extern "C" void unload_overlays(int32_t ram_addr, uint32_t size); - extern "C" void unload_overlay_by_id(uint32_t id) { - uint32_t section_table_index = overlay_sections_by_index[id]; - const SectionTableEntry& section = section_table[section_table_index]; + uint32_t section_table_index = overlays_info.table[id]; + const SectionTableEntry& section = sections_info.code_sections[section_table_index]; auto find_it = std::find_if(loaded_sections.begin(), loaded_sections.end(), [section_table_index](const LoadedSection& s) { return s.section_table_index == section_table_index; }); @@ -90,8 +96,8 @@ extern "C" void unload_overlay_by_id(uint32_t id) { } extern "C" void load_overlay_by_id(uint32_t id, uint32_t ram_addr) { - uint32_t section_table_index = overlay_sections_by_index[id]; - const SectionTableEntry& section = section_table[section_table_index]; + uint32_t section_table_index = overlays_info.table[id]; + const SectionTableEntry& section = sections_info.code_sections[section_table_index]; int32_t prev_address = section_addresses[section.index]; if (/*ram_addr >= 0x80000000 && ram_addr < 0x81000000) {*/ prev_address == section.ram_addr) { load_overlay(section_table_index, ram_addr); @@ -105,7 +111,7 @@ extern "C" void load_overlay_by_id(uint32_t id, uint32_t ram_addr) { extern "C" void unload_overlays(int32_t ram_addr, uint32_t size) { for (auto it = loaded_sections.begin(); it != loaded_sections.end();) { - const auto& section = section_table[it->section_table_index]; + const auto& section = sections_info.code_sections[it->section_table_index]; // Check if the unloaded region overlaps with the loaded section if (ram_addr < (it->loaded_ram_addr + section.size) && (ram_addr + size) >= it->loaded_ram_addr) { @@ -139,12 +145,14 @@ extern "C" void unload_overlays(int32_t ram_addr, uint32_t size) { void load_patch_functions(); void init_overlays() { - for (size_t section_index = 0; section_index < num_code_sections; section_index++) { - section_addresses[section_table[section_index].index] = section_table[section_index].ram_addr; + section_addresses = (int32_t *)malloc(sections_info.total_num_sections * sizeof(int32_t)); + + for (size_t section_index = 0; section_index < sections_info.total_num_sections; section_index++) { + section_addresses[sections_info.code_sections[section_index].index] = sections_info.code_sections[section_index].ram_addr; } // Sort the executable sections by rom address - std::sort(§ion_table[0], §ion_table[num_code_sections], + std::sort(§ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], [](const SectionTableEntry& a, const SectionTableEntry& b) { return a.rom_addr < b.rom_addr; } diff --git a/librecomp/src/patch_loading.cpp b/librecomp/src/patch_loading.cpp index 660d6a5..0e8effd 100644 --- a/librecomp/src/patch_loading.cpp +++ b/librecomp/src/patch_loading.cpp @@ -2,10 +2,17 @@ #include #include #include "recomp.h" -#include "../../RecompiledPatches/recomp_overlays.inl" +#include "sections.h" +#include "recomp_overlays.h" + +static SectionTableEntry* code_sections = nullptr; void load_special_overlay(const SectionTableEntry& section, int32_t ram); -void load_patch_functions() { - load_special_overlay(section_table[0], section_table[0].ram_addr); +void register_patch_section(SectionTableEntry* sections) { + code_sections = sections; +} + +void load_patch_functions() { + load_special_overlay(code_sections[0], code_sections[0].ram_addr); } diff --git a/librecomp/src/recomp.cpp b/librecomp/src/recomp.cpp index ba4d4ae..b16f5d6 100644 --- a/librecomp/src/recomp.cpp +++ b/librecomp/src/recomp.cpp @@ -1,6 +1,3 @@ -#ifdef _WIN32 -#include -#endif #include #include #include @@ -10,12 +7,19 @@ #include #include #include +#include + +#ifdef _WIN32 +#include +#elif defined(__linux__) +#include +#endif + #include "recomp.h" #include "recomp_overlays.h" #include "recomp_game.h" #include "xxHash/xxh3.h" #include -//#include "../../RecompiledPatches/patches_bin.h" #ifdef _MSC_VER inline uint32_t byteswap(uint32_t val) { @@ -98,7 +102,7 @@ std::filesystem::path recomp::get_app_folder_path() { PWSTR known_path = NULL; HRESULT result = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &known_path); if (result == S_OK) { - recomp_dir = std::filesystem::path{known_path} / recomp::program_id; + recomp_dir = std::filesystem::path{known_path} / recomp::get_program_id(); } CoTaskMemFree(known_path); @@ -110,7 +114,7 @@ std::filesystem::path recomp::get_app_folder_path() { } if (homedir != nullptr) { - recomp_dir = std::filesystem::path{homedir} / (std::u8string{u8".config/"} + std::u8string{recomp::program_id}); + recomp_dir = std::filesystem::path{homedir} / (std::u8string{u8".config/"} + recomp::get_program_id()); } #endif @@ -448,9 +452,9 @@ void recomp::start(ultramodern::WindowHandle window_handle, const ultramodern::a std::thread game_thread{[](ultramodern::WindowHandle window_handle, uint8_t* rdram) { debug_printf("[Recomp] Starting\n"); - + ultramodern::set_native_thread_name("Game Start Thread"); - + ultramodern::preinit(rdram, window_handle); game_status.wait(GameStatus::None); @@ -459,25 +463,31 @@ void recomp::start(ultramodern::WindowHandle window_handle, const ultramodern::a switch (game_status.load()) { // TODO refactor this to allow a project to specify what entrypoint function to run for a give game. case GameStatus::Running: - if (!recomp::load_stored_rom(current_game.value())) { - recomp::message_box("Error opening stored ROM! Please restart this program."); + { + if (!recomp::load_stored_rom(current_game.value())) { + recomp::message_box("Error opening stored ROM! Please restart this program."); + } + + auto find_it = game_roms.find(current_game.value()); + const recomp::GameEntry& game_entry = find_it->second; + + ultramodern::load_shader_cache(game_entry.cache_data); + init(rdram, &context); + try { + recomp_entrypoint(rdram, &context); + } catch (ultramodern::thread_terminated& terminated) { + + } } - - auto find_it = game_roms.find(current_game.value()); - const recomp::GameEntry& game_entry = find_it->second; - - ultramodern::load_shader_cache(game_entry.cache_data); - init(rdram, &context); - try { - recomp_entrypoint(rdram, &context); - } catch (ultramodern::thread_terminated& terminated) { - - } break; + case GameStatus::Quit: break; + + case GameStatus::None: + break; } - + debug_printf("[Recomp] Quitting\n"); }, window_handle, rdram_buffer.get()};