diff options
| author | Raphaël Zumer <rzumer@tebako.net> | 2019-12-22 13:58:27 -0500 | 
|---|---|---|
| committer | Raphaël Zumer <rzumer@tebako.net> | 2019-12-22 14:13:10 -0500 | 
| commit | f380767fab219df087488a4e4e8a5eab47efb94c (patch) | |
| tree | 29150433a4fdf36efc605287d1225a77de8902b9 /src | |
| parent | a57ba1368e151484908052d696aa90f28928cfe2 (diff) | |
Only store the GBA ROM header in save states
Also fix some potential crashes due to SRAM
state not being cleared correctly on state load.
Diffstat (limited to 'src')
| -rw-r--r-- | src/GBACart.cpp | 40 | 
1 files changed, 31 insertions, 9 deletions
diff --git a/src/GBACart.cpp b/src/GBACart.cpp index f6bed86..7753482 100644 --- a/src/GBACart.cpp +++ b/src/GBACart.cpp @@ -110,8 +110,11 @@ void DoSavestate(Savestate* file)      }
      else
      {
 -        // no save data, nothing left to do
 +        // no save data, clear the current state
          SRAMType = SaveType::S_NULL;
 +        if (SRAMFile) fclose(SRAMFile);
 +        SRAM = NULL;
 +        SRAMFile = NULL;
          return;
      }
 @@ -541,21 +544,40 @@ void DoSavestate(Savestate* file)      // first we need to reload the cart itself,
      // since unlike with DS, it's not loaded in advance
 -    u32 oldlen = CartROMSize;
 -
      file->Var32(&CartROMSize);
      if (!CartROMSize) return; // no GBA cartridge state? nothing to do here.
 -    if (CartROMSize != oldlen) // loading a differently-sized cartridge
 +    u32 oldCRC = CartCRC;
 +    file->Var32(&CartCRC);
 +    if (CartCRC != oldCRC)
      {
 -        if (oldlen) delete[] CartROM;
 +        // delete and reallocate ROM so that it is zero-padded to its full length
 +        if (CartROM) delete[] CartROM;
          CartROM = new u8[CartROMSize];
 -    }
 -    // why yes, let's save the whole GBA cart in the state
 -    // TODO: let's maybe not?
 +        // clear the SRAM file handle; writes will not be committed
 +        if (GBACart_SRAM::SRAMFile)
 +        {
 +            fclose(GBACart_SRAM::SRAMFile);
 +            GBACart_SRAM::SRAMFile = NULL;
 +        }
 +    }
 -    file->VarArray(CartROM, CartROMSize);
 +    // only save/load the cartridge header
 +    //
 +    // GBA connectivity on DS mainly involves identifying the title currently
 +    // inserted, reading save data, and issuing commands intercepted here
 +    // (e.g. solar sensor signals). we don't know of any case where GBA ROM is
 +    // read directly from DS software. therefore, it is more practical, both
 +    // from the development and user experience perspectives, to avoid dealing
 +    // with file dependencies, and store a small portion of ROM data that should
 +    // satisfy the needs of all known software that reads from the GBA slot.
 +    //
 +    // note: in case of a state load, only the cartridge header is restored, but
 +    // the rest of the ROM data is only cleared (zero-initialized) if the CRC
 +    // differs. Therefore, loading the GBA cartridge associated with the save state
 +    // in advance will maintain access to the full ROM contents.
 +    file->VarArray(CartROM, 192);
      CartInserted = true; // known, because CartROMSize > 0
      file->Var32(&CartCRC);
  |