more WIP. ROM loading working, sorta. not loading saves or anything yet.

This commit is contained in:
Arisotura
2021-12-29 15:42:30 +01:00
parent aa443c6bce
commit 9529356062
10 changed files with 353 additions and 98 deletions

View File

@ -648,6 +648,9 @@ void Reset()
void Eject() void Eject()
{ {
if (Cart) delete Cart;
Cart = nullptr;
if (CartROM) delete[] CartROM; if (CartROM) delete[] CartROM;
CartInserted = false; CartInserted = false;
@ -656,9 +659,6 @@ void Eject()
CartCRC = 0; CartCRC = 0;
CartID = 0; CartID = 0;
if (Cart) delete Cart;
Cart = nullptr;
Reset(); Reset();
} }

View File

@ -903,12 +903,12 @@ bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen)
if (savedata && savelen) if (savedata && savelen)
NDSCart::LoadSave(savedata, savelen); NDSCart::LoadSave(savedata, savelen);
//Running = true; return true;
} }
void EjectCart() void EjectCart()
{ {
printf("TODO!!!!\n"); NDSCart::EjectCart();
} }
bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen)

View File

@ -55,8 +55,6 @@ bool CartInserted;
u8* CartROM; u8* CartROM;
u32 CartROMSize; u32 CartROMSize;
u32 CartID; u32 CartID;
bool CartIsHomebrew;
bool CartIsDSi;
NDSHeader Header; NDSHeader Header;
NDSBanner Banner; NDSBanner Banner;
@ -1505,16 +1503,14 @@ void DeInit()
void Reset() void Reset()
{ {
if (Cart) delete Cart;
Cart = nullptr;
CartInserted = false; CartInserted = false;
if (CartROM) delete[] CartROM; if (CartROM) delete[] CartROM;
CartROM = nullptr; CartROM = nullptr;
CartROMSize = 0; CartROMSize = 0;
CartID = 0; CartID = 0;
CartIsHomebrew = false;
CartIsDSi = false;
if (Cart) delete Cart;
Cart = nullptr;
ResetCart(); ResetCart();
} }
@ -1624,7 +1620,8 @@ void DecryptSecureArea(u8* out)
//bool LoadROMCommon(u32 filelength, const char *sram, bool direct) //bool LoadROMCommon(u32 filelength, const char *sram, bool direct)
bool LoadROM(const u8* romdata, u32 romlen) bool LoadROM(const u8* romdata, u32 romlen)
{ {
//NDS::Reset(); if (CartInserted)
EjectCart();
CartROMSize = 0x200; CartROMSize = 0x200;
while (CartROMSize < romlen) while (CartROMSize < romlen)
@ -1654,10 +1651,10 @@ bool LoadROM(const u8* romdata, u32 romlen)
(u32)Header.GameCode[0]; (u32)Header.GameCode[0];
u8 unitcode = Header.UnitCode; u8 unitcode = Header.UnitCode;
CartIsDSi = (unitcode & 0x02) != 0; bool dsi = (unitcode & 0x02) != 0;
u32 arm9base = Header.ARM9ROMOffset; u32 arm9base = Header.ARM9ROMOffset;
CartIsHomebrew = (arm9base < 0x4000) || (gamecode == 0x23232323); bool homebrew = (arm9base < 0x4000) || (gamecode == 0x23232323);
ROMListEntry romparams; ROMListEntry romparams;
if (!ReadROMParams(gamecode, &romparams)) if (!ReadROMParams(gamecode, &romparams))
@ -1667,7 +1664,7 @@ bool LoadROM(const u8* romdata, u32 romlen)
romparams.GameCode = gamecode; romparams.GameCode = gamecode;
romparams.ROMSize = CartROMSize; romparams.ROMSize = CartROMSize;
if (CartIsHomebrew) if (homebrew)
romparams.SaveMemType = 0; // no saveRAM for homebrew romparams.SaveMemType = 0; // no saveRAM for homebrew
else else
romparams.SaveMemType = 2; // assume EEPROM 64k (TODO FIXME) romparams.SaveMemType = 2; // assume EEPROM 64k (TODO FIXME)
@ -1691,7 +1688,7 @@ bool LoadROM(const u8* romdata, u32 romlen)
if (romparams.SaveMemType >= 8 && romparams.SaveMemType <= 10) if (romparams.SaveMemType >= 8 && romparams.SaveMemType <= 10)
CartID |= 0x08000000; // NAND flag CartID |= 0x08000000; // NAND flag
if (CartIsDSi) if (dsi)
CartID |= 0x40000000; CartID |= 0x40000000;
// cart ID for Jam with the Band // cart ID for Jam with the Band
@ -1719,7 +1716,7 @@ bool LoadROM(const u8* romdata, u32 romlen)
Key1_Encrypt((u32*)&CartROM[arm9base]); Key1_Encrypt((u32*)&CartROM[arm9base]);
} }
} }
printf("FAZIL");
CartInserted = true; CartInserted = true;
u32 irversion = 0; u32 irversion = 0;
@ -1731,7 +1728,7 @@ bool LoadROM(const u8* romdata, u32 romlen)
irversion = 2; // Pokémon HG/SS, B/W, B2/W2 irversion = 2; // Pokémon HG/SS, B/W, B2/W2
} }
if (CartIsHomebrew) if (homebrew)
Cart = new CartHomebrew(CartROM, CartROMSize, CartID); Cart = new CartHomebrew(CartROM, CartROMSize, CartID);
else if (CartID & 0x08000000) else if (CartID & 0x08000000)
Cart = new CartRetailNAND(CartROM, CartROMSize, CartID); Cart = new CartRetailNAND(CartROM, CartROMSize, CartID);
@ -1741,7 +1738,7 @@ bool LoadROM(const u8* romdata, u32 romlen)
Cart = new CartRetailBT(CartROM, CartROMSize, CartID); Cart = new CartRetailBT(CartROM, CartROMSize, CartID);
else else
Cart = new CartRetail(CartROM, CartROMSize, CartID); Cart = new CartRetail(CartROM, CartROMSize, CartID);
printf("PFART\n");
if (Cart) if (Cart)
Cart->Reset(); Cart->Reset();
/*{ /*{
@ -1762,14 +1759,14 @@ bool LoadROM(const u8* romdata, u32 romlen)
//if (Cart) Cart->LoadSave(sram, romparams.SaveMemType); //if (Cart) Cart->LoadSave(sram, romparams.SaveMemType);
if (Cart && romparams.SaveMemType > 0) if (Cart && romparams.SaveMemType > 0)
Cart->SetupSave(romparams.SaveMemType); Cart->SetupSave(romparams.SaveMemType);
printf("PROEUPRAOUTTE\n");
return true; return true;
} }
void LoadSave(const u8* savedata, u32 savelen) void LoadSave(const u8* savedata, u32 savelen)
{ {printf("CARTSAVE\n");
if (Cart) if (Cart)
Cart->LoadSave(savedata, savelen); Cart->LoadSave(savedata, savelen);printf("SAVE FARTED\n");
} }
/*bool LoadROM(const char* path, const char* sram, bool direct) /*bool LoadROM(const char* path, const char* sram, bool direct)
@ -1854,6 +1851,26 @@ int ImportSRAM(const u8* data, u32 length)
return 0; return 0;
}*/ }*/
void EjectCart()
{
if (!CartInserted) return;
// ejecting the cart triggers the gamecard IRQ
NDS::SetIRQ(0, NDS::IRQ_CartIREQMC);
NDS::SetIRQ(1, NDS::IRQ_CartIREQMC);
if (Cart) delete Cart;
Cart = nullptr;
CartInserted = false;
if (CartROM) delete[] CartROM;
CartROM = nullptr;
CartROMSize = 0;
CartID = 0;
// CHECKME: does an eject imply anything for the ROM/SPI transfer registers?
}
void ResetCart() void ResetCart()
{ {
// CHECKME: what if there is a transfer in progress? // CHECKME: what if there is a transfer in progress?

View File

@ -218,6 +218,8 @@ bool LoadROM(const u8* romdata, u32 romlen);
void LoadSave(const u8* savedata, u32 savelen); void LoadSave(const u8* savedata, u32 savelen);
void SetupDirectBoot(std::string romname); void SetupDirectBoot(std::string romname);
void EjectCart();
//void FlushSRAMFile(); //void FlushSRAMFile();
//void RelocateSave(const char* path, bool write); //void RelocateSave(const char* path, bool write);

View File

@ -116,7 +116,45 @@ QVector<QString> ExtractFileFromArchive(QString path, QString wantedFile, QByteA
} }
u32 ExtractFileFromArchive(const char* path, const char* wantedFile, u8 **romdata) u32 ExtractFileFromArchive(QString path, QString wantedFile, u8** filedata, u32* filesize)
{
struct archive *a = archive_read_new();
struct archive_entry *entry;
int r;
if (!filedata) return -1;
archive_read_support_format_all(a);
archive_read_support_filter_all(a);
//r = archive_read_open_filename(a, path, 10240);
r = melon_archive_open(a, path, 10240);
if (r != ARCHIVE_OK)
{
return -1;
}
while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
{
if (strcmp(wantedFile.toUtf8().constData(), archive_entry_pathname_utf8(entry)) == 0)
{
break;
}
}
size_t bytesToRead = archive_entry_size(entry);
if (filesize) *filesize = bytesToRead;
*filedata = new u8[bytesToRead];
ssize_t bytesRead = archive_read_data(a, *filedata, bytesToRead);
archive_read_close(a);
archive_read_free(a);
return (u32)bytesRead;
}
/*u32 ExtractFileFromArchive(const char* path, const char* wantedFile, u8 **romdata)
{ {
QByteArray romBuffer; QByteArray romBuffer;
QVector<QString> extractResult = ExtractFileFromArchive(path, wantedFile, &romBuffer); QVector<QString> extractResult = ExtractFileFromArchive(path, wantedFile, &romBuffer);
@ -131,6 +169,6 @@ u32 ExtractFileFromArchive(const char* path, const char* wantedFile, u8 **romdat
memcpy(*romdata, romBuffer.data(), len); memcpy(*romdata, romBuffer.data(), len);
return len; return len;
} }*/
} }

View File

@ -36,7 +36,8 @@ namespace Archive
{ {
QVector<QString> ListArchive(QString path); QVector<QString> ListArchive(QString path);
QVector<QString> ExtractFileFromArchive(QString path, QString wantedFile, QByteArray *romBuffer); u32 ExtractFileFromArchive(QString path, QString wantedFile, u8** filedata, u32* filesize);
//QVector<QString> ExtractFileFromArchive(QString path, QString wantedFile, QByteArray *romBuffer);
//u32 ExtractFileFromArchive(const char* path, const char* wantedFile, u8 **romdata); //u32 ExtractFileFromArchive(const char* path, const char* wantedFile, u8 **romdata);
} }

View File

@ -51,7 +51,7 @@ ARCodeFile* CheatFile;
bool CheatsOn; bool CheatsOn;
void Init_ROM() /*void Init_ROM()
{ {
SavestateLoaded = false; SavestateLoaded = false;
@ -73,55 +73,53 @@ void DeInit_ROM()
delete CheatFile; delete CheatFile;
CheatFile = nullptr; CheatFile = nullptr;
} }
} }*/
// TODO: currently, when failing to load a ROM for whatever reason, we attempt // 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 // 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. // good thing, depending on what state the core was left in.
// should we do a better state revert (via the savestate system)? completely stop? // should we do a better state revert (via the savestate system)? completely stop?
void SetupSRAMPath(int slot) /*void SetupSRAMPath(int slot)
{ {
SRAMPath[slot] = ROMPath[slot].substr(0, ROMPath[slot].length() - 3) + "sav"; SRAMPath[slot] = ROMPath[slot].substr(0, ROMPath[slot].length() - 3) + "sav";
} }*/
int VerifyDSBIOS() QString VerifyDSBIOS()
{ {
FILE* f; FILE* f;
long len; long len;
if (!Config::ExternalBIOSEnable) return Load_OK;
f = Platform::OpenLocalFile(Config::BIOS9Path, "rb"); f = Platform::OpenLocalFile(Config::BIOS9Path, "rb");
if (!f) return Load_BIOS9Missing; if (!f) return "DS ARM9 BIOS was not found or could not be accessed. Check your emu settings.";
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
if (len != 0x1000) if (len != 0x1000)
{ {
fclose(f); fclose(f);
return Load_BIOS9Bad; return "DS ARM9 BIOS is not a valid BIOS dump.";
} }
fclose(f); fclose(f);
f = Platform::OpenLocalFile(Config::BIOS7Path, "rb"); f = Platform::OpenLocalFile(Config::BIOS7Path, "rb");
if (!f) return Load_BIOS7Missing; if (!f) return "DS ARM7 BIOS was not found or could not be accessed. Check your emu settings.";
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
if (len != 0x4000) if (len != 0x4000)
{ {
fclose(f); fclose(f);
return Load_BIOS7Bad; return "DS ARM7 BIOS is not a valid BIOS dump.";
} }
fclose(f); fclose(f);
return Load_OK; return "";
} }
int VerifyDSiBIOS() QString VerifyDSiBIOS()
{ {
FILE* f; FILE* f;
long len; long len;
@ -129,43 +127,41 @@ int VerifyDSiBIOS()
// TODO: check the first 32 bytes // TODO: check the first 32 bytes
f = Platform::OpenLocalFile(Config::DSiBIOS9Path, "rb"); f = Platform::OpenLocalFile(Config::DSiBIOS9Path, "rb");
if (!f) return Load_DSiBIOS9Missing; if (!f) return "DSi ARM9 BIOS was not found or could not be accessed. Check your emu settings.";
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
if (len != 0x10000) if (len != 0x10000)
{ {
fclose(f); fclose(f);
return Load_DSiBIOS9Bad; return "DSi ARM9 BIOS is not a valid BIOS dump.";
} }
fclose(f); fclose(f);
f = Platform::OpenLocalFile(Config::DSiBIOS7Path, "rb"); f = Platform::OpenLocalFile(Config::DSiBIOS7Path, "rb");
if (!f) return Load_DSiBIOS7Missing; if (!f) return "DSi ARM7 BIOS was not found or could not be accessed. Check your emu settings.";
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
if (len != 0x10000) if (len != 0x10000)
{ {
fclose(f); fclose(f);
return Load_DSiBIOS7Bad; return "DSi ARM7 BIOS is not a valid BIOS dump.";
} }
fclose(f); fclose(f);
return Load_OK; return "";
} }
int VerifyDSFirmware() QString VerifyDSFirmware()
{ {
FILE* f; FILE* f;
long len; long len;
if (!Config::ExternalBIOSEnable) return Load_FirmwareNotBootable;
f = Platform::OpenLocalFile(Config::FirmwarePath, "rb"); f = Platform::OpenLocalFile(Config::FirmwarePath, "rb");
if (!f) return Load_FirmwareNotBootable; if (!f) return "DS firmware was not found or could not be accessed. Check your emu settings.";
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
@ -173,26 +169,27 @@ int VerifyDSFirmware()
{ {
// 128KB firmware, not bootable // 128KB firmware, not bootable
fclose(f); fclose(f);
return Load_FirmwareNotBootable; // TODO report it somehow? detect in core?
return "";
} }
else if (len != 0x40000 && len != 0x80000) else if (len != 0x40000 && len != 0x80000)
{ {
fclose(f); fclose(f);
return Load_FirmwareBad; return "DS firmware is not a valid firmware dump.";
} }
fclose(f); fclose(f);
return Load_OK; return "";
} }
int VerifyDSiFirmware() QString VerifyDSiFirmware()
{ {
FILE* f; FILE* f;
long len; long len;
f = Platform::OpenLocalFile(Config::DSiFirmwarePath, "rb"); f = Platform::OpenLocalFile(Config::DSiFirmwarePath, "rb");
if (!f) return Load_FirmwareMissing; if (!f) return "DSi firmware was not found or could not be accessed. Check your emu settings.";
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
@ -201,30 +198,132 @@ int VerifyDSiFirmware()
// not 128KB // not 128KB
// TODO: check whether those work // TODO: check whether those work
fclose(f); fclose(f);
return Load_FirmwareBad; return "DSi firmware is not a valid firmware dump.";
} }
fclose(f); fclose(f);
return Load_OK; return "";
} }
int SetupDSiNAND() QString VerifyDSiNAND()
{ {
FILE* f; FILE* f;
long len; long len;
f = Platform::OpenLocalFile(Config::DSiNANDPath, "r+b"); f = Platform::OpenLocalFile(Config::DSiNANDPath, "r+b");
if (!f) return Load_DSiNANDMissing; if (!f) return "DSi NAND was not found or could not be accessed. Check your emu settings.";
// TODO: some basic checks // TODO: some basic checks
// check that it has the nocash footer, and all // check that it has the nocash footer, and all
DSi::SDMMCFile = f; fclose(f);
return Load_OK; return "";
} }
QString VerifySetup()
{
QString res;
if (Config::ExternalBIOSEnable)
{
res = VerifyDSBIOS();
if (!res.isEmpty()) return res;
}
if (Config::ConsoleType == 1)
{
res = VerifyDSiBIOS();
if (!res.isEmpty()) return res;
if (Config::ExternalBIOSEnable)
{
res = VerifyDSiFirmware();
if (!res.isEmpty()) return res;
}
res = VerifyDSiNAND();
if (!res.isEmpty()) return res;
}
else
{
if (Config::ExternalBIOSEnable)
{
res = VerifyDSFirmware();
if (!res.isEmpty()) return res;
}
}
return "";
}
bool LoadROM(QStringList filepath, bool reset)
{
if (filepath.empty()) return false;
u8* filedata;
u32 filelen;
int num = filepath.count();
if (num == 1)
{
// regular file
FILE* f = Platform::OpenFile(filepath.at(0).toStdString(), "rb", true);
if (!f) return false;
fseek(f, 0, SEEK_END);
long len = ftell(f);
if (len > 0x40000000)
{
fclose(f);
return false;
}
fseek(f, 0, SEEK_SET);
filedata = new u8[len];
size_t nread = fread(filedata, (size_t)len, 1, f);
if (nread != 1)
{
fclose(f);
delete[] filedata;
return false;
}
fclose(f);
filelen = (u32)len;
}
#ifdef ARCHIVE_SUPPORT_ENABLED
else if (num == 2)
{
// file inside archive
u32 lenread = Archive::ExtractFileFromArchive(filepath.at(0), filepath.at(1), &filedata, &filelen);
if (lenread < 0) return false;
if (!filedata) return false;
if (lenread != filelen)
{
delete[] filedata;
return false;
}
}
#endif
else
return false;
if (reset)
{
NDS::Reset();
}
// TODO: SAVE
return NDS::LoadCart(filedata, filelen, nullptr, 0);
}
void LoadCheats() void LoadCheats()
{ {
if (CheatFile) if (CheatFile)
@ -251,7 +350,7 @@ void LoadCheats()
AREngine::SetCodeFile(CheatsOn ? CheatFile : nullptr); AREngine::SetCodeFile(CheatsOn ? CheatFile : nullptr);
} }
int LoadBIOS() /*int LoadBIOS()
{ {
DSi::CloseDSiNAND(); DSi::CloseDSiNAND();
@ -363,7 +462,7 @@ int LoadROM(const u8 *romdata, u32 romlength, const char *archivefilename, const
PrevSRAMPath[slot] = SRAMPath[slot]; // safety PrevSRAMPath[slot] = SRAMPath[slot]; // safety
return Load_OK; return Load_OK;
} }
else*/ else*-/
{ {
ROMPath[slot] = oldpath; ROMPath[slot] = oldpath;
SRAMPath[slot] = oldsram; SRAMPath[slot] = oldsram;
@ -443,13 +542,13 @@ int LoadROM(const char* file, int slot)
PrevSRAMPath[slot] = SRAMPath[slot]; // safety PrevSRAMPath[slot] = SRAMPath[slot]; // safety
return Load_OK; return Load_OK;
} }
else*/ else*-/
{ {
ROMPath[slot] = oldpath; ROMPath[slot] = oldpath;
SRAMPath[slot] = oldsram; SRAMPath[slot] = oldsram;
return Load_ROMLoadError; return Load_ROMLoadError;
} }
} }*/
void ROMIcon(u8 (&data)[512], u16 (&palette)[16], u32* iconRef) void ROMIcon(u8 (&data)[512], u16 (&palette)[16], u32* iconRef)
{ {
@ -535,7 +634,7 @@ void UnloadROM(int slot)
int Reset() int Reset()
{ {
DSi::CloseDSiNAND(); /*DSi::CloseDSiNAND();
int res; int res;
bool directboot = Config::DirectBoot != 0; bool directboot = Config::DirectBoot != 0;
@ -611,7 +710,7 @@ int Reset()
bool ok = NDS::LoadROM(romdata, romlen, sramfilename, directboot); bool ok = NDS::LoadROM(romdata, romlen, sramfilename, directboot);
delete romdata; delete romdata;
if (!ok)*/ if (!ok)*-/
return Load_ROMLoadError; return Load_ROMLoadError;
} }
#endif #endif
@ -650,13 +749,13 @@ int Reset()
bool ok = NDS::LoadGBAROM(romdata, romlen, romfilename, SRAMPath[ROMSlot_GBA]); bool ok = NDS::LoadGBAROM(romdata, romlen, romfilename, SRAMPath[ROMSlot_GBA]);
delete romdata; delete romdata;
if (!ok)*/ if (!ok)*-/
return Load_ROMLoadError; return Load_ROMLoadError;
} }
#endif #endif
} }
LoadCheats(); LoadCheats();*/
return Load_OK; return Load_OK;
} }

View File

@ -27,6 +27,9 @@
namespace ROMLoader namespace ROMLoader
{ {
QString VerifySetup();
bool LoadROM(QStringList filepath, bool reset);
enum enum
{ {
ROMSlot_NDS = 0, ROMSlot_NDS = 0,

View File

@ -81,6 +81,7 @@
#include "main_shaders.h" #include "main_shaders.h"
#include "ROMLoader.h"
#include "ArchiveUtil.h" #include "ArchiveUtil.h"
// TODO: uniform variable spelling // TODO: uniform variable spelling
@ -1792,7 +1793,7 @@ void MainWindow::dropEvent(QDropEvent* event)
QList<QUrl> urls = event->mimeData()->urls(); QList<QUrl> urls = event->mimeData()->urls();
if (urls.count() > 1) return; // not handling more than one file at once if (urls.count() > 1) return; // not handling more than one file at once
emuThread->emuPause(); /*emuThread->emuPause();
QString filename = urls.at(0).toLocalFile(); QString filename = urls.at(0).toLocalFile();
QString ext = filename.right(3).toLower(); QString ext = filename.right(3).toLower();
@ -1852,7 +1853,7 @@ void MainWindow::dropEvent(QDropEvent* event)
else else
{ {
emuThread->emuRun(); emuThread->emuRun();
} }*/
} }
void MainWindow::onAppStateChanged(Qt::ApplicationState state) void MainWindow::onAppStateChanged(Qt::ApplicationState state)
@ -1912,7 +1913,7 @@ QString MainWindow::loadErrorStr(int error)
} }
} }
void MainWindow::loadROM(QByteArray *romData, QString archiveFileName, QString romFileName) /*void MainWindow::loadROM(QByteArray *romData, QString archiveFileName, QString romFileName)
{ {
recentFileList.removeAll(archiveFileName); recentFileList.removeAll(archiveFileName);
recentFileList.prepend(archiveFileName); recentFileList.prepend(archiveFileName);
@ -2006,13 +2007,60 @@ void MainWindow::loadROM(QString filename)
{ {
emuThread->emuRun(); emuThread->emuRun();
} }
}*/
bool MainWindow::verifySetup()
{
QString res = ROMLoader::VerifySetup();
if (!res.isEmpty())
{
QMessageBox::critical(this, "melonDS", res);
return false;
}
return true;
} }
void MainWindow::pickAndLoadROM(bool gba) QString MainWindow::pickFileFromArchive(QString archiveFileName)
{
QVector<QString> archiveROMList = Archive::ListArchive(archiveFileName);
QString romFileName = ""; // file name inside archive
if (archiveROMList.size() > 2)
{
archiveROMList.removeFirst();
bool ok;
QString toLoad = QInputDialog::getItem(this, "melonDS",
"This archive contains multiple files. Select which ROM you want to load.", archiveROMList.toList(), 0, false, &ok);
if (!ok) // User clicked on cancel
return QString();
romFileName = toLoad;
}
else if (archiveROMList.size() == 2)
{
romFileName = archiveROMList.at(1);
}
else if ((archiveROMList.size() == 1) && (archiveROMList[0] == QString("OK")))
{
QMessageBox::warning(this, "melonDS", "This archive is empty.");
}
else
{
QMessageBox::critical(this, "melonDS", "This archive could not be read. It may be corrupt or you don't have the permissions.");
}
return romFileName;
}
QStringList MainWindow::pickROM(bool gba)
{ {
QString console; QString console;
QStringList romexts; QStringList romexts;
QStringList arcexts{"*.zip", "*.7z", "*.rar", "*.tar", "*.gz", "*.xz", "*.bz2"}; QStringList arcexts{"*.zip", "*.7z", "*.rar", "*.tar", "*.tar.gz", "*.tar.xz", "*.tar.bz2"};
QStringList ret;
if (gba) if (gba)
{ {
@ -2025,8 +2073,6 @@ void MainWindow::pickAndLoadROM(bool gba)
romexts.append({"*.nds", "*.dsi", "*.srl"}); romexts.append({"*.nds", "*.dsi", "*.srl"});
} }
emuThread->emuPause();
QString filter = romexts.join(' ') + " " + arcexts.join(' '); QString filter = romexts.join(' ') + " " + arcexts.join(' ');
filter = console + " ROMs (" + filter + ");;Any file (*.*)"; filter = console + " ROMs (" + filter + ");;Any file (*.*)";
@ -2035,37 +2081,81 @@ void MainWindow::pickAndLoadROM(bool gba)
QString::fromStdString(Config::LastROMFolder), QString::fromStdString(Config::LastROMFolder),
filter); filter);
if (filename.isEmpty()) if (filename.isEmpty())
{ return ret;
emuThread->emuUnpause();
return;
}
int pos = filename.length() - 1; int pos = filename.length() - 1;
while (filename[pos] != '/' && filename[pos] != '\\' && pos > 0) pos--; while (filename[pos] != '/' && filename[pos] != '\\' && pos > 0) pos--;
QString path_dir = filename.left(pos); QString path_dir = filename.left(pos);
QString path_file = filename.mid(pos+1); QString path_file = filename.mid(pos+1);
QString path_ext = path_file.mid(path_file.lastIndexOf('.')).toLower();
Config::LastROMFolder = path_dir.toStdString(); Config::LastROMFolder = path_dir.toStdString();
printf("LOADING ROM: %s\n", filename.toStdString().c_str()); bool isarc = false;
printf("- %s\n", path_dir.toStdString().c_str()); for (const auto& ext : arcexts)
printf("- %s\n", path_file.toStdString().c_str());
printf("- %s\n", path_ext.toStdString().c_str());
if (arcexts.contains("*"+path_ext))
{ {
QByteArray romBuffer; int l = ext.length() - 1;
QString arcfile = pickAndExtractFileFromArchive(filename, &romBuffer); if (path_file.right(l).toLower() == ext.right(l))
{
printf("ARCHIVE: %s\n", arcfile.toStdString().c_str()); isarc = true;
printf("SIZE=%d\n", romBuffer.size()); break;
} }
}
if (isarc)
{
path_file = pickFileFromArchive(filename);
if (path_file.isEmpty())
return ret;
ret.append(filename);
ret.append(path_file);
}
else
{
ret.append(filename);
}
return ret;
} }
void MainWindow::onOpenFile() void MainWindow::onOpenFile()
{ {
pickAndLoadROM(false); emuThread->emuPause();
// stock path/archivepath in this module, alongside recent ROM list
// update them at the same time?
//
// 1. verify BIOS/firm/etc
// 2. pick ROM
// 3. set recent ROM, last folder, etc
// 4. reset system (if need be)
// 5. load ROM/SRAM into core
// 6. boot
if (!verifySetup())
{
emuThread->emuUnpause();
return;
}
QStringList file = pickROM(false);
if (file.isEmpty())
{
emuThread->emuUnpause();
return;
}
// TODO: add to recent ROM list
if (!ROMLoader::LoadROM(file, true))
{
// TODO: better error reporting?
QMessageBox::critical(this, "melonDS", "Failed to load the ROM.");
emuThread->emuUnpause();
return;
}
printf("PROEUPRAON\n");
NDS::Start();printf("PROOT\n");
emuThread->emuRun();printf("ASSFAZIL\n");
} }
void MainWindow::onOpenFileArchive() void MainWindow::onOpenFileArchive()
@ -2090,7 +2180,7 @@ void MainWindow::onOpenFileArchive()
}*/ }*/
} }
QString MainWindow::pickAndExtractFileFromArchive(QString archiveFileName, QByteArray *romBuffer) /*QString MainWindow::pickAndExtractFileFromArchive(QString archiveFileName, QByteArray *romBuffer)
{ {
printf("Finding list of ROMs...\n"); printf("Finding list of ROMs...\n");
QVector<QString> archiveROMList = Archive::ListArchive(archiveFileName.toUtf8().constData()); QVector<QString> archiveROMList = Archive::ListArchive(archiveFileName.toUtf8().constData());
@ -2142,7 +2232,7 @@ QString MainWindow::pickAndExtractFileFromArchive(QString archiveFileName, QByte
} }
return romFileName; return romFileName;
} }*/
void MainWindow::onClearRecentFiles() void MainWindow::onClearRecentFiles()
{ {
@ -2201,7 +2291,7 @@ void MainWindow::updateRecentFilesMenu()
void MainWindow::onClickRecentFile() void MainWindow::onClickRecentFile()
{ {
QAction *act = (QAction *)sender(); /*QAction *act = (QAction *)sender();
QString fileName = act->data().toString(); QString fileName = act->data().toString();
if (fileName.endsWith(".gba", Qt::CaseInsensitive) || if (fileName.endsWith(".gba", Qt::CaseInsensitive) ||
@ -2223,7 +2313,7 @@ void MainWindow::onClickRecentFile()
emuThread->emuPause(); emuThread->emuPause();
loadROM(&romBuffer, archiveFileName, romFileName); loadROM(&romBuffer, archiveFileName, romFileName);
} }
} }*/
} }
void MainWindow::onBootFirmware() void MainWindow::onBootFirmware()
@ -2868,7 +2958,8 @@ bool MelonApplication::event(QEvent *event)
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent*>(event); QFileOpenEvent *openEvent = static_cast<QFileOpenEvent*>(event);
emuThread->emuPause(); emuThread->emuPause();
mainWindow->loadROM(openEvent->file()); //mainWindow->loadROM(openEvent->file());
printf("ASS EVENT???\n");
} }
return QApplication::event(event); return QApplication::event(event);

View File

@ -292,13 +292,17 @@ private slots:
void onFullscreenToggled(); void onFullscreenToggled();
private: private:
QStringList currentROM;
QStringList currentGBAROM;
QList<QString> recentFileList; QList<QString> recentFileList;
QMenu *recentMenu; QMenu *recentMenu;
void updateRecentFilesMenu(); void updateRecentFilesMenu();
QString pickAndExtractFileFromArchive(QString archiveFileName, QByteArray *romBuffer); //QString pickAndExtractFileFromArchive(QString archiveFileName, QByteArray *romBuffer);
void pickAndLoadROM(bool gba); bool verifySetup();
QString pickFileFromArchive(QString archiveFileName);
QStringList pickROM(bool gba);
void createScreenPanel(); void createScreenPanel();