Polish up archive support (#930)

* Fix directory path when extracting from archive

* Don't create new dir in execution dir of melonds
* Create it beside the archive instead

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* ArchiveUtil : Use QT functions for I/O

* Make it more platform independent, cleaner

* Fixes permission related crash on linux

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* NDSCart : Abstract out common code in LoadROM()

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Extract nds roms to memory

* Some stuff is still broken in the frontend

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* GBACart : Abstract out common code in LoadROM()

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Extract gba roms to memory

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Integrate archive support with recent files

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* onClickRecentFile : Pause emu thread conditionally

* Don't pause at start of the function
* If user opens an archive and hits cancel, it won't pause

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Handle Resets when loading from archives

* Ask user to pick the rom(s) again (i.e. GBA & NDS)
when there are multiple files in the archive(s)

* Directly load if only 1 file

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Archive support for drag-n-drop

* Also recent files support for drag-n-drop

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* main : Allocate rombuffer objects on stack

* Less messy, decreases chances of memory leaks

* Underlying implementation of qbytearray uses heap (hopefully?)

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* GetSavestateName : Archive support

* Construct ssname from srampath (since rompath has archive name)

NOTE: In general, archive name != rom file name !!!!!!!!!!

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Add srl and dsi as "direct-load" formats

* Direct-load = anything not in an archive

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Don't use static functions

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Remove QT stuff from Util_ROM

* Also, during reset, directly load file from archive (no rom picker)

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Remove QT includes from FrontendUtil.h

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Util_ROM/LoadROM() : Use SetupDSiNAND()

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Util_ROM/Reset() : Use strrchr()

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Util_ROM : Put Archive stuff behind ifdefs

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* main: Set parent widget for archive dialog boxes

Signed-off-by: Madhav Kanbur <abcdjdj@gmail.com>

* Revert "Util_ROM/Reset() : Use strrchr()"

This reverts commit c8af6f066f.
This commit is contained in:
Madhav Kanbur
2021-01-22 15:52:32 +05:30
committed by GitHub
parent d42ca1ec4b
commit 1e4c0c9d72
13 changed files with 449 additions and 108 deletions

View File

@ -19,6 +19,9 @@
#include <stdio.h>
#include <string.h>
#ifdef ARCHIVE_SUPPORT_ENABLED
#include "ArchiveUtil.h"
#endif
#include "FrontendUtil.h"
#include "Config.h"
#include "SharedConfig.h"
@ -38,6 +41,8 @@ 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;
@ -295,6 +300,84 @@ int LoadBIOS()
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();
@ -440,16 +523,76 @@ int Reset()
}
else
{
SetupSRAMPath(0);
if (!NDS::LoadROM(ROMPath[ROMSlot_NDS], SRAMPath[ROMSlot_NDS], directboot))
return Load_ROMLoadError;
char ext[5] = {0}; int _len = strlen(ROMPath[ROMSlot_NDS]);
strncpy(ext, ROMPath[ROMSlot_NDS] + _len - 4, 4);
if(!strncmp(ext, ".nds", 4) || !strncmp(ext, ".srl", 4) || !strncmp(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')
{
SetupSRAMPath(1);
if (!NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]))
return Load_ROMLoadError;
char ext[5] = {0}; int _len = strlen(ROMPath[ROMSlot_GBA]);
strncpy(ext, ROMPath[ROMSlot_NDS] + _len - 4, 4);
if(!strncmp(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();
@ -472,15 +615,24 @@ void GetSavestateName(int slot, char* filename, int len)
}
else
{
int l = strlen(ROMPath[ROMSlot_NDS]);
char *rompath;
char ext[5] = {0}; int _len = strlen(ROMPath[ROMSlot_NDS]);
strncpy(ext, ROMPath[ROMSlot_NDS] + _len - 4, 4);
if(!strncmp(ext, ".nds", 4) || !strncmp(ext, ".srl", 4) || !strncmp(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[ROMSlot_NDS][pos] != '.' && pos > 0) pos--;
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[ROMSlot_NDS], pos);
strncpy(&filename[0], rompath, pos);
}
strcpy(&filename[pos], ".ml");
filename[pos+3] = '0'+slot;