From df246532d82c2ef553d0ad9be0f54d3821de8e3c Mon Sep 17 00:00:00 2001 From: Rupert Carmichael <5050061-carmiker@users.noreply.gitlab.com> Date: Fri, 14 Jun 2024 19:54:15 -0400 Subject: [PATCH] program: Add support for loading firmware and saving RTC, BS-X download data --- bsnes/target-libretro/program.cpp | 119 +++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 17 deletions(-) diff --git a/bsnes/target-libretro/program.cpp b/bsnes/target-libretro/program.cpp index b06980957..d8bf5ddcb 100644 --- a/bsnes/target-libretro/program.cpp +++ b/bsnes/target-libretro/program.cpp @@ -250,6 +250,7 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) -> result = openRomBSMemory(name, mode); } } + return result; } @@ -490,34 +491,24 @@ auto Program::inputRumble(uint port, uint device, uint input, bool enable) -> vo auto Program::openRomSuperFamicom(string name, vfs::file::mode mode) -> shared_pointer { - if(name == "program.rom" && mode == vfs::file::mode::read) - { + string firmware{}; + if (name == "program.rom" && mode == vfs::file::mode::read) { return vfs::memory::file::open(superFamicom.program.data(), superFamicom.program.size()); } - - if(name == "data.rom" && mode == vfs::file::mode::read) - { + else if (name == "data.rom" && mode == vfs::file::mode::read) { return vfs::memory::file::open(superFamicom.data.data(), superFamicom.data.size()); } - - if(name == "expansion.rom" && mode == vfs::file::mode::read) - { + else if (name == "expansion.rom" && mode == vfs::file::mode::read) { return vfs::memory::file::open(superFamicom.expansion.data(), superFamicom.expansion.size()); } - - if(name == "msu1/data.rom") - { + else if (name == "msu1/data.rom") { return vfs::fs::file::open({Location::notsuffix(superFamicom.location), ".msu"}, mode); } - - if(name.match("msu1/track*.pcm")) - { + else if (name.match("msu1/track*.pcm")) { name.trimLeft("msu1/track", 1L); return vfs::fs::file::open({Location::notsuffix(superFamicom.location), name}, mode); } - - if(name == "save.ram") - { + else if (name == "save.ram") { string save_path; auto suffix = Location::suffix(base_name); @@ -531,6 +522,100 @@ auto Program::openRomSuperFamicom(string name, vfs::file::mode mode) -> shared_p return vfs::fs::file::open(save_path, mode); } + else if (name == "time.rtc") { + string time_path; + + auto suffix = Location::suffix(base_name); + auto base = Location::base(base_name.transform("\\", "/")); + + const char *save = nullptr; + if (environ_cb && environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &save) && save) + time_path = { string(save).transform("\\", "/"), "/", base.trimRight(suffix, 1L), ".rtc" }; + else + time_path = { base_name.trimRight(suffix, 1L), ".rtc" }; + + return vfs::fs::file::open(time_path, mode); + } + else if (name == "download.ram") { + string psr_path; + + auto suffix = Location::suffix(base_name); + auto base = Location::base(base_name.transform("\\", "/")); + + const char *save = nullptr; + if (environ_cb && environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &save) && save) + psr_path = { string(save).transform("\\", "/"), "/", base.trimRight(suffix, 1L), ".psr" }; + else + psr_path = { base_name.trimRight(suffix, 1L), ".psr" }; + + return vfs::fs::file::open(psr_path, mode); + } + else if (name == "arm6.program.rom" && mode == vfs::file::mode::read) { + if (superFamicom.firmware.size() == 0x28000) { + return vfs::memory::file::open(&superFamicom.firmware.data()[0x00000], 0x20000); + } + if (auto memory = superFamicom.document["game/board/memory(type=ROM,content=Program,architecture=ARM6)"]) { + firmware = string(memory["identifier"].text().downcase(), ".program.rom"); + } + } + else if (name == "arm6.data.rom" && mode == vfs::file::mode::read) { + if (superFamicom.firmware.size() == 0x28000) { + return vfs::memory::file::open(&superFamicom.firmware.data()[0x20000], 0x08000); + } + if (auto memory = superFamicom.document["game/board/memory(type=ROM,content=Data,architecture=ARM6)"]) { + firmware = string(memory["identifier"].text().downcase(), ".data.rom"); + } + } + else if (name == "hg51bs169.data.rom" && mode == vfs::file::mode::read) { + if (superFamicom.firmware.size() == 0xc00) { + return vfs::memory::file::open(superFamicom.firmware.data(), superFamicom.firmware.size()); + } + if (auto memory = superFamicom.document["game/board/memory(type=ROM,content=Data,architecture=HG51BS169)"]) { + firmware = string(memory["identifier"].text().downcase(), ".data.rom"); + } + } + else if (name == "upd7725.program.rom" && mode == vfs::file::mode::read) { + if (superFamicom.firmware.size() == 0x2000) { + return vfs::memory::file::open(&superFamicom.firmware.data()[0x0000], 0x1800); + } + if (auto memory = superFamicom.document["game/board/memory(type=ROM,content=Program,architecture=uPD7725)"]) { + firmware = string(memory["identifier"].text().downcase(), ".program.rom"); + } + } + else if (name == "upd7725.data.rom" && mode == vfs::file::mode::read) { + if (superFamicom.firmware.size() == 0x2000) { + return vfs::memory::file::open(&superFamicom.firmware.data()[0x1800], 0x0800); + } + if (auto memory = superFamicom.document["game/board/memory(type=ROM,content=Data,architecture=uPD7725)"]) { + firmware = string(memory["identifier"].text().downcase(), ".data.rom"); + } + } + else if (name == "upd96050.program.rom" && mode == vfs::file::mode::read) { + if (superFamicom.firmware.size() == 0xd000) { + return vfs::memory::file::open(&superFamicom.firmware.data()[0x0000], 0xc000); + } + if (auto memory = superFamicom.document["game/board/memory(type=ROM,content=Program,architecture=uPD96050)"]) { + firmware = string(memory["identifier"].text().downcase(), ".program.rom"); + } + } + else if (name == "upd96050.data.rom" && mode == vfs::file::mode::read) { + if (superFamicom.firmware.size() == 0xd000) { + return vfs::memory::file::open(&superFamicom.firmware.data()[0xc000], 0x1000); + } + if (auto memory = superFamicom.document["game/board/memory(type=ROM,content=Data,architecture=uPD96050)"]) { + firmware = string(memory["identifier"].text().downcase(), ".data.rom"); + } + } + + if (firmware) { + const char *system_dir; + environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir); + string firmware_path = string(system_dir, '/', firmware).transform("\\", "/"); + + if (file::exists(firmware_path)) { + return vfs::fs::file::open(firmware_path, mode); + } + } return {}; }