diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 2f0ccab1..dbe5afe2 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -34,7 +34,7 @@ void Core::LoadROM(const std::string& rom_) { GameDB::match(cpu->mem); cpu->mem.mmio.vi.isPal = cpu->mem.IsROMPAL(); cpu->mem.mmio.si.pif.InitDevices(cpu->mem.saveType); - cpu->mem.mmio.si.pif.LoadMempak(rom); + cpu->mem.mmio.si.pif.mempakPath = rom; cpu->mem.mmio.si.pif.LoadEeprom(cpu->mem.saveType, rom); cpu->mem.flash.Load(cpu->mem.saveType, rom); cpu->mem.LoadSRAM(cpu->mem.saveType, rom); diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index 930de0e6..c7111f1b 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -27,33 +27,36 @@ void PIF::Reset() { } } -void PIF::LoadMempak(const std::string& path) { - mempakPath = fs::path(path).replace_extension(".mempak").string(); - std::error_code error; - if (mempak.is_mapped()) { - mempak.sync(error); - if (error) { Util::panic("Could not sync {}", mempakPath); } - mempak.unmap(); - } - FILE* f = fopen(mempakPath.c_str(), "rb"); - if (!f) { - f = fopen(mempakPath.c_str(), "wb"); - u8* dummy = (u8*)calloc(MEMPAK_SIZE, 1); - fwrite(dummy, 1, MEMPAK_SIZE, f); - free(dummy); - } +void PIF::MaybeLoadMempak() { + if(!mempakOpen) { + mempakPath = fs::path(mempakPath).replace_extension(".mempak").string(); + std::error_code error; + if (mempak.is_mapped()) { + mempak.sync(error); + if (error) { Util::panic("Could not sync {}", mempakPath); } + mempak.unmap(); + } + FILE *f = fopen(mempakPath.c_str(), "rb"); + if (!f) { + f = fopen(mempakPath.c_str(), "wb"); + u8 *dummy = (u8 *) calloc(MEMPAK_SIZE, 1); + fwrite(dummy, 1, MEMPAK_SIZE, f); + free(dummy); + } - fseek(f, 0, SEEK_END); - size_t actualSize = ftell(f); - fseek(f, 0, SEEK_SET); - if (actualSize != MEMPAK_SIZE) { - Util::panic("Corrupt mempak!"); - } - fclose(f); + fseek(f, 0, SEEK_END); + size_t actualSize = ftell(f); + fseek(f, 0, SEEK_SET); + if (actualSize != MEMPAK_SIZE) { + Util::panic("Corrupt mempak!"); + } + fclose(f); - mempak = mio::make_mmap_sink( + mempak = mio::make_mmap_sink( mempakPath, 0, mio::map_entire_file, error); - if (error) { Util::panic("Could not open {}", mempakPath); } + if (error) { Util::panic("Could not open {}", mempakPath); } + mempakOpen = true; + } } FORCE_INLINE size_t getSaveSize(SaveType saveType) { @@ -247,7 +250,8 @@ void PIF::ProcessCommands(Mem &mem) { } } -void PIF::MempakRead(const u8* cmd, u8* res) const { +void PIF::MempakRead(const u8* cmd, u8* res) { + MaybeLoadMempak(); u16 offset = cmd[3] << 8; offset |= cmd[4]; @@ -274,6 +278,7 @@ void PIF::MempakRead(const u8* cmd, u8* res) const { } void PIF::MempakWrite(u8* cmd, u8* res) { + MaybeLoadMempak(); // First two bytes in the command are the offset u16 offset = cmd[3] << 8; offset |= cmd[4]; diff --git a/src/backend/core/mmio/PIF.hpp b/src/backend/core/mmio/PIF.hpp index 77f052e8..d4acdace 100644 --- a/src/backend/core/mmio/PIF.hpp +++ b/src/backend/core/mmio/PIF.hpp @@ -107,7 +107,7 @@ struct PIF { PIF() = default; ~PIF() = default; void Reset(); - void LoadMempak(const std::string&); + void MaybeLoadMempak(); void LoadEeprom(SaveType, const std::string&); void ProcessCommands(Mem&); void InitDevices(SaveType); @@ -118,12 +118,12 @@ struct PIF { void UpdateController(); bool ReadButtons(u8*) const; void ControllerID(u8*) const; - void MempakRead(const u8*, u8*) const; + void MempakRead(const u8*, u8*); void MempakWrite(u8*, u8*); void EepromRead(const u8*, u8*, const Mem&) const; void EepromWrite(const u8*, u8*, const Mem&); - bool gamepadConnected = false; + bool gamepadConnected = false, mempakOpen = false; SDL_GameController* gamepad{}; JoybusDevice joybusDevices[6]{}; u8 bootrom[PIF_BOOTROM_SIZE]{}, ram[PIF_RAM_SIZE]{};