fix crashes when inserting/ejecting GBA carts/addons with nothing loaded

This commit is contained in:
Arisotura 2024-11-17 15:23:25 +01:00
parent 5e8beb3ab7
commit 0a4287c6ad
7 changed files with 77 additions and 42 deletions

View File

@ -832,6 +832,27 @@ std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen
return cart;
}
std::unique_ptr<CartCommon> LoadAddon(int type, void* userdata)
{
std::unique_ptr<CartCommon> cart;
switch (type)
{
case GBAAddon_RAMExpansion:
cart = std::make_unique<CartRAMExpansion>();
break;
case GBAAddon_RumblePak:
cart = std::make_unique<CartRumblePak>(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<CartCommon>&& 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<CartRAMExpansion>();
break;
case GBAAddon_RumblePak:
Cart = std::make_unique<CartRumblePak>(userdata);
break;
default:
Log(LogLevel::Warn, "GBACart: !! invalid addon type %d\n", type);
return;
}
}
std::unique_ptr<CartCommon> GBACartSlot::EjectCart() noexcept
{
return std::move(Cart);

View File

@ -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<CartCommon> EjectCart() noexcept;
@ -309,6 +307,8 @@ std::unique_ptr<CartCommon> ParseROM(const u8* romdata, u32 romlen, const u8* sr
/// or \c nullptr if there was an error.
std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen, std::unique_ptr<u8[]>&& sramdata, u32 sramlen, void* userdata = nullptr);
std::unique_ptr<CartCommon> LoadAddon(int type, void* userdata);
}
#endif // GBACART_H

View File

@ -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();

View File

@ -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<GBACart::CartCommon> EjectGBACart() { return GBACartSlot.EjectCart(); }
u32 RunFrame();

View File

@ -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<GBACart::CartCommon> nextgbacart;
if (std::holds_alternative<Keep>(_gbaargs))
if (!changeGBACart)
{
nextgbacart = nds ? nds->EjectGBACart() : nullptr;
}
else if (const auto ptr = std::get_if<std::unique_ptr<GBACart::CartCommon>>(&_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<SaveManager>(savname);
if (emuIsActive())
{
nds->SetGBACart(std::move(cart));
gbaSave = std::make_unique<SaveManager>(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 = "";

View File

@ -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::unique_ptr<melonDS::Firmware>, std::string> generateDefaultFirmware();
bool parseMacAddress(void* data);
void customizeFirmware(melonDS::Firmware& firmware, bool overridesettings) noexcept;
bool loadROMData(const QStringList& filepath, std::unique_ptr<melonDS::u8[]>& 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<melonDS::GBACart::CartCommon> nextGBACart;
// HACK
public:

View File

@ -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;