Skip to content

Commit

Permalink
fix crashes when inserting/ejecting GBA carts/addons with nothing loaded
Browse files Browse the repository at this point in the history
  • Loading branch information
Arisotura committed Nov 17, 2024
1 parent 5e8beb3 commit 0a4287c
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 41 deletions.
38 changes: 21 additions & 17 deletions src/GBACart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/GBACart.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,6 @@ class GBACartSlot
[[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;
Expand Down Expand Up @@ -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
5 changes: 0 additions & 5 deletions src/NDS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 0 additions & 1 deletion src/NDS.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,6 @@ class NDS
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();
Expand Down
61 changes: 47 additions & 14 deletions src/frontend/qt_sdl/EmuInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ EmuInstance::EmuInstance(int inst) : deleting(false),
baseGBAROMDir = "";
baseGBAROMName = "";
baseGBAAssetName = "";
nextGBACart = nullptr;
changeGBACart = false;

cheatFile = nullptr;
cheatsOn = localCfg.GetBool("EnableCheats");
Expand Down Expand Up @@ -118,7 +120,7 @@ EmuInstance::EmuInstance(int inst) : deleting(false),
mpAudioMode = globalCfg.GetInt("MP.AudioMode");

nds = nullptr;
//updateConsole(nullptr, nullptr);
//updateConsole(nullptr);

audioInit();
inputInit();
Expand Down Expand Up @@ -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");
Expand All @@ -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;
}


Expand Down Expand Up @@ -1391,7 +1393,7 @@ bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs, UpdateConsoleGB

void EmuInstance::reset()
{
updateConsole(Keep {}, Keep {});
updateConsole(Keep {});

if (consoleType == 1) ejectGBACart();

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2043,20 +2045,43 @@ 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;
}

void EmuInstance::loadGBAAddon(int type)
{
if (consoleType == 1) return;

gbaSave = nullptr;
auto cart = GBACart::LoadAddon(type, this);
if (!cart)
{
QMessageBox::critical(mainWindow, "melonDS", "Failed to load the GBA addon.");
return;
}

nds->LoadGBAAddon(type);
if (emuIsActive())
{
nds->SetGBACart(std::move(cart));
}
else
{
nextGBACart = std::move(cart);
changeGBACart = true;
}

gbaSave = nullptr;
gbaCartType = type;
baseGBAROMDir = "";
baseGBAROMName = "";
Expand All @@ -2067,7 +2092,15 @@ void EmuInstance::ejectGBACart()
{
gbaSave = nullptr;

nds->EjectGBACart();
if (emuIsActive())
{
nds->EjectGBACart();
}
else
{
nextGBACart = nullptr;
changeGBACart = true;
}

gbaCartType = -1;
baseGBAROMDir = "";
Expand Down
6 changes: 5 additions & 1 deletion src/frontend/qt_sdl/EmuInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class EmuInstance
// 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();
Expand Down Expand Up @@ -188,12 +188,14 @@ class EmuInstance
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();
Expand Down Expand Up @@ -264,6 +266,8 @@ class EmuInstance
std::string baseGBAROMDir;
std::string baseGBAROMName;
std::string baseGBAAssetName;
bool changeGBACart;
std::unique_ptr<melonDS::GBACart::CartCommon> nextGBACart;

// HACK
public:
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/qt_sdl/EmuThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 0a4287c

Please sign in to comment.