diff --git a/src/GBACart.cpp b/src/GBACart.cpp index a62aca6b..c3550207 100644 --- a/src/GBACart.cpp +++ b/src/GBACart.cpp @@ -832,6 +832,27 @@ std::unique_ptr ParseROM(std::unique_ptr&& romdata, u32 romlen return cart; } +std::unique_ptr LoadAddon(int type, void* userdata) +{ + std::unique_ptr cart; + switch (type) + { + case GBAAddon_RAMExpansion: + cart = std::make_unique(); + break; + case GBAAddon_RumblePak: + cart = std::make_unique(userdata); + break; + + default: + Log(LogLevel::Warn, "GBACart: !! invalid addon type %d\n", type); + return nullptr; + } + + cart->Reset(); + return cart; +} + void GBACartSlot::SetCart(std::unique_ptr&& cart) noexcept { Cart = std::move(cart); @@ -864,23 +885,6 @@ void GBACartSlot::SetSaveMemory(const u8* savedata, u32 savelen) noexcept } } -void GBACartSlot::LoadAddon(void* userdata, int type) noexcept -{ - switch (type) - { - case GBAAddon_RAMExpansion: - Cart = std::make_unique(); - break; - case GBAAddon_RumblePak: - Cart = std::make_unique(userdata); - break; - - default: - Log(LogLevel::Warn, "GBACart: !! invalid addon type %d\n", type); - return; - } -} - std::unique_ptr GBACartSlot::EjectCart() noexcept { return std::move(Cart); diff --git a/src/GBACart.h b/src/GBACart.h index 726a234d..e6639813 100644 --- a/src/GBACart.h +++ b/src/GBACart.h @@ -241,8 +241,6 @@ public: [[nodiscard]] CartCommon* GetCart() noexcept { return Cart.get(); } [[nodiscard]] const CartCommon* GetCart() const noexcept { return Cart.get(); } - void LoadAddon(void* userdata, int type) noexcept; - /// @return The cart that was in the cart slot if any, /// or \c nullptr if the cart slot was empty. std::unique_ptr EjectCart() noexcept; @@ -309,6 +307,8 @@ std::unique_ptr ParseROM(const u8* romdata, u32 romlen, const u8* sr /// or \c nullptr if there was an error. std::unique_ptr ParseROM(std::unique_ptr&& romdata, u32 romlen, std::unique_ptr&& sramdata, u32 sramlen, void* userdata = nullptr); +std::unique_ptr LoadAddon(int type, void* userdata); + } #endif // GBACART_H diff --git a/src/NDS.cpp b/src/NDS.cpp index 1023d3c0..bf2e4283 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -752,11 +752,6 @@ void NDS::SetGBASave(const u8* savedata, u32 savelen) } -void NDS::LoadGBAAddon(int type) -{ - GBACartSlot.LoadAddon(UserData, type); -} - void NDS::LoadBIOS() { Reset(); diff --git a/src/NDS.h b/src/NDS.h index b2bfb385..5e474807 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -384,7 +384,6 @@ public: // TODO: Encapsulate the rest of these members u32 GetGBASaveLength() const { return GBACartSlot.GetSaveMemoryLength(); } void SetGBASave(const u8* savedata, u32 savelen); - void LoadGBAAddon(int type); std::unique_ptr EjectGBACart() { return GBACartSlot.EjectCart(); } u32 RunFrame(); diff --git a/src/frontend/qt_sdl/EmuInstance.cpp b/src/frontend/qt_sdl/EmuInstance.cpp index 2ac3f42d..a66396bb 100644 --- a/src/frontend/qt_sdl/EmuInstance.cpp +++ b/src/frontend/qt_sdl/EmuInstance.cpp @@ -83,6 +83,8 @@ EmuInstance::EmuInstance(int inst) : deleting(false), baseGBAROMDir = ""; baseGBAROMName = ""; baseGBAAssetName = ""; + nextGBACart = nullptr; + changeGBACart = false; cheatFile = nullptr; cheatsOn = localCfg.GetBool("EnableCheats"); @@ -118,7 +120,7 @@ EmuInstance::EmuInstance(int inst) : deleting(false), mpAudioMode = globalCfg.GetInt("MP.AudioMode"); nds = nullptr; - //updateConsole(nullptr, nullptr); + //updateConsole(nullptr); audioInit(); inputInit(); @@ -1215,7 +1217,7 @@ void EmuInstance::setDateTime() time.time().hour(), time.time().minute(), time.time().second()); } -bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs, UpdateConsoleGBAArgs&& _gbaargs) noexcept +bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs) noexcept { // update the console type consoleType = globalCfg.GetInt("Emu.ConsoleType"); @@ -1242,14 +1244,14 @@ bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs, UpdateConsoleGB } std::unique_ptr nextgbacart; - if (std::holds_alternative(_gbaargs)) + if (!changeGBACart) { nextgbacart = nds ? nds->EjectGBACart() : nullptr; } - else if (const auto ptr = std::get_if>(&_gbaargs)) + else { - nextgbacart = std::move(*ptr); - _gbaargs = {}; + nextgbacart = std::move(nextGBACart); + changeGBACart = false; } @@ -1391,7 +1393,7 @@ bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs, UpdateConsoleGB void EmuInstance::reset() { - updateConsole(Keep {}, Keep {}); + updateConsole(Keep {}); if (consoleType == 1) ejectGBACart(); @@ -1455,7 +1457,7 @@ void EmuInstance::reset() bool EmuInstance::bootToMenu() { // Keep whatever cart is in the console, if any. - if (!updateConsole(Keep {}, Keep {})) + if (!updateConsole(Keep {})) // Try to update the console, but keep the existing cart. If that fails... return false; @@ -1910,7 +1912,7 @@ bool EmuInstance::loadROM(QStringList filepath, bool reset) if (reset) { - if (!updateConsole(std::move(cart), Keep {})) + if (!updateConsole(std::move(cart))) { QMessageBox::critical(mainWindow, "melonDS", "Failed to load the DS ROM."); return false; @@ -2043,9 +2045,18 @@ bool EmuInstance::loadGBAROM(QStringList filepath) return false; } - nds->SetGBACart(std::move(cart)); gbaCartType = 0; - gbaSave = std::make_unique(savname); + if (emuIsActive()) + { + nds->SetGBACart(std::move(cart)); + gbaSave = std::make_unique(savname); + } + else + { + nextGBACart = std::move(cart); + changeGBACart = true; + } + return true; } @@ -2053,10 +2064,24 @@ void EmuInstance::loadGBAAddon(int type) { if (consoleType == 1) return; + auto cart = GBACart::LoadAddon(type, this); + if (!cart) + { + QMessageBox::critical(mainWindow, "melonDS", "Failed to load the GBA addon."); + return; + } + + if (emuIsActive()) + { + nds->SetGBACart(std::move(cart)); + } + else + { + nextGBACart = std::move(cart); + changeGBACart = true; + } + gbaSave = nullptr; - - nds->LoadGBAAddon(type); - gbaCartType = type; baseGBAROMDir = ""; baseGBAROMName = ""; @@ -2067,7 +2092,15 @@ void EmuInstance::ejectGBACart() { gbaSave = nullptr; - nds->EjectGBACart(); + if (emuIsActive()) + { + nds->EjectGBACart(); + } + else + { + nextGBACart = nullptr; + changeGBACart = true; + } gbaCartType = -1; baseGBAROMDir = ""; diff --git a/src/frontend/qt_sdl/EmuInstance.h b/src/frontend/qt_sdl/EmuInstance.h index a135a52c..fbee4bf4 100644 --- a/src/frontend/qt_sdl/EmuInstance.h +++ b/src/frontend/qt_sdl/EmuInstance.h @@ -120,7 +120,7 @@ public: // return: empty string = setup OK, non-empty = error message QString verifySetup(); - bool updateConsole(UpdateConsoleNDSArgs&& ndsargs, UpdateConsoleGBAArgs&& gbaargs) noexcept; + bool updateConsole(UpdateConsoleNDSArgs&& ndsargs) noexcept; void enableCheats(bool enable); melonDS::ARCodeFile* getCheatFile(); @@ -188,12 +188,14 @@ private: std::pair, std::string> generateDefaultFirmware(); bool parseMacAddress(void* data); void customizeFirmware(melonDS::Firmware& firmware, bool overridesettings) noexcept; + bool loadROMData(const QStringList& filepath, std::unique_ptr& filedata, melonDS::u32& filelen, std::string& basepath, std::string& romname) noexcept; QString getSavErrorString(std::string& filepath, bool gba); bool loadROM(QStringList filepath, bool reset); void ejectCart(); bool cartInserted(); QString cartLabel(); + bool loadGBAROM(QStringList filepath); void loadGBAAddon(int type); void ejectGBACart(); @@ -264,6 +266,8 @@ private: std::string baseGBAROMDir; std::string baseGBAROMName; std::string baseGBAAssetName; + bool changeGBACart; + std::unique_ptr nextGBACart; // HACK public: diff --git a/src/frontend/qt_sdl/EmuThread.cpp b/src/frontend/qt_sdl/EmuThread.cpp index f767c6db..1592c481 100644 --- a/src/frontend/qt_sdl/EmuThread.cpp +++ b/src/frontend/qt_sdl/EmuThread.cpp @@ -109,7 +109,7 @@ void EmuThread::run() Config::Table& globalCfg = emuInstance->getGlobalConfig(); u32 mainScreenPos[3]; - //emuInstance->updateConsole(nullptr, nullptr); + //emuInstance->updateConsole(nullptr); // No carts are inserted when melonDS first boots mainScreenPos[0] = 0;