Finish integration

This commit is contained in:
dcvz 2024-05-20 01:35:12 +02:00
parent 137009940c
commit 9307b56f46
2 changed files with 46 additions and 17 deletions

View file

@ -30,6 +30,7 @@ namespace recomp {
OtherError
};
GameHandle register_game(const recomp::GameEntry& entry);
void register_patch(const char* patch, std::size_t size);
void check_all_stored_roms();
bool load_stored_rom(GameHandle game);
RomValidationError select_rom(const std::filesystem::path& rom_path, GameHandle game);

View file

@ -27,6 +27,19 @@ constexpr uint32_t byteswap(uint32_t val) {
}
#endif
enum GameStatus {
None,
Running,
Quit
};
// Mutexes
std::mutex game_roms_mutex;
std::mutex patch_data_mutex;
std::mutex current_game_mutex;
// Global variables
std::vector<char> patch_data;
std::unordered_map<uint64_t, recomp::GameEntry> game_roms {};
std::string recomp::GameEntry::stored_filename() const {
@ -34,10 +47,16 @@ std::string recomp::GameEntry::stored_filename() const {
}
recomp::GameHandle recomp::register_game(const recomp::GameEntry& entry) {
std::lock_guard<std::mutex> lock(game_roms_mutex);
game_roms.insert({ entry.rom_hash, entry });
return { entry.rom_hash };
}
void recomp::register_patch(const char* patch, std::size_t size) {
std::lock_guard<std::mutex> lock(patch_data_mutex);
std::memcpy(patch_data.data(), patch, size);
}
bool check_hash(const std::vector<uint8_t>& rom_data, uint64_t expected_hash) {
uint64_t calculated_hash = XXH3_64bits(rom_data.data(), rom_data.size());
return calculated_hash == expected_hash;
@ -157,8 +176,6 @@ ByteswapType check_rom_start(const std::vector<uint8_t>& rom_data) {
return ByteswapType::Invalid;
}
bool matched_all = true;
auto check_match = [&](uint8_t index0, uint8_t index1, uint8_t index2, uint8_t index3) {
return
rom_data[0] == first_rom_bytes[index0] &&
@ -328,8 +345,11 @@ gpr get_entrypoint_address();
const char* get_rom_name();
void read_patch_data(uint8_t* rdram, gpr patch_data_address) {
for (size_t i = 0; i < sizeof(mm_patches_bin); i++) {
MEM_B(i, patch_data_address) = mm_patches_bin[i];
// for (size_t i = 0; i < sizeof(pa); i++) {
// MEM_B(i, patch_data_address) = mm_patches_bin[i];
// }
for (size_t i = 0; i < patch_data.size(); i++) {
MEM_B(i, patch_data_address) = patch_data[i];
}
}
@ -371,15 +391,17 @@ void init(uint8_t* rdram, recomp_context* ctx) {
MEM_W(osMemSize, 0) = 8 * 1024 * 1024; // 8MB
}
std::atomic<std::optional<recomp::GameHandle>> game_started = std::nullopt;
std::optional<recomp::GameHandle> current_game = std::nullopt;
std::atomic<GameStatus> game_status = GameStatus::None;
void recomp::start_game(recomp::GameHandle game) {
game_started.store(game);
game_started.notify_all();
std::lock_guard<std::mutex> lock(current_game_mutex);
current_game = game;
game_status.store(GameStatus::Running);
}
bool ultramodern::is_game_started() {
return game_started.load() != std::nullopt;
return game_status.load() != GameStatus::None;
}
void set_audio_callbacks(const ultramodern::audio_callbacks_t& callbacks);
@ -389,9 +411,11 @@ std::atomic_bool exited = false;
void ultramodern::quit() {
exited.store(true);
recomp::Game desired = recomp::Game::None;
game_started.compare_exchange_strong(desired, recomp::Game::Quit);
game_started.notify_all();
GameStatus desired = GameStatus::None;
game_status.compare_exchange_strong(desired, GameStatus::Quit);
game_status.notify_all();
std::lock_guard<std::mutex> lock(current_game_mutex);
current_game.reset();
}
void recomp::start(ultramodern::WindowHandle window_handle, const ultramodern::audio_callbacks_t& audio_callbacks, const ultramodern::input_callbacks_t& input_callbacks, const ultramodern::gfx_callbacks_t& gfx_callbacks_) {
@ -427,16 +451,20 @@ void recomp::start(ultramodern::WindowHandle window_handle, const ultramodern::a
ultramodern::preinit(rdram, window_handle);
game_started.wait(recomp::Game::None);
game_status.wait(GameStatus::None);
recomp_context context{};
switch (game_started.load()) {
switch (game_status.load()) {
// TODO refactor this to allow a project to specify what entrypoint function to run for a give game.
case recomp::Game::MM:
if (!recomp::load_stored_rom(recomp::Game::MM)) {
case GameStatus::Running:
if (!recomp::load_stored_rom(current_game.value())) {
recomp::message_box("Error opening stored ROM! Please restart this program.");
}
ultramodern::load_shader_cache({mm_shader_cache_bytes, sizeof(mm_shader_cache_bytes)});
auto find_it = game_roms.find(current_game.value().id);
const recomp::GameEntry& game_entry = find_it->second;
ultramodern::load_shader_cache(game_entry.cache_data);
init(rdram, &context);
try {
recomp_entrypoint(rdram, &context);
@ -444,7 +472,7 @@ void recomp::start(ultramodern::WindowHandle window_handle, const ultramodern::a
}
break;
case recomp::Game::Quit:
case GameStatus::Quit:
break;
}