Expose SRAM pointers for frontends that manage save data their own way (#1643)

* Add a clarifying comment

- In case it saves some poor bastard hours of fruitless work

* Expose GBA and NDS save memory

- Add GetSaveMemory and GetSaveMemoryLength functions
- Where unsupported, they return null and zero
This commit is contained in:
Jesse Talavera-Greenberg 2023-03-27 16:36:26 -04:00 committed by GitHub
parent 808292e424
commit b078ca802f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 99 additions and 0 deletions

View File

@ -100,6 +100,15 @@ void CartCommon::SRAMWrite(u32 addr, u8 val)
{
}
u8* CartCommon::GetSaveMemory() const
{
return nullptr;
}
u32 CartCommon::GetSaveMemoryLength() const
{
return 0;
}
CartGame::CartGame(u8* rom, u32 len) : CartCommon()
{
@ -334,6 +343,16 @@ void CartGame::SRAMWrite(u32 addr, u8 val)
}
}
u8* CartGame::GetSaveMemory() const
{
return SRAM;
}
u32 CartGame::GetSaveMemoryLength() const
{
return SRAMLength;
}
void CartGame::ProcessGPIO()
{
}
@ -878,4 +897,14 @@ void SRAMWrite(u32 addr, u8 val)
if (Cart) Cart->SRAMWrite(addr, val);
}
u8* GetSaveMemory()
{
return Cart ? Cart->GetSaveMemory() : nullptr;
}
u32 GetSaveMemoryLength()
{
return Cart ? Cart->GetSaveMemoryLength() : 0;
}
}

View File

@ -49,6 +49,9 @@ public:
virtual u8 SRAMRead(u32 addr);
virtual void SRAMWrite(u32 addr, u8 val);
virtual u8* GetSaveMemory() const;
virtual u32 GetSaveMemoryLength() const;
};
// CartGame -- regular retail game cart (ROM, SRAM)
@ -74,6 +77,8 @@ public:
virtual u8 SRAMRead(u32 addr) override;
virtual void SRAMWrite(u32 addr, u8 val) override;
virtual u8* GetSaveMemory() const override;
virtual u32 GetSaveMemoryLength() const override;
protected:
virtual void ProcessGPIO();
@ -207,6 +212,19 @@ void ROMWrite(u32 addr, u16 val);
u8 SRAMRead(u32 addr);
void SRAMWrite(u32 addr, u8 val);
/// This function is intended to allow frontends to save and load SRAM
/// without using melonDS APIs.
/// Modifying the emulated SRAM for any other reason is strongly discouraged.
/// The returned pointer may be invalidated if the emulator is reset,
/// or when a new game is loaded.
/// Consequently, don't store the returned pointer for any longer than necessary.
/// @returns Pointer to this cart's SRAM if a cart is loaded and supports SRAM, otherwise \c nullptr.
u8* GetSaveMemory();
/// @returns The length of the buffer returned by ::GetSaveMemory()
/// if a cart is loaded and supports SRAM, otherwise zero.
u32 GetSaveMemoryLength();
}
#endif // GBACART_H

View File

@ -383,6 +383,16 @@ void CartCommon::SetIRQ()
NDS::SetIRQ(1, NDS::IRQ_CartIREQMC);
}
u8 *CartCommon::GetSaveMemory() const
{
return nullptr;
}
u32 CartCommon::GetSaveMemoryLength() const
{
return 0;
}
void CartCommon::ReadROM(u32 addr, u32 len, u8* data, u32 offset)
{
if (addr >= ROMLength) return;
@ -553,6 +563,16 @@ u8 CartRetail::SPIWrite(u8 val, u32 pos, bool last)
}
}
u8 *CartRetail::GetSaveMemory() const
{
return SRAM;
}
u32 CartRetail::GetSaveMemoryLength() const
{
return SRAMLength;
}
void CartRetail::ReadROM_B7(u32 addr, u32 len, u8* data, u32 offset)
{
addr &= (ROMLength-1);
@ -1732,6 +1752,16 @@ void SetupDirectBoot(std::string romname)
Cart->SetupDirectBoot(romname);
}
u8* GetSaveMemory()
{
return Cart ? Cart->GetSaveMemory() : nullptr;
}
u32 GetSaveMemoryLength()
{
return Cart ? Cart->GetSaveMemoryLength() : 0;
}
void EjectCart()
{
if (!CartInserted) return;

View File

@ -52,6 +52,9 @@ public:
virtual u8 SPIWrite(u8 val, u32 pos, bool last);
virtual u8* GetSaveMemory() const;
virtual u32 GetSaveMemoryLength() const;
protected:
void ReadROM(u32 addr, u32 len, u8* data, u32 offset);
@ -88,6 +91,9 @@ public:
virtual u8 SPIWrite(u8 val, u32 pos, bool last) override;
virtual u8* GetSaveMemory() const override;
virtual u32 GetSaveMemoryLength() const override;
protected:
void ReadROM_B7(u32 addr, u32 len, u8* data, u32 offset);
@ -223,6 +229,19 @@ bool LoadROM(const u8* romdata, u32 romlen);
void LoadSave(const u8* savedata, u32 savelen);
void SetupDirectBoot(std::string romname);
/// This function is intended to allow frontends to save and load SRAM
/// without using melonDS APIs.
/// Modifying the emulated SRAM for any other reason is strongly discouraged.
/// The returned pointer may be invalidated if the emulator is reset,
/// or when a new game is loaded.
/// Consequently, don't store the returned pointer for any longer than necessary.
/// @returns Pointer to this cart's SRAM if a cart is loaded and supports SRAM, otherwise \c nullptr.
u8* GetSaveMemory();
/// @returns The length of the buffer returned by ::GetSaveMemory()
/// if a cart is loaded and supports SRAM, otherwise zero.
u32 GetSaveMemoryLength();
void EjectCart();
void ResetCart();

View File

@ -30,6 +30,9 @@ using Platform::LogLevel;
namespace RTC
{
/// This value represents the Nintendo DS IO register,
/// \em not the value of the system's clock.
/// The actual system time is taken directly from the host.
u16 IO;
u8 Input;