diff --git a/CMakeLists.txt b/CMakeLists.txt index 788c7991b..8dad0965f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -922,6 +922,19 @@ target_sources(${PROJECT_NAME} PRIVATE core/hw/sh4/sh4_sched.h core/hw/sh4/storeq.cpp) +cmrc_add_resources(flycast-resources + WHENCE resources + resources/flash/gunsur2.nvmem.zip + resources/flash/otrigger.nvmem.zip + resources/flash/wldkicks.nvmem.zip # free play + resources/flash/wldkicksj.nvmem.zip # free play + resources/flash/wldkicksu.nvmem.zip # free play + resources/flash/f355.nvmem.zip # printer on + resources/flash/f355twin.nvmem.zip + resources/flash/f355twn2.nvmem.zip + resources/flash/dirtypig.nvmem.zip # 4 players + resources/flash/dirtypig.nvmem2.zip) + cmrc_add_resources(flycast-resources fonts/printer_ascii8x16.bin fonts/printer_ascii12x24.bin diff --git a/core/archive/ZipArchive.cpp b/core/archive/ZipArchive.cpp index 394f919ac..70b08c31b 100644 --- a/core/archive/ZipArchive.cpp +++ b/core/archive/ZipArchive.cpp @@ -88,3 +88,23 @@ u32 ZipArchiveFile::Read(void* buffer, u32 length) { return zip_fread(zip_file, buffer, length); } + +bool ZipArchive::Open(const void *data, size_t size) +{ + zip_error_t error; + zip_source_t *source = zip_source_buffer_create(data, size, 0, &error); + if (source == nullptr) + return false; + zip = zip_open_from_source(source, 0, NULL); + if (zip == nullptr) + zip_source_free(source); + return zip != nullptr; +} + +ArchiveFile *ZipArchive::OpenFirstFile() +{ + zip_file *zipFile = zip_fopen_index(zip, 0, 0); + if (zipFile == nullptr) + return nullptr; + return new ZipArchiveFile(zipFile); +} diff --git a/core/archive/ZipArchive.h b/core/archive/ZipArchive.h index d14dca812..697fd6a48 100644 --- a/core/archive/ZipArchive.h +++ b/core/archive/ZipArchive.h @@ -32,6 +32,9 @@ public: ArchiveFile* OpenFile(const char* name) override; ArchiveFile* OpenFileByCrc(u32 crc) override; + bool Open(const void *data, size_t size); + ArchiveFile *OpenFirstFile(); + private: bool Open(const char* path) override; diff --git a/core/hw/flashrom/flashrom.cpp b/core/hw/flashrom/flashrom.cpp index f407fc48c..f848af3de 100644 --- a/core/hw/flashrom/flashrom.cpp +++ b/core/hw/flashrom/flashrom.cpp @@ -33,6 +33,12 @@ bool MemChip::Load(const std::string& file) return false; } +void MemChip::Load(const u8 *data, size_t size) +{ + verify(size == this->size - write_protect_size); + memcpy(this->data + write_protect_size, data, this->size - write_protect_size); +} + void WritableChip::Save(const std::string& file) { FILE *f = nowide::fopen(file.c_str(), "wb"); diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index 30cf0e396..1fd7d7c90 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -64,6 +64,7 @@ public: virtual bool Reload() { return true; } bool Load(const std::string &prefix, const std::string &names_ro, const std::string &title); + void Load(const u8 *data, size_t size); void digest(u8 md5Digest[16]); virtual void Reset() {} @@ -82,6 +83,8 @@ public: bool Reload() override { + if (load_filename.empty()) + return false; return Load(this->load_filename); } void Save(const std::string& file); diff --git a/core/hw/flashrom/nvmem.cpp b/core/hw/flashrom/nvmem.cpp index d1317b712..52dde4b34 100644 --- a/core/hw/flashrom/nvmem.cpp +++ b/core/hw/flashrom/nvmem.cpp @@ -22,6 +22,9 @@ #include "hw/aica/aica_if.h" #include "reios/reios.h" #include "oslib/oslib.h" +#include "archive/ZipArchive.h" +#include +CMRC_DECLARE(flycast); extern bool bios_loaded; @@ -193,13 +196,81 @@ static void fixUpDCFlash() } } +static std::unique_ptr loadFlashResource(const std::string& name, size_t& size) +{ + try { + cmrc::embedded_filesystem fs = cmrc::flycast::get_filesystem(); + std::string fname = "flash/" + name + ".zip"; + if (fs.exists(fname)) + { + cmrc::file zipFile = fs.open(fname); + ZipArchive zip; + if (zip.Open(zipFile.cbegin(), zipFile.size())) + { + std::unique_ptr flashFile; + flashFile.reset(zip.OpenFirstFile()); + if (flashFile != nullptr) + { + std::unique_ptr buffer = std::make_unique(size); + size = flashFile->Read(buffer.get(), size); + + return buffer; + } + } + } + else + { + cmrc::file flashFile = fs.open("flash/" + name); + size = flashFile.size(); + std::unique_ptr buffer = std::make_unique(size); + + return buffer; + } + DEBUG_LOG(FLASHROM, "Default flash not found"); + } catch (const std::system_error& e) { + DEBUG_LOG(FLASHROM, "Default flash not found: %s", e.what()); + } + size = 0; + return nullptr; +} + +static void loadDefaultAWBiosFlash() +{ + std::string flashName = get_game_basename() + ".nvmem2"; + size_t lastindex = get_last_slash_pos(flashName); + if (lastindex != std::string::npos) + flashName = flashName.substr(lastindex + 1); + + size_t size = settings.platform.bios_size / 2; + std::unique_ptr buffer = loadFlashResource(flashName, size); + if (buffer) + sys_rom->Load(buffer.get(), size); +} + static bool loadFlash() { bool rc = true; if (settings.platform.isConsole()) rc = sys_nvmem->Load(getRomPrefix(), "%nvmem.bin", "nvram"); else if (!settings.naomi.slave) + { rc = sys_nvmem->Load(hostfs::getArcadeFlashPath() + ".nvmem"); + if (!rc) + { + std::string flashName = get_game_basename() + ".nvmem"; + size_t lastindex = get_last_slash_pos(flashName); + if (lastindex != std::string::npos) + flashName = flashName.substr(lastindex + 1); + + size_t size = settings.platform.flash_size; + std::unique_ptr buffer = loadFlashResource(flashName, size); + if (buffer) + { + sys_nvmem->Load(buffer.get(), size); + rc = true; + } + } + } if (!rc) INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file..."); fixUpDCFlash(); @@ -208,7 +279,10 @@ static bool loadFlash() if (settings.platform.isAtomiswave()) { - sys_rom->Load(hostfs::getArcadeFlashPath() + ".nvmem2"); + rc = sys_rom->Load(hostfs::getArcadeFlashPath() + ".nvmem2"); + // TODO default AW .nvmem2 + if (!rc) + loadDefaultAWBiosFlash(); if (config::GGPOEnable) sys_nvmem->digest(settings.network.md5.nvmem2); } @@ -281,10 +355,14 @@ u8 *getBiosData() { return sys_rom->data; } + void reloadAWBios() { - if (settings.platform.isAtomiswave()) - sys_rom->Reload(); + if (!settings.platform.isAtomiswave()) + return; + if (sys_rom->Reload()) + return; + loadDefaultAWBiosFlash(); } void init() diff --git a/core/network/naomi_network.cpp b/core/network/naomi_network.cpp index 6812a54d0..a5e39e59f 100644 --- a/core/network/naomi_network.cpp +++ b/core/network/naomi_network.cpp @@ -307,7 +307,6 @@ void SetNaomiNetworkConfig(int node) } else if (gameId == " BIOHAZARD GUN SURVIVOR2") { - // FIXME need default flash write_naomi_flash(0x21c, node == 0 ? 0 : 1); // CPU ID - 1 write_naomi_flash(0x22a, node == -1 ? 0 : 1); // comm link on } @@ -317,7 +316,6 @@ void SetNaomiNetworkConfig(int node) } else if (gameId == "OUTTRIGGER JAPAN") { - // FIXME need default flash write_naomi_flash(0x21a, node == -1 ? 0 : 1); // network on write_naomi_flash(0x21b, node); // node id } @@ -349,7 +347,6 @@ void SetNaomiNetworkConfig(int node) } else if (gameId == "WORLD KICKS") { - // FIXME need default flash write_naomi_flash(0x224, node == -1 ? 0 : 1); // network on write_naomi_flash(0x220, node == 0 ? 0 : 1); // node id } diff --git a/resources/flash/dirtypig.nvmem.zip b/resources/flash/dirtypig.nvmem.zip new file mode 100644 index 000000000..40cf98ecf Binary files /dev/null and b/resources/flash/dirtypig.nvmem.zip differ diff --git a/resources/flash/dirtypig.nvmem2.zip b/resources/flash/dirtypig.nvmem2.zip new file mode 100644 index 000000000..2a270ee31 Binary files /dev/null and b/resources/flash/dirtypig.nvmem2.zip differ diff --git a/resources/flash/f355.nvmem.zip b/resources/flash/f355.nvmem.zip new file mode 100644 index 000000000..7341e8fce Binary files /dev/null and b/resources/flash/f355.nvmem.zip differ diff --git a/resources/flash/f355twin.nvmem.zip b/resources/flash/f355twin.nvmem.zip new file mode 100644 index 000000000..939399002 Binary files /dev/null and b/resources/flash/f355twin.nvmem.zip differ diff --git a/resources/flash/f355twn2.nvmem.zip b/resources/flash/f355twn2.nvmem.zip new file mode 100644 index 000000000..6816edc24 Binary files /dev/null and b/resources/flash/f355twn2.nvmem.zip differ diff --git a/resources/flash/gunsur2.nvmem.zip b/resources/flash/gunsur2.nvmem.zip new file mode 100644 index 000000000..0db597228 Binary files /dev/null and b/resources/flash/gunsur2.nvmem.zip differ diff --git a/resources/flash/otrigger.nvmem.zip b/resources/flash/otrigger.nvmem.zip new file mode 100644 index 000000000..eff167b43 Binary files /dev/null and b/resources/flash/otrigger.nvmem.zip differ diff --git a/resources/flash/wldkicks.nvmem.zip b/resources/flash/wldkicks.nvmem.zip new file mode 100644 index 000000000..402e8aeff Binary files /dev/null and b/resources/flash/wldkicks.nvmem.zip differ diff --git a/resources/flash/wldkicksj.nvmem.zip b/resources/flash/wldkicksj.nvmem.zip new file mode 100644 index 000000000..698f7dbc0 Binary files /dev/null and b/resources/flash/wldkicksj.nvmem.zip differ diff --git a/resources/flash/wldkicksu.nvmem.zip b/resources/flash/wldkicksu.nvmem.zip new file mode 100644 index 000000000..52f9c1c4e Binary files /dev/null and b/resources/flash/wldkicksu.nvmem.zip differ