aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/Util_ROM.cpp
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2022-01-07 14:00:43 +0100
committerGitHub <noreply@github.com>2022-01-07 14:00:43 +0100
commite665e25bd3ea4b9af932e182b1c93e77b762ccb0 (patch)
tree06b5ceb336e42868806113cbf1f45add2b56a3e8 /src/frontend/Util_ROM.cpp
parentc4cd9da674bcfb8dca89086ce3ffa2d3b03438eb (diff)
Custom path support (#1333)
also including: * getting rid of shitty strings * all new, cleaner ROM handling code * base for DSi savestates * GBA slot addons (for now, memory cart)
Diffstat (limited to 'src/frontend/Util_ROM.cpp')
-rw-r--r--src/frontend/Util_ROM.cpp845
1 files changed, 0 insertions, 845 deletions
diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp
deleted file mode 100644
index 4d23c70..0000000
--- a/src/frontend/Util_ROM.cpp
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- Copyright 2016-2021 Arisotura
-
- This file is part of melonDS.
-
- melonDS is free software: you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation, either version 3 of the License, or (at your option)
- any later version.
-
- melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with melonDS. If not, see http://www.gnu.org/licenses/.
-*/
-
-#include <stdio.h>
-#include <string.h>
-
-#include <utility>
-
-#ifdef ARCHIVE_SUPPORT_ENABLED
-#include "ArchiveUtil.h"
-#endif
-#include "FrontendUtil.h"
-#include "SharedConfig.h"
-#include "Platform.h"
-
-#include "NDS.h"
-#include "DSi.h"
-#include "GBACart.h"
-
-#include "AREngine.h"
-
-
-namespace Frontend
-{
-
-char ROMPath [ROMSlot_MAX][1024];
-char SRAMPath [ROMSlot_MAX][1024];
-char PrevSRAMPath[ROMSlot_MAX][1024]; // for savestate 'undo load'
-
-char NDSROMExtension[4];
-
-bool SavestateLoaded;
-
-ARCodeFile* CheatFile;
-bool CheatsOn;
-
-
-void Init_ROM()
-{
- SavestateLoaded = false;
-
- memset(ROMPath[ROMSlot_NDS], 0, 1024);
- memset(ROMPath[ROMSlot_GBA], 0, 1024);
- memset(SRAMPath[ROMSlot_NDS], 0, 1024);
- memset(SRAMPath[ROMSlot_GBA], 0, 1024);
- memset(PrevSRAMPath[ROMSlot_NDS], 0, 1024);
- memset(PrevSRAMPath[ROMSlot_GBA], 0, 1024);
-
- CheatFile = nullptr;
- CheatsOn = false;
-}
-
-void DeInit_ROM()
-{
- if (CheatFile)
- {
- delete CheatFile;
- CheatFile = nullptr;
- }
-}
-
-// TODO: currently, when failing to load a ROM for whatever reason, we attempt
-// to revert to the previous state and resume execution; this may not be a very
-// good thing, depending on what state the core was left in.
-// should we do a better state revert (via the savestate system)? completely stop?
-
-void SetupSRAMPath(int slot)
-{
- strncpy(SRAMPath[slot], ROMPath[slot], 1023);
- SRAMPath[slot][1023] = '\0';
- strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3);
-}
-
-int VerifyDSBIOS()
-{
- FILE* f;
- long len;
-
- if (!Config::ExternalBIOSEnable) return Load_OK;
-
- f = Platform::OpenLocalFile(Config::BIOS9Path, "rb");
- if (!f) return Load_BIOS9Missing;
-
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- if (len != 0x1000)
- {
- fclose(f);
- return Load_BIOS9Bad;
- }
-
- fclose(f);
-
- f = Platform::OpenLocalFile(Config::BIOS7Path, "rb");
- if (!f) return Load_BIOS7Missing;
-
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- if (len != 0x4000)
- {
- fclose(f);
- return Load_BIOS7Bad;
- }
-
- fclose(f);
-
- return Load_OK;
-}
-
-int VerifyDSiBIOS()
-{
- FILE* f;
- long len;
-
- // TODO: check the first 32 bytes
-
- f = Platform::OpenLocalFile(Config::DSiBIOS9Path, "rb");
- if (!f) return Load_DSiBIOS9Missing;
-
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- if (len != 0x10000)
- {
- fclose(f);
- return Load_DSiBIOS9Bad;
- }
-
- fclose(f);
-
- f = Platform::OpenLocalFile(Config::DSiBIOS7Path, "rb");
- if (!f) return Load_DSiBIOS7Missing;
-
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- if (len != 0x10000)
- {
- fclose(f);
- return Load_DSiBIOS7Bad;
- }
-
- fclose(f);
-
- return Load_OK;
-}
-
-int VerifyDSFirmware()
-{
- FILE* f;
- long len;
-
- if (!Config::ExternalBIOSEnable) return Load_FirmwareNotBootable;
-
- f = Platform::OpenLocalFile(Config::FirmwarePath, "rb");
- if (!f) return Load_FirmwareNotBootable;
-
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- if (len == 0x20000)
- {
- // 128KB firmware, not bootable
- fclose(f);
- return Load_FirmwareNotBootable;
- }
- else if (len != 0x40000 && len != 0x80000)
- {
- fclose(f);
- return Load_FirmwareBad;
- }
-
- fclose(f);
-
- return Load_OK;
-}
-
-int VerifyDSiFirmware()
-{
- FILE* f;
- long len;
-
- f = Platform::OpenLocalFile(Config::DSiFirmwarePath, "rb");
- if (!f) return Load_FirmwareMissing;
-
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- if (len != 0x20000)
- {
- // not 128KB
- // TODO: check whether those work
- fclose(f);
- return Load_FirmwareBad;
- }
-
- fclose(f);
-
- return Load_OK;
-}
-
-int SetupDSiNAND()
-{
- FILE* f;
- long len;
-
- f = Platform::OpenLocalFile(Config::DSiNANDPath, "r+b");
- if (!f) return Load_DSiNANDMissing;
-
- // TODO: some basic checks
- // check that it has the nocash footer, and all
-
- DSi::SDMMCFile = f;
-
- return Load_OK;
-}
-
-void LoadCheats()
-{
- if (CheatFile)
- {
- delete CheatFile;
- CheatFile = nullptr;
- }
-
- char filename[1024];
- if (ROMPath[ROMSlot_NDS][0] != '\0')
- {
- strncpy(filename, ROMPath[ROMSlot_NDS], 1023);
- filename[1023] = '\0';
- strncpy(filename + strlen(ROMPath[ROMSlot_NDS]) - 3, "mch", 3);
- }
- else
- {
- strncpy(filename, "firmware.mch", 1023);
- }
-
- // TODO: check for error (malformed cheat file, ...)
- CheatFile = new ARCodeFile(filename);
-
- AREngine::SetCodeFile(CheatsOn ? CheatFile : nullptr);
-}
-
-int LoadBIOS()
-{
- DSi::CloseDSiNAND();
-
- int res;
-
- res = VerifyDSBIOS();
- if (res != Load_OK) return res;
-
- if (Config::ConsoleType == 1)
- {
- res = VerifyDSiBIOS();
- if (res != Load_OK) return res;
-
- res = VerifyDSiFirmware();
- if (res != Load_OK) return res;
-
- res = SetupDSiNAND();
- if (res != Load_OK) return res;
- }
- else
- {
- res = VerifyDSFirmware();
- if (res != Load_OK) return res;
- }
-
- // TODO:
- // original code in the libui frontend called NDS::LoadGBAROM() if needed
- // should this be carried over here?
- // is that behavior consistent with that of LoadROM() below?
-
- ROMPath[ROMSlot_NDS][0] = '\0';
- SRAMPath[ROMSlot_NDS][0] = '\0';
-
- NDS::SetConsoleType(Config::ConsoleType);
- NDS::LoadBIOS();
-
- SavestateLoaded = false;
-
- LoadCheats();
-
- return Load_OK;
-}
-
-int LoadROM(const u8 *romdata, u32 romlength, const char *archivefilename, const char *romfilename, const char *sramfilename, int slot)
-{
- int res;
- bool directboot = Config::DirectBoot != 0;
-
- if (Config::ConsoleType == 1 && slot == 1)
- {
- // cannot load a GBA ROM into a DSi
- return Load_ROMLoadError;
- }
-
- res = VerifyDSBIOS();
- if (res != Load_OK) return res;
-
- if (Config::ConsoleType == 1)
- {
- res = VerifyDSiBIOS();
- if (res != Load_OK) return res;
-
- res = VerifyDSiFirmware();
- if (res != Load_OK) return res;
-
- res = SetupDSiNAND();
- if (res != Load_OK) return res;
-
- GBACart::Eject();
- ROMPath[ROMSlot_GBA][0] = '\0';
- }
- else
- {
- res = VerifyDSFirmware();
- if (res != Load_OK)
- {
- if (res == Load_FirmwareNotBootable)
- directboot = true;
- else
- return res;
- }
- }
-
- char oldpath[1024];
- char oldsram[1024];
- strncpy(oldpath, ROMPath[slot], 1024);
- strncpy(oldsram, SRAMPath[slot], 1024);
-
- strncpy(SRAMPath[slot], sramfilename, 1024);
- strncpy(ROMPath[slot], archivefilename, 1024);
-
- NDS::SetConsoleType(Config::ConsoleType);
-
- if (slot == ROMSlot_NDS && NDS::LoadROM(romdata, romlength, SRAMPath[slot], directboot))
- {
- SavestateLoaded = false;
-
- LoadCheats();
-
- // Reload the inserted GBA cartridge (if any)
- // TODO: report failure there??
- //if (ROMPath[ROMSlot_GBA][0] != '\0') NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]);
-
- strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety
- return Load_OK;
- }
- else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(romdata, romlength, romfilename, SRAMPath[slot]))
- {
- SavestateLoaded = false; // checkme??
-
- strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety
- return Load_OK;
- }
- else
- {
- strncpy(ROMPath[slot], oldpath, 1024);
- strncpy(SRAMPath[slot], oldsram, 1024);
- return Load_ROMLoadError;
- }
-}
-
-int LoadROM(const char* file, int slot)
-{
- DSi::CloseDSiNAND();
-
- int res;
- bool directboot = Config::DirectBoot != 0;
-
- if (Config::ConsoleType == 1 && slot == 1)
- {
- // cannot load a GBA ROM into a DSi
- return Load_ROMLoadError;
- }
-
- res = VerifyDSBIOS();
- if (res != Load_OK) return res;
-
- if (Config::ConsoleType == 1)
- {
- res = VerifyDSiBIOS();
- if (res != Load_OK) return res;
-
- res = VerifyDSiFirmware();
- if (res != Load_OK) return res;
-
- res = SetupDSiNAND();
- if (res != Load_OK) return res;
-
- GBACart::Eject();
- ROMPath[ROMSlot_GBA][0] = '\0';
- }
- else
- {
- res = VerifyDSFirmware();
- if (res != Load_OK)
- {
- if (res == Load_FirmwareNotBootable)
- directboot = true;
- else
- return res;
- }
- }
-
- char oldpath[1024];
- char oldsram[1024];
- strncpy(oldpath, ROMPath[slot], 1024);
- strncpy(oldsram, SRAMPath[slot], 1024);
-
- strncpy(ROMPath[slot], file, 1023);
- ROMPath[slot][1023] = '\0';
-
- SetupSRAMPath(0);
- SetupSRAMPath(1);
-
- NDS::SetConsoleType(Config::ConsoleType);
-
- if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], directboot))
- {
- SavestateLoaded = false;
-
- LoadCheats();
-
- // Reload the inserted GBA cartridge (if any)
- // TODO: report failure there??
- if (ROMPath[ROMSlot_GBA][0] != '\0') NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]);
-
- strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety
- return Load_OK;
- }
- else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot]))
- {
- SavestateLoaded = false; // checkme??
-
- strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety
- return Load_OK;
- }
- else
- {
- strncpy(ROMPath[slot], oldpath, 1024);
- strncpy(SRAMPath[slot], oldsram, 1024);
- return Load_ROMLoadError;
- }
-}
-
-void ROMIcon(u8 (&data)[512], u16 (&palette)[16], u32* iconRef)
-{
- int index = 0;
- for (int i = 0; i < 4; i++)
- {
- for (int j = 0; j < 4; j++)
- {
- for (int k = 0; k < 8; k++)
- {
- for (int l = 0; l < 8; l++)
- {
- u8 pal_index = index % 2 ? data[index/2] >> 4 : data[index/2] & 0x0F;
- u8 r = ((palette[pal_index] >> 0) & 0x1F) * 255 / 31;
- u8 g = ((palette[pal_index] >> 5) & 0x1F) * 255 / 31;
- u8 b = ((palette[pal_index] >> 10) & 0x1F) * 255 / 31;
- u8 a = pal_index ? 255: 0;
- u32* row = &iconRef[256 * i + 32 * k + 8 * j];
- row[l] = (a << 24) | (r << 16) | (g << 8) | b;
- index++;
- }
- }
- }
- }
-}
-
-#define SEQ_FLIPV(i) ((i & 0b1000000000000000) >> 15)
-#define SEQ_FLIPH(i) ((i & 0b0100000000000000) >> 14)
-#define SEQ_PAL(i) ((i & 0b0011100000000000) >> 11)
-#define SEQ_BMP(i) ((i & 0b0000011100000000) >> 8)
-#define SEQ_DUR(i) ((i & 0b0000000011111111) >> 0)
-
-void AnimatedROMIcon(u8 (&data)[8][512], u16 (&palette)[8][16], u16 (&sequence)[64], u32 (&animatedTexRef)[32 * 32 * 64], std::vector<int> &animatedSequenceRef)
-{
- for (int i = 0; i < 64; i++)
- {
- if (!sequence[i])
- break;
- u32* frame = &animatedTexRef[32 * 32 * i];
- ROMIcon(data[SEQ_BMP(sequence[i])], palette[SEQ_PAL(sequence[i])], frame);
-
- if (SEQ_FLIPH(sequence[i]))
- {
- for (int x = 0; x < 32; x++)
- {
- for (int y = 0; y < 32/2; y++)
- {
- std::swap(frame[x * 32 + y], frame[x * 32 + (32 - 1 - y)]);
- }
- }
- }
- if (SEQ_FLIPV(sequence[i]))
- {
- for (int x = 0; x < 32/2; x++)
- {
- for (int y = 0; y < 32; y++)
- {
- std::swap(frame[x * 32 + y], frame[(32 - 1 - x) * 32 + y]);
- }
- }
- }
-
- for (int j = 0; j < SEQ_DUR(sequence[i]); j++)
- animatedSequenceRef.push_back(i);
- }
-}
-
-void UnloadROM(int slot)
-{
- if (slot == ROMSlot_NDS)
- {
- // TODO!
- }
- else if (slot == ROMSlot_GBA)
- {
- GBACart::Eject();
- }
-
- ROMPath[slot][0] = '\0';
-
- DSi::CloseDSiNAND();
-}
-
-int Reset()
-{
- DSi::CloseDSiNAND();
-
- int res;
- bool directboot = Config::DirectBoot != 0;
-
- res = VerifyDSBIOS();
- if (res != Load_OK) return res;
-
- if (Config::ConsoleType == 1)
- {
- res = VerifyDSiBIOS();
- if (res != Load_OK) return res;
-
- res = VerifyDSiFirmware();
- if (res != Load_OK) return res;
-
- res = SetupDSiNAND();
- if (res != Load_OK) return res;
-
- GBACart::Eject();
- ROMPath[ROMSlot_GBA][0] = '\0';
- }
- else
- {
- res = VerifyDSFirmware();
- if (res != Load_OK)
- {
- if (res == Load_FirmwareNotBootable)
- directboot = true;
- else
- return res;
- }
- }
-
- SavestateLoaded = false;
-
- NDS::SetConsoleType(Config::ConsoleType);
-
- if (ROMPath[ROMSlot_NDS][0] == '\0')
- {
- NDS::LoadBIOS();
- }
- else
- {
- char ext[5] = {0}; int _len = strlen(ROMPath[ROMSlot_NDS]);
- strncpy(ext, ROMPath[ROMSlot_NDS] + _len - 4, 4);
-
- if(!strncasecmp(ext, ".nds", 4) || !strncasecmp(ext, ".srl", 4) || !strncasecmp(ext, ".dsi", 4))
- {
- SetupSRAMPath(0);
- if (!NDS::LoadROM(ROMPath[ROMSlot_NDS], SRAMPath[ROMSlot_NDS], directboot))
- return Load_ROMLoadError;
- }
-#ifdef ARCHIVE_SUPPORT_ENABLED
- else
- {
- u8 *romdata = nullptr; u32 romlen;
- char romfilename[1024] = {0}, sramfilename[1024];
- strncpy(sramfilename, SRAMPath[ROMSlot_NDS], 1024); // Use existing SRAMPath
-
- int pos = strlen(sramfilename) - 1;
- while(pos > 0 && sramfilename[pos] != '/' && sramfilename[pos] != '\\')
- --pos;
-
- strncpy(romfilename, &sramfilename[pos + 1], 1024);
- strncpy(&romfilename[strlen(romfilename) - 3], NDSROMExtension, 3); // extension could be nds, srl or dsi
- printf("RESET loading from archive : %s\n", romfilename);
- romlen = Archive::ExtractFileFromArchive(ROMPath[ROMSlot_NDS], romfilename, &romdata);
- if(!romdata)
- return Load_ROMLoadError;
-
- bool ok = NDS::LoadROM(romdata, romlen, sramfilename, directboot);
- delete romdata;
- if(!ok)
- return Load_ROMLoadError;
- }
-#endif
- }
-
- if (ROMPath[ROMSlot_GBA][0] != '\0')
- {
- char ext[5] = {0}; int _len = strlen(ROMPath[ROMSlot_GBA]);
- strncpy(ext, ROMPath[ROMSlot_GBA] + _len - 4, 4);
-
- if(!strncasecmp(ext, ".gba", 4))
- {
- SetupSRAMPath(1);
- if (!NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]))
- return Load_ROMLoadError;
- }
-#ifdef ARCHIVE_SUPPORT_ENABLED
- else
- {
- u8 *romdata = nullptr; u32 romlen;
- char romfilename[1024] = {0}, sramfilename[1024];
- strncpy(sramfilename, SRAMPath[ROMSlot_GBA], 1024); // Use existing SRAMPath
-
- int pos = strlen(sramfilename) - 1;
- while(pos > 0 && sramfilename[pos] != '/' && sramfilename[pos] != '\\')
- --pos;
-
- strncpy(romfilename, &sramfilename[pos + 1], 1024);
- strncpy(&romfilename[strlen(romfilename) - 3], "gba", 3);
- printf("RESET loading from archive : %s\n", romfilename);
- romlen = Archive::ExtractFileFromArchive(ROMPath[ROMSlot_GBA], romfilename, &romdata);
- if(!romdata)
- return Load_ROMLoadError;
-
- bool ok = NDS::LoadGBAROM(romdata, romlen, romfilename, SRAMPath[ROMSlot_GBA]);
- delete romdata;
- if(!ok)
- return Load_ROMLoadError;
- }
-#endif
- }
-
- LoadCheats();
-
- return Load_OK;
-}
-
-
-// SAVESTATE TODO
-// * configurable paths. not everyone wants their ROM directory to be polluted, I guess.
-
-void GetSavestateName(int slot, char* filename, int len)
-{
- int pos;
-
- if (ROMPath[ROMSlot_NDS][0] == '\0') // running firmware, no ROM
- {
- strcpy(filename, "firmware");
- pos = 8;
- }
- else
- {
- char *rompath;
- char ext[5] = {0}; int _len = strlen(ROMPath[ROMSlot_NDS]);
- strncpy(ext, ROMPath[ROMSlot_NDS] + _len - 4, 4);
-
- if(!strncasecmp(ext, ".nds", 4) || !strncasecmp(ext, ".srl", 4) || !strncasecmp(ext, ".dsi", 4))
- rompath = ROMPath[ROMSlot_NDS];
- else
- rompath = SRAMPath[ROMSlot_NDS]; // If archive, construct ssname from sram file
-
- int l = strlen(rompath);
- pos = l;
- while (rompath[pos] != '.' && pos > 0) pos--;
- if (pos == 0) pos = l;
-
- // avoid buffer overflow. shoddy
- if (pos > len-5) pos = len-5;
-
- strncpy(&filename[0], rompath, pos);
- }
- strcpy(&filename[pos], ".ml");
- filename[pos+3] = '0'+slot;
- filename[pos+4] = '\0';
-}
-
-bool SavestateExists(int slot)
-{
- char ssfile[1024];
- GetSavestateName(slot, ssfile, 1024);
- return Platform::FileExists(ssfile);
-}
-
-bool LoadState(const char* filename)
-{
- u32 oldGBACartCRC = GBACart::CartCRC;
-
- // backup
- Savestate* backup = new Savestate("timewarp.mln", true);
- NDS::DoSavestate(backup);
- delete backup;
-
- bool failed = false;
-
- Savestate* state = new Savestate(filename, false);
- if (state->Error)
- {
- delete state;
-
- //uiMsgBoxError(MainWindow, "Error", "Could not load savestate file.");
-
- // current state might be crapoed, so restore from sane backup
- state = new Savestate("timewarp.mln", false);
- failed = true;
- }
-
- NDS::DoSavestate(state);
- delete state;
-
- if (!failed)
- {
- if (Config::SavestateRelocSRAM && ROMPath[ROMSlot_NDS][0]!='\0')
- {
- strncpy(PrevSRAMPath[ROMSlot_NDS], SRAMPath[0], 1024);
-
- strncpy(SRAMPath[ROMSlot_NDS], filename, 1019);
- int len = strlen(SRAMPath[ROMSlot_NDS]);
- strcpy(&SRAMPath[ROMSlot_NDS][len], ".sav");
- SRAMPath[ROMSlot_NDS][len+4] = '\0';
-
- NDS::RelocateSave(SRAMPath[ROMSlot_NDS], 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[ROMSlot_GBA][0] = '\0';
- SRAMPath[ROMSlot_GBA][0] = '\0';
- loadedPartialGBAROM = true;
- }
-
- // TODO forward this to user in a meaningful way!!
- /*char msg[64];
- 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;
- }
-
- return !failed;
-}
-
-bool SaveState(const char* filename)
-{
- Savestate* state = new Savestate(filename, true);
- if (state->Error)
- {
- delete state;
- return false;
- }
- else
- {
- NDS::DoSavestate(state);
- delete state;
-
- if (Config::SavestateRelocSRAM && ROMPath[ROMSlot_NDS][0]!='\0')
- {
- strncpy(SRAMPath[ROMSlot_NDS], filename, 1019);
- int len = strlen(SRAMPath[ROMSlot_NDS]);
- strcpy(&SRAMPath[ROMSlot_NDS][len], ".sav");
- SRAMPath[ROMSlot_NDS][len+4] = '\0';
-
- NDS::RelocateSave(SRAMPath[ROMSlot_NDS], true);
- }
- }
-
- return true;
-}
-
-void UndoStateLoad()
-{
- if (!SavestateLoaded) return;
-
- // pray that this works
- // what do we do if it doesn't???
- // but it should work.
- Savestate* backup = new Savestate("timewarp.mln", false);
- NDS::DoSavestate(backup);
- delete backup;
-
- if (ROMPath[ROMSlot_NDS][0]!='\0')
- {
- strncpy(SRAMPath[ROMSlot_NDS], PrevSRAMPath[ROMSlot_NDS], 1024);
- NDS::RelocateSave(SRAMPath[ROMSlot_NDS], false);
- }
-}
-
-int ImportSRAM(const char* filename)
-{
- FILE* file = fopen(filename, "rb");
- fseek(file, 0, SEEK_END);
- u32 size = ftell(file);
- u8* importData = new u8[size];
- rewind(file);
- fread(importData, size, 1, file);
- fclose(file);
-
- int diff = NDS::ImportSRAM(importData, size);
- delete[] importData;
- return diff;
-}
-
-void EnableCheats(bool enable)
-{
- CheatsOn = enable;
- if (CheatFile)
- AREngine::SetCodeFile(CheatsOn ? CheatFile : nullptr);
-}
-
-}