BizHawk/waterbox/melon/BizPlatform/BizSaveManager.cpp

114 lines
2.9 KiB
C++

#include "NDS.h"
#include "NDSCart.h"
#include "GBACart.h"
#include "DSi.h"
#include "DSi_NAND.h"
#include "Platform.h"
namespace Platform
{
constexpr u32 DSIWARE_CATEGORY = 0x00030004;
static bool NdsSaveRamIsDirty = false;
static bool GbaSaveRamIsDirty = false;
ECL_EXPORT void PutSaveRam(u8* data, u32 len)
{
const u32 ndsSaveLen = NDSCart::GetSaveMemoryLength();
const u32 gbaSaveLen = GBACart::GetSaveMemoryLength();
if (len >= ndsSaveLen)
{
NDS::LoadSave(data, len);
NdsSaveRamIsDirty = false;
data += ndsSaveLen;
len -= ndsSaveLen;
if (gbaSaveLen && len >= gbaSaveLen)
{
GBACart::LoadSave(data, gbaSaveLen);
GbaSaveRamIsDirty = false;
}
}
}
ECL_EXPORT void GetSaveRam(u8* data)
{
const u32 ndsSaveLen = NDSCart::GetSaveMemoryLength();
const u32 gbaSaveLen = GBACart::GetSaveMemoryLength();
if (ndsSaveLen)
{
memcpy(data, NDSCart::GetSaveMemory(), ndsSaveLen);
NdsSaveRamIsDirty = false;
}
if (gbaSaveLen)
{
memcpy(data + ndsSaveLen, GBACart::GetSaveMemory(), gbaSaveLen);
GbaSaveRamIsDirty = false;
}
}
ECL_EXPORT u32 GetSaveRamLength()
{
return NDSCart::GetSaveMemoryLength() + GBACart::GetSaveMemoryLength();
}
ECL_EXPORT bool SaveRamIsDirty()
{
return NdsSaveRamIsDirty || GbaSaveRamIsDirty;
}
ECL_EXPORT void ImportDSiWareSavs(u32 titleId)
{
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
{
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
DSi_NAND::ImportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
DSi_NAND::DeInit();
}
}
ECL_EXPORT void ExportDSiWareSavs(u32 titleId)
{
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
{
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PublicSav, "public.sav");
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_PrivateSav, "private.sav");
DSi_NAND::ExportTitleData(DSIWARE_CATEGORY, titleId, DSi_NAND::TitleData_BannerSav, "banner.sav");
DSi_NAND::DeInit();
}
}
ECL_EXPORT void DSiWareSavsLength(u32 titleId, u32* publicSavSize, u32* privateSavSize, u32* bannerSavSize)
{
*publicSavSize = *privateSavSize = *bannerSavSize = 0;
if (DSi_NAND::Init(&DSi::ARM7iBIOS[0x8308]))
{
u32 version;
NDSHeader header{};
DSi_NAND::GetTitleInfo(DSIWARE_CATEGORY, titleId, version, &header, nullptr);
*publicSavSize = header.DSiPublicSavSize;
*privateSavSize = header.DSiPrivateSavSize;
*bannerSavSize = (header.AppFlags & 0x04) ? 0x4000 : 0;
DSi_NAND::DeInit();
}
}
void WriteNDSSave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
{
NdsSaveRamIsDirty = true;
}
void WriteGBASave(const u8* savedata, u32 savelen, u32 writeoffset, u32 writelen)
{
GbaSaveRamIsDirty = true;
}
}