fix crashes when inserting/ejecting GBA carts/addons with nothing loaded
This commit is contained in:
parent
5e8beb3ab7
commit
0a4287c6ad
|
@ -832,6 +832,27 @@ std::unique_ptr<CartCommon> ParseROM(std::unique_ptr<u8[]>&& romdata, u32 romlen
|
||||||
return cart;
|
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
|
void GBACartSlot::SetCart(std::unique_ptr<CartCommon>&& cart) noexcept
|
||||||
{
|
{
|
||||||
Cart = std::move(cart);
|
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
|
std::unique_ptr<CartCommon> GBACartSlot::EjectCart() noexcept
|
||||||
{
|
{
|
||||||
return std::move(Cart);
|
return std::move(Cart);
|
||||||
|
|
|
@ -241,8 +241,6 @@ public:
|
||||||
[[nodiscard]] CartCommon* GetCart() noexcept { return Cart.get(); }
|
[[nodiscard]] CartCommon* GetCart() noexcept { return Cart.get(); }
|
||||||
[[nodiscard]] const CartCommon* GetCart() const 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,
|
/// @return The cart that was in the cart slot if any,
|
||||||
/// or \c nullptr if the cart slot was empty.
|
/// or \c nullptr if the cart slot was empty.
|
||||||
std::unique_ptr<CartCommon> EjectCart() noexcept;
|
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.
|
/// 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> 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
|
#endif // GBACART_H
|
||||||
|
|
|
@ -752,11 +752,6 @@ void NDS::SetGBASave(const u8* savedata, u32 savelen)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NDS::LoadGBAAddon(int type)
|
|
||||||
{
|
|
||||||
GBACartSlot.LoadAddon(UserData, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NDS::LoadBIOS()
|
void NDS::LoadBIOS()
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
|
|
|
@ -384,7 +384,6 @@ public: // TODO: Encapsulate the rest of these members
|
||||||
u32 GetGBASaveLength() const { return GBACartSlot.GetSaveMemoryLength(); }
|
u32 GetGBASaveLength() const { return GBACartSlot.GetSaveMemoryLength(); }
|
||||||
void SetGBASave(const u8* savedata, u32 savelen);
|
void SetGBASave(const u8* savedata, u32 savelen);
|
||||||
|
|
||||||
void LoadGBAAddon(int type);
|
|
||||||
std::unique_ptr<GBACart::CartCommon> EjectGBACart() { return GBACartSlot.EjectCart(); }
|
std::unique_ptr<GBACart::CartCommon> EjectGBACart() { return GBACartSlot.EjectCart(); }
|
||||||
|
|
||||||
u32 RunFrame();
|
u32 RunFrame();
|
||||||
|
|
|
@ -83,6 +83,8 @@ EmuInstance::EmuInstance(int inst) : deleting(false),
|
||||||
baseGBAROMDir = "";
|
baseGBAROMDir = "";
|
||||||
baseGBAROMName = "";
|
baseGBAROMName = "";
|
||||||
baseGBAAssetName = "";
|
baseGBAAssetName = "";
|
||||||
|
nextGBACart = nullptr;
|
||||||
|
changeGBACart = false;
|
||||||
|
|
||||||
cheatFile = nullptr;
|
cheatFile = nullptr;
|
||||||
cheatsOn = localCfg.GetBool("EnableCheats");
|
cheatsOn = localCfg.GetBool("EnableCheats");
|
||||||
|
@ -118,7 +120,7 @@ EmuInstance::EmuInstance(int inst) : deleting(false),
|
||||||
mpAudioMode = globalCfg.GetInt("MP.AudioMode");
|
mpAudioMode = globalCfg.GetInt("MP.AudioMode");
|
||||||
|
|
||||||
nds = nullptr;
|
nds = nullptr;
|
||||||
//updateConsole(nullptr, nullptr);
|
//updateConsole(nullptr);
|
||||||
|
|
||||||
audioInit();
|
audioInit();
|
||||||
inputInit();
|
inputInit();
|
||||||
|
@ -1215,7 +1217,7 @@ void EmuInstance::setDateTime()
|
||||||
time.time().hour(), time.time().minute(), time.time().second());
|
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
|
// update the console type
|
||||||
consoleType = globalCfg.GetInt("Emu.ConsoleType");
|
consoleType = globalCfg.GetInt("Emu.ConsoleType");
|
||||||
|
@ -1242,14 +1244,14 @@ bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs, UpdateConsoleGB
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GBACart::CartCommon> nextgbacart;
|
std::unique_ptr<GBACart::CartCommon> nextgbacart;
|
||||||
if (std::holds_alternative<Keep>(_gbaargs))
|
if (!changeGBACart)
|
||||||
{
|
{
|
||||||
nextgbacart = nds ? nds->EjectGBACart() : nullptr;
|
nextgbacart = nds ? nds->EjectGBACart() : nullptr;
|
||||||
}
|
}
|
||||||
else if (const auto ptr = std::get_if<std::unique_ptr<GBACart::CartCommon>>(&_gbaargs))
|
else
|
||||||
{
|
{
|
||||||
nextgbacart = std::move(*ptr);
|
nextgbacart = std::move(nextGBACart);
|
||||||
_gbaargs = {};
|
changeGBACart = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1391,7 +1393,7 @@ bool EmuInstance::updateConsole(UpdateConsoleNDSArgs&& _ndsargs, UpdateConsoleGB
|
||||||
|
|
||||||
void EmuInstance::reset()
|
void EmuInstance::reset()
|
||||||
{
|
{
|
||||||
updateConsole(Keep {}, Keep {});
|
updateConsole(Keep {});
|
||||||
|
|
||||||
if (consoleType == 1) ejectGBACart();
|
if (consoleType == 1) ejectGBACart();
|
||||||
|
|
||||||
|
@ -1455,7 +1457,7 @@ void EmuInstance::reset()
|
||||||
bool EmuInstance::bootToMenu()
|
bool EmuInstance::bootToMenu()
|
||||||
{
|
{
|
||||||
// Keep whatever cart is in the console, if any.
|
// 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...
|
// Try to update the console, but keep the existing cart. If that fails...
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1910,7 +1912,7 @@ bool EmuInstance::loadROM(QStringList filepath, bool reset)
|
||||||
|
|
||||||
if (reset)
|
if (reset)
|
||||||
{
|
{
|
||||||
if (!updateConsole(std::move(cart), Keep {}))
|
if (!updateConsole(std::move(cart)))
|
||||||
{
|
{
|
||||||
QMessageBox::critical(mainWindow, "melonDS", "Failed to load the DS ROM.");
|
QMessageBox::critical(mainWindow, "melonDS", "Failed to load the DS ROM.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -2043,9 +2045,18 @@ bool EmuInstance::loadGBAROM(QStringList filepath)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nds->SetGBACart(std::move(cart));
|
|
||||||
gbaCartType = 0;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2053,10 +2064,24 @@ void EmuInstance::loadGBAAddon(int type)
|
||||||
{
|
{
|
||||||
if (consoleType == 1) return;
|
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;
|
gbaSave = nullptr;
|
||||||
|
|
||||||
nds->LoadGBAAddon(type);
|
|
||||||
|
|
||||||
gbaCartType = type;
|
gbaCartType = type;
|
||||||
baseGBAROMDir = "";
|
baseGBAROMDir = "";
|
||||||
baseGBAROMName = "";
|
baseGBAROMName = "";
|
||||||
|
@ -2067,7 +2092,15 @@ void EmuInstance::ejectGBACart()
|
||||||
{
|
{
|
||||||
gbaSave = nullptr;
|
gbaSave = nullptr;
|
||||||
|
|
||||||
nds->EjectGBACart();
|
if (emuIsActive())
|
||||||
|
{
|
||||||
|
nds->EjectGBACart();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextGBACart = nullptr;
|
||||||
|
changeGBACart = true;
|
||||||
|
}
|
||||||
|
|
||||||
gbaCartType = -1;
|
gbaCartType = -1;
|
||||||
baseGBAROMDir = "";
|
baseGBAROMDir = "";
|
||||||
|
|
|
@ -120,7 +120,7 @@ public:
|
||||||
// return: empty string = setup OK, non-empty = error message
|
// return: empty string = setup OK, non-empty = error message
|
||||||
QString verifySetup();
|
QString verifySetup();
|
||||||
|
|
||||||
bool updateConsole(UpdateConsoleNDSArgs&& ndsargs, UpdateConsoleGBAArgs&& gbaargs) noexcept;
|
bool updateConsole(UpdateConsoleNDSArgs&& ndsargs) noexcept;
|
||||||
|
|
||||||
void enableCheats(bool enable);
|
void enableCheats(bool enable);
|
||||||
melonDS::ARCodeFile* getCheatFile();
|
melonDS::ARCodeFile* getCheatFile();
|
||||||
|
@ -188,12 +188,14 @@ private:
|
||||||
std::pair<std::unique_ptr<melonDS::Firmware>, std::string> generateDefaultFirmware();
|
std::pair<std::unique_ptr<melonDS::Firmware>, std::string> generateDefaultFirmware();
|
||||||
bool parseMacAddress(void* data);
|
bool parseMacAddress(void* data);
|
||||||
void customizeFirmware(melonDS::Firmware& firmware, bool overridesettings) noexcept;
|
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;
|
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);
|
QString getSavErrorString(std::string& filepath, bool gba);
|
||||||
bool loadROM(QStringList filepath, bool reset);
|
bool loadROM(QStringList filepath, bool reset);
|
||||||
void ejectCart();
|
void ejectCart();
|
||||||
bool cartInserted();
|
bool cartInserted();
|
||||||
QString cartLabel();
|
QString cartLabel();
|
||||||
|
|
||||||
bool loadGBAROM(QStringList filepath);
|
bool loadGBAROM(QStringList filepath);
|
||||||
void loadGBAAddon(int type);
|
void loadGBAAddon(int type);
|
||||||
void ejectGBACart();
|
void ejectGBACart();
|
||||||
|
@ -264,6 +266,8 @@ private:
|
||||||
std::string baseGBAROMDir;
|
std::string baseGBAROMDir;
|
||||||
std::string baseGBAROMName;
|
std::string baseGBAROMName;
|
||||||
std::string baseGBAAssetName;
|
std::string baseGBAAssetName;
|
||||||
|
bool changeGBACart;
|
||||||
|
std::unique_ptr<melonDS::GBACart::CartCommon> nextGBACart;
|
||||||
|
|
||||||
// HACK
|
// HACK
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -109,7 +109,7 @@ void EmuThread::run()
|
||||||
Config::Table& globalCfg = emuInstance->getGlobalConfig();
|
Config::Table& globalCfg = emuInstance->getGlobalConfig();
|
||||||
u32 mainScreenPos[3];
|
u32 mainScreenPos[3];
|
||||||
|
|
||||||
//emuInstance->updateConsole(nullptr, nullptr);
|
//emuInstance->updateConsole(nullptr);
|
||||||
// No carts are inserted when melonDS first boots
|
// No carts are inserted when melonDS first boots
|
||||||
|
|
||||||
mainScreenPos[0] = 0;
|
mainScreenPos[0] = 0;
|
||||||
|
|
Loading…
Reference in New Issue