aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRaphaël Zumer <rzumer@tebako.net>2019-12-22 15:49:23 -0500
committerRaphaël Zumer <rzumer@tebako.net>2019-12-22 16:01:13 -0500
commit22d11209b0466e3c852da543ddfc512b66735bc2 (patch)
tree3539a080f103cec24bee6880d679e8aaa37a9271 /src
parentf380767fab219df087488a4e4e8a5eab47efb94c (diff)
Split GBA Reset and Eject logic into two sets
This allows solving some crashes and provides more flexibility in how GBA cartridges change state between soft and hard resets. Since save states including GBA data do not carry over the original save file path, and the GBA cartridge is being reset along with the other parts of the system, this is needed to avoid losing the GBA state on reset following a state load, while preserving the behavior where cartridges are ejected when calling Stop().
Diffstat (limited to 'src')
-rw-r--r--src/GBACart.cpp35
-rw-r--r--src/GBACart.h2
-rw-r--r--src/libui_sdl/main.cpp22
3 files changed, 52 insertions, 7 deletions
diff --git a/src/GBACart.cpp b/src/GBACart.cpp
index 7753482..4d44d3a 100644
--- a/src/GBACart.cpp
+++ b/src/GBACart.cpp
@@ -77,9 +77,13 @@ void DeInit()
void Reset()
{
+ // do nothing, we don't want to clear GBA SRAM on reset
+}
+
+void Eject()
+{
if (SRAMFile) fclose(SRAMFile);
if (SRAM) delete[] SRAM;
-
SRAM = NULL;
SRAMFile = NULL;
SRAMLength = 0;
@@ -524,15 +528,30 @@ void DeInit()
void Reset()
{
+ // Do not reset cartridge ROM.
+ // Prefer keeping the inserted cartridge on reset.
+ // This allows resetting a DS game without losing GBA state,
+ // and resetting to firmware without the slot being emptied.
+ // The Stop function will clear the cartridge state via Eject().
+
+ GBACart_SRAM::Reset();
+ GBACart_SolarSensor::Reset();
+}
+
+void Eject()
+{
+ if (CartROM) delete[] CartROM;
+
CartInserted = false;
HasSolarSensor = false;
- if (CartROM) delete[] CartROM;
CartROM = NULL;
CartROMSize = 0;
+ CartCRC = NULL;
+ CartID = NULL;
CartGPIO = {};
- GBACart_SRAM::Reset();
- GBACart_SolarSensor::Reset();
+ GBACart_SRAM::Eject();
+ Reset();
}
void DoSavestate(Savestate* file)
@@ -545,10 +564,16 @@ void DoSavestate(Savestate* file)
// since unlike with DS, it's not loaded in advance
file->Var32(&CartROMSize);
- if (!CartROMSize) return; // no GBA cartridge state? nothing to do here.
+ if (!CartROMSize) // no GBA cartridge state? nothing to do here
+ {
+ // do eject the cartridge if something is inserted
+ Eject();
+ return;
+ }
u32 oldCRC = CartCRC;
file->Var32(&CartCRC);
+
if (CartCRC != oldCRC)
{
// delete and reallocate ROM so that it is zero-padded to its full length
diff --git a/src/GBACart.h b/src/GBACart.h
index fd26326..96a05b8 100644
--- a/src/GBACart.h
+++ b/src/GBACart.h
@@ -57,10 +57,12 @@ extern bool CartInserted;
extern bool HasSolarSensor;
extern u8* CartROM;
extern u32 CartROMSize;
+extern u32 CartCRC;
bool Init();
void DeInit();
void Reset();
+void Eject();
void DoSavestate(Savestate* file);
bool LoadROM(const char* path, const char* sram);
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 38804f6..af69f8e 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -1694,6 +1694,7 @@ void Stop(bool internal)
RunningSomething = false;
// eject any inserted GBA cartridge
+ GBACart::Eject();
ROMPath[1][0] = '\0';
uiWindowSetTitle(MainWindow, "melonDS " MELONDS_VERSION);
@@ -1834,6 +1835,8 @@ void LoadState(int slot)
return;
}
+ u32 oldGBACartCRC = GBACart::CartCRC;
+
// backup
Savestate* backup = new Savestate("timewarp.mln", true);
NDS::DoSavestate(backup);
@@ -1870,9 +1873,24 @@ void LoadState(int slot)
NDS::RelocateSave(SRAMPath[0], false);
}
+ bool loadedPartialGBAROM = false;
+
+ // in case we have a GBA cart inserted, and the GBA ROM changes
+ // due to having loaded a save state, we do not want to reload
+ // the previous cartridge on reset, or commit writes to any
+ // loaded save file. therefore, their paths are "nulled".
+ if (GBACart::CartInserted && GBACart::CartCRC != oldGBACartCRC)
+ {
+ ROMPath[1][0] = '\0';
+ SRAMPath[1][0] = '\0';
+ loadedPartialGBAROM = true;
+ }
+
char msg[64];
- if (slot > 0) sprintf(msg, "State loaded from slot %d", slot);
- else sprintf(msg, "State loaded from file");
+ if (slot > 0) sprintf(msg, "State loaded from slot %d%s",
+ slot, loadedPartialGBAROM ? " (GBA ROM header only)" : "");
+ else sprintf(msg, "State loaded from file%s",
+ loadedPartialGBAROM ? " (GBA ROM header only)" : "");
OSD::AddMessage(0, msg);
SavestateLoaded = true;