From f2ba4f8239e79294e770b1fb367d9743fe671fd1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 4 Jan 2022 02:00:36 +0100 Subject: [PATCH] some more shit working --- src/NDS.cpp | 2 + src/frontend/qt_sdl/ROMManager.cpp | 139 ++++++++++- src/frontend/qt_sdl/ROMManager.h | 2 +- src/frontend/qt_sdl/main.cpp | 364 +++++++++++------------------ src/frontend/qt_sdl/main.h | 10 +- 5 files changed, 275 insertions(+), 242 deletions(-) diff --git a/src/NDS.cpp b/src/NDS.cpp index 1bb17fee..3faed85a 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -943,6 +943,8 @@ bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) if (savedata && savelen) GBACart::LoadSave(savedata, savelen); + + return true; } void LoadGBAAddon(int type) diff --git a/src/frontend/qt_sdl/ROMManager.cpp b/src/frontend/qt_sdl/ROMManager.cpp index 6c58b74a..7bf15c81 100644 --- a/src/frontend/qt_sdl/ROMManager.cpp +++ b/src/frontend/qt_sdl/ROMManager.cpp @@ -38,12 +38,14 @@ namespace ROMManager { -std::string FullROMPath = ""; std::string BaseROMDir = ""; std::string BaseROMName = ""; std::string BaseAssetName = ""; int GBACartType = -1; +std::string BaseGBAROMDir = ""; +std::string BaseGBAROMName = ""; +std::string BaseGBAAssetName = ""; SaveManager* NDSSave = nullptr; SaveManager* GBASave = nullptr; @@ -63,10 +65,10 @@ int LastSep(std::string path) return -1; } -std::string GetAssetPath(std::string configpath, std::string ext) +std::string GetAssetPath(bool gba, std::string configpath, std::string ext) { if (configpath.empty()) - configpath = BaseROMDir; + configpath = gba ? BaseGBAROMDir : BaseROMDir; for (;;) { @@ -80,12 +82,10 @@ std::string GetAssetPath(std::string configpath, std::string ext) if (!configpath.empty()) configpath += "/"; - return configpath + BaseAssetName + ext; + return configpath + (gba ? BaseGBAAssetName : BaseAssetName) + ext; } - - QString VerifyDSBIOS() { FILE* f; @@ -285,7 +285,6 @@ bool LoadBIOS() if (NDSSave) delete NDSSave; NDSSave = nullptr; - FullROMPath = ""; BaseROMDir = ""; BaseROMName = ""; BaseAssetName = ""; @@ -294,6 +293,7 @@ bool LoadBIOS() return true; } + bool LoadROM(QStringList filepath, bool reset) { if (filepath.empty()) return false; @@ -365,7 +365,6 @@ bool LoadROM(QStringList filepath, bool reset) if (NDSSave) delete NDSSave; NDSSave = nullptr; - FullROMPath = filepath.join('|').toStdString(); BaseROMDir = basepath; BaseROMName = romname; BaseAssetName = romname.substr(0, romname.rfind('.')); @@ -379,7 +378,7 @@ bool LoadROM(QStringList filepath, bool reset) u32 savelen = 0; u8* savedata = nullptr; - std::string savname = GetAssetPath(Config::SaveFilePath, ".sav"); + std::string savname = GetAssetPath(false, Config::SaveFilePath, ".sav"); FILE* sav = Platform::OpenFile(savname, "rb", true); if (sav) { @@ -418,7 +417,6 @@ void EjectCart() NDS::EjectCart(); - FullROMPath = ""; BaseROMDir = ""; BaseROMName = ""; BaseAssetName = ""; @@ -439,16 +437,135 @@ QString CartLabel() } +bool LoadGBAROM(QStringList filepath) +{ + if (filepath.empty()) return false; + u8* filedata; + u32 filelen; + + std::string basepath; + std::string romname; + + int num = filepath.count(); + if (num == 1) + { + // regular file + + std::string filename = filepath.at(0).toStdString(); + FILE* f = Platform::OpenFile(filename, "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; + + int pos = LastSep(filename); + basepath = filename.substr(0, pos); + romname = filename.substr(pos+1); + } +#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; + } + + std::string std_archivepath = filepath.at(0).toStdString(); + basepath = std_archivepath.substr(0, LastSep(std_archivepath)); + + std::string std_romname = filepath.at(1).toStdString(); + romname = std_romname.substr(LastSep(std_romname)+1); + } +#endif + else + return false; + + if (GBASave) delete GBASave; + GBASave = nullptr; + + BaseGBAROMDir = basepath; + BaseGBAROMName = romname; + BaseGBAAssetName = romname.substr(0, romname.rfind('.')); + + u32 savelen = 0; + u8* savedata = nullptr; + + std::string savname = GetAssetPath(true, Config::SaveFilePath, ".sav"); + FILE* sav = Platform::OpenFile(savname, "rb", true); + if (sav) + { + fseek(sav, 0, SEEK_END); + savelen = (u32)ftell(sav); + + fseek(sav, 0, SEEK_SET); + savedata = new u8[savelen]; + fread(savedata, savelen, 1, sav); + fclose(sav); + } + + bool res = NDS::LoadGBACart(filedata, filelen, savedata, savelen); + + if (res) + { + GBASave = new SaveManager(savname); + } + + delete[] savedata; + delete[] filedata; + return res; +} void LoadGBAAddon(int type) { + if (GBASave) delete GBASave; + GBASave = nullptr; + NDS::LoadGBAAddon(type); GBACartType = type; + BaseGBAROMDir = ""; + BaseGBAROMName = ""; + BaseGBAAssetName = ""; +} + +void EjectGBACart() +{ + if (GBASave) delete GBASave; + GBASave = nullptr; + + NDS::EjectGBACart(); + + GBACartType = -1; + BaseGBAROMDir = ""; + BaseGBAROMName = ""; + BaseGBAAssetName = ""; } -// PLACEHOLDER QString GBACartLabel() { switch (GBACartType) diff --git a/src/frontend/qt_sdl/ROMManager.h b/src/frontend/qt_sdl/ROMManager.h index 638be3f5..7d730477 100644 --- a/src/frontend/qt_sdl/ROMManager.h +++ b/src/frontend/qt_sdl/ROMManager.h @@ -39,7 +39,7 @@ bool LoadROM(QStringList filepath, bool reset); void EjectCart(); QString CartLabel(); -bool LoadGBAROM(QStringList filepath, bool reset); +bool LoadGBAROM(QStringList filepath); void LoadGBAAddon(int type); void EjectGBACart(); QString GBACartLabel(); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 0b211b6b..1b6e7466 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1329,25 +1329,18 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actCurrentGBACart->setEnabled(false); actInsertGBACart = menu->addAction("Insert ROM cart..."); + connect(actInsertGBACart, &QAction::triggered, this, &MainWindow::onInsertGBACart); - //actInsertGBAAddon = menu->addAction("Insert add-on cart"); { QMenu* submenu = menu->addMenu("Insert add-on cart"); - /*actInsertGBAAddon[0] = submenu->addAction("Memory expansion"); - actInsertGBAAddon[1] = submenu->addAction("Vibrator Pak"); - actInsertGBAAddon[2] = submenu->addAction("Guitar Hero grip"); - actInsertGBAAddon[3] = submenu->addAction("Fartslapper"); - actInsertGBAAddon[4] = submenu->addAction("Fartslapper Mk. II"); - actInsertGBAAddon[5] = submenu->addAction("Ghostbusters ray"); - actInsertGBAAddon[6] = submenu->addAction("Fridge Pak"); - actInsertGBAAddon[7] = submenu->addAction("Fazil");*/ actInsertGBAAddon[0] = submenu->addAction("Memory expansion"); actInsertGBAAddon[0]->setData(QVariant(NDS::GBAAddon_RAMExpansion)); connect(actInsertGBAAddon[0], &QAction::triggered, this, &MainWindow::onInsertGBAAddon); } actEjectGBACart = menu->addAction("Eject cart"); + connect(actEjectGBACart, &QAction::triggered, this, &MainWindow::onEjectGBACart); menu->addSeparator(); @@ -1793,9 +1786,9 @@ void MainWindow::dragEnterEvent(QDragEnterEvent* event) QStringList acceptedExts{".nds", ".srl", ".dsi", ".gba", ".rar", ".zip", ".7z", ".tar", ".tar.gz", ".tar.xz", ".tar.bz2"}; - for(const QString &ext : acceptedExts) + for (const QString &ext : acceptedExts) { - if(filename.endsWith(ext, Qt::CaseInsensitive)) + if (filename.endsWith(ext, Qt::CaseInsensitive)) event->acceptProposedAction(); } } @@ -1807,67 +1800,69 @@ void MainWindow::dropEvent(QDropEvent* event) QList urls = event->mimeData()->urls(); if (urls.count() > 1) return; // not handling more than one file at once - /*emuThread->emuPause(); - QString filename = urls.at(0).toLocalFile(); - QString ext = filename.right(3).toLower(); + QStringList arcexts{".zip", ".7z", ".rar", ".tar", ".tar.gz", ".tar.xz", ".tar.bz2"}; - recentFileList.removeAll(filename); - recentFileList.prepend(filename); - updateRecentFilesMenu(); + emuThread->emuPause(); - char _filename[1024]; - strncpy(_filename, filename.toStdString().c_str(), 1023); _filename[1023] = '\0'; - - int slot; int res; - if (ext == "gba") + if (!verifySetup()) { - slot = 1; - res = Frontend::LoadROM(_filename, Frontend::ROMSlot_GBA); + emuThread->emuUnpause(); + return; } - else if(ext == "nds" || ext == "srl" || ext == "dsi") - { - slot = 0; - res = Frontend::LoadROM(_filename, Frontend::ROMSlot_NDS); - } - else - { - QByteArray romBuffer; - QString romFileName = pickAndExtractFileFromArchive(_filename, &romBuffer); - if(romFileName.isEmpty()) - { - res = Frontend::Load_ROMLoadError; - } - else - { - slot = (romFileName.endsWith(".gba", Qt::CaseInsensitive) ? 1 : 0); - QString sramFileName = QFileInfo(_filename).absolutePath() + QDir::separator() + QFileInfo(romFileName).completeBaseName() + ".sav"; - if (slot == 0) - Frontend::NDSROMExtension= QFileInfo(romFileName).suffix().toStdString(); + for (const QString &ext : arcexts) + { + if (filename.endsWith(ext, Qt::CaseInsensitive)) + { + QString arcfile = pickFileFromArchive(filename); + if (arcfile.isEmpty()) + { + emuThread->emuUnpause(); + return; + } - res = Frontend::LoadROM((const u8*)romBuffer.constData(), romBuffer.size(), - _filename, romFileName.toStdString().c_str(), sramFileName.toStdString().c_str(), - slot); + filename += "|" + arcfile; } } - if (res != Frontend::Load_OK) + QStringList file = filename.split('|'); + + if (filename.endsWith(".gba", Qt::CaseInsensitive)) { - QMessageBox::critical(this, - "melonDS", - loadErrorStr(res)); - emuThread->emuUnpause(); - } - else if (slot == 1) - { - // checkme + if (!ROMManager::LoadGBAROM(file)) + { + // TODO: better error reporting? + QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); + emuThread->emuUnpause(); + return; + } + emuThread->emuUnpause(); + + actCurrentGBACart->setText("GBA slot: " + ROMManager::GBACartLabel()); + actEjectGBACart->setEnabled(true); } else { + if (!ROMManager::LoadROM(file, true)) + { + // TODO: better error reporting? + QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); + emuThread->emuUnpause(); + return; + } + + recentFileList.removeAll(filename); + recentFileList.prepend(filename); + updateRecentFilesMenu(); + + NDS::Start(); emuThread->emuRun(); - }*/ + + actCurrentCart->setText("DS slot: " + ROMManager::CartLabel()); + actEjectCart->setEnabled(true); + } } void MainWindow::onAppStateChanged(Qt::ApplicationState state) @@ -1884,146 +1879,6 @@ void MainWindow::onAppStateChanged(Qt::ApplicationState state) } } -QString MainWindow::loadErrorStr(int error) -{ - /*switch (error) - { - case Frontend::Load_BIOS9Missing: - return "DS ARM9 BIOS was not found or could not be accessed. Check your emu settings."; - case Frontend::Load_BIOS9Bad: - return "DS ARM9 BIOS is not a valid BIOS dump."; - - case Frontend::Load_BIOS7Missing: - return "DS ARM7 BIOS was not found or could not be accessed. Check your emu settings."; - case Frontend::Load_BIOS7Bad: - return "DS ARM7 BIOS is not a valid BIOS dump."; - - case Frontend::Load_FirmwareMissing: - return "DS firmware was not found or could not be accessed. Check your emu settings."; - case Frontend::Load_FirmwareBad: - return "DS firmware is not a valid firmware dump."; - case Frontend::Load_FirmwareNotBootable: - return "DS firmware is not bootable."; - - case Frontend::Load_DSiBIOS9Missing: - return "DSi ARM9 BIOS was not found or could not be accessed. Check your emu settings."; - case Frontend::Load_DSiBIOS9Bad: - return "DSi ARM9 BIOS is not a valid BIOS dump."; - - case Frontend::Load_DSiBIOS7Missing: - return "DSi ARM7 BIOS was not found or could not be accessed. Check your emu settings."; - case Frontend::Load_DSiBIOS7Bad: - return "DSi ARM7 BIOS is not a valid BIOS dump."; - - case Frontend::Load_DSiNANDMissing: - return "DSi NAND was not found or could not be accessed. Check your emu settings."; - case Frontend::Load_DSiNANDBad: - return "DSi NAND is not a valid NAND dump."; - - case Frontend::Load_ROMLoadError: - return "Failed to load the ROM. Make sure the file is accessible and isn't used by another application."; - - default: return "Unknown error during launch; smack Arisotura."; - }*/ - return "REMOVE ME"; -} - -/*void MainWindow::loadROM(QByteArray *romData, QString archiveFileName, QString romFileName) -{ - recentFileList.removeAll(archiveFileName); - recentFileList.prepend(archiveFileName); - updateRecentFilesMenu(); - - // Strip entire archive name and get folder path - Config::LastROMFolder = QFileInfo(archiveFileName).absolutePath().toStdString(); - - QString sramFileName = QFileInfo(archiveFileName).absolutePath() + QDir::separator() + QFileInfo(romFileName).completeBaseName() + ".sav"; - - int slot; int res; - if (romFileName.endsWith("gba")) - { - slot = 1; - res = Frontend::LoadROM((const u8*)romData->constData(), romData->size(), - archiveFileName.toStdString().c_str(), - romFileName.toStdString().c_str(), sramFileName.toStdString().c_str(), - Frontend::ROMSlot_GBA); - } - else - { - Frontend::NDSROMExtension = QFileInfo(romFileName).suffix().toStdString(); - slot = 0; - res = Frontend::LoadROM((const u8*)romData->constData(), romData->size(), - archiveFileName.toStdString().c_str(), - romFileName.toStdString().c_str(), sramFileName.toStdString().c_str(), - Frontend::ROMSlot_NDS); - } - - if (res != Frontend::Load_OK) - { - QMessageBox::critical(this, - "melonDS", - loadErrorStr(res)); - emuThread->emuUnpause(); - } - else if (slot == 1) - { - // checkme - emuThread->emuUnpause(); - } - else - { - emuThread->emuRun(); - } -} - -void MainWindow::loadROM(QString filename) -{ - recentFileList.removeAll(filename); - recentFileList.prepend(filename); - updateRecentFilesMenu(); - - // TODO: validate the input file!! - // * check that it is a proper ROM - // * ensure the binary offsets are sane - // * etc - - std::string file = filename.toStdString(); - int pos = file.length() - 1; - while (file[pos] != '/' && file[pos] != '\\' && pos > 0) pos--; - Config::LastROMFolder = file.substr(0, pos); - - std::string ext = file.substr(file.length() - 3); - - int slot; int res; - if (ext == "gba") - { - slot = 1; - res = Frontend::LoadROM(file.c_str(), Frontend::ROMSlot_GBA); - } - else - { - slot = 0; - res = Frontend::LoadROM(file.c_str(), Frontend::ROMSlot_NDS); - } - - if (res != Frontend::Load_OK) - { - QMessageBox::critical(this, - "melonDS", - loadErrorStr(res)); - emuThread->emuUnpause(); - } - else if (slot == 1) - { - // checkme - emuThread->emuUnpause(); - } - else - { - emuThread->emuRun(); - } -}*/ - bool MainWindow::verifySetup() { QString res = ROMManager::VerifySetup(); @@ -2036,6 +1891,52 @@ bool MainWindow::verifySetup() return true; } +void MainWindow::preloadROMs(QString filename, QString gbafilename) +{ + if (!verifySetup()) + { + return; + } + + bool gbaloaded = false; + if (!gbafilename.isEmpty()) + { + QStringList gbafile = gbafilename.split('|'); + if (!ROMManager::LoadGBAROM(gbafile)) + { + // TODO: better error reporting? + QMessageBox::critical(this, "melonDS", "Failed to load the GBA ROM."); + return; + } + + gbaloaded = true; + } + + QStringList file = filename.split('|'); + if (!ROMManager::LoadROM(file, true)) + { + // TODO: better error reporting? + QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); + return; + } + + recentFileList.removeAll(filename); + recentFileList.prepend(filename); + updateRecentFilesMenu(); + + NDS::Start(); + emuThread->emuRun(); + + actCurrentCart->setText("DS slot: " + ROMManager::CartLabel()); + actEjectCart->setEnabled(true); + + if (gbaloaded) + { + actCurrentGBACart->setText("GBA slot: " + ROMManager::GBACartLabel()); + actEjectGBACart->setEnabled(true); + } +} + QString MainWindow::pickFileFromArchive(QString archiveFileName) { QVector archiveROMList = Archive::ListArchive(archiveFileName); @@ -2351,8 +2252,6 @@ void MainWindow::onInsertCart() return; } - // TODO: add to recent ROM list?? - if (!ROMManager::LoadROM(file, false)) { // TODO: better error reporting? @@ -2379,13 +2278,36 @@ void MainWindow::onEjectCart() actEjectCart->setEnabled(false); } +void MainWindow::onInsertGBACart() +{ + emuThread->emuPause(); + + QStringList file = pickROM(true); + if (file.isEmpty()) + { + emuThread->emuUnpause(); + return; + } + + if (!ROMManager::LoadGBAROM(file)) + { + // TODO: better error reporting? + QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); + emuThread->emuUnpause(); + return; + } + + emuThread->emuUnpause(); + + actCurrentGBACart->setText("GBA slot: " + ROMManager::GBACartLabel()); + actEjectGBACart->setEnabled(true); +} + void MainWindow::onInsertGBAAddon() { QAction* act = (QAction*)sender(); int type = act->data().toInt(); - printf("INSERT: %d\n", type); - emuThread->emuPause(); ROMManager::LoadGBAAddon(type); @@ -2396,6 +2318,18 @@ void MainWindow::onInsertGBAAddon() actEjectGBACart->setEnabled(true); } +void MainWindow::onEjectGBACart() +{ + emuThread->emuPause(); + + ROMManager::EjectGBACart(); + + emuThread->emuUnpause(); + + actCurrentGBACart->setText("GBA slot: " + ROMManager::GBACartLabel()); + actEjectGBACart->setEnabled(false); +} + void MainWindow::onSaveState() { int slot = ((QAction*)sender())->data().toInt(); @@ -2508,7 +2442,7 @@ void MainWindow::onImportSavefile() { if (!RunningSomething) return; - emuThread->emuPause(); + /*emuThread->emuPause(); QString path = QFileDialog::getOpenFileName(this, "Select savefile", QString::fromStdString(Config::LastROMFolder), @@ -2536,7 +2470,7 @@ void MainWindow::onImportSavefile() } } } - emuThread->emuUnpause(); + emuThread->emuUnpause();*/ } void MainWindow::onQuit() @@ -3136,29 +3070,11 @@ int main(int argc, char** argv) if (argc > 1) { - char* file = argv[1]; - char* ext = &file[strlen(file)-3]; + QString file = argv[1]; + QString gbafile = ""; + if (argc > 2) gbafile = argv[2]; - if (!strcasecmp(ext, "nds") || !strcasecmp(ext, "srl") || !strcasecmp(ext, "dsi")) - { - int res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS); - - if (res == Frontend::Load_OK) - { - if (argc > 2) - { - file = argv[2]; - ext = &file[strlen(file)-3]; - - if (!strcasecmp(ext, "gba")) - { - Frontend::LoadROM(file, Frontend::ROMSlot_GBA); - } - } - - emuThread->emuRun(); - } - } + mainWindow->preloadROMs(file, gbafile); } int ret = melon.exec(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 6c911599..fa21892d 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -210,8 +210,7 @@ public: bool hasOGL; QOpenGLContext* getOGLContext(); - void loadROM(QString filename); - void loadROM(QByteArray *romData, QString archiveFileName, QString romFileName); + void preloadROMs(QString filename, QString gbafilename); void onAppStateChanged(Qt::ApplicationState state); @@ -235,7 +234,9 @@ private slots: void onBootFirmware(); void onInsertCart(); void onEjectCart(); + void onInsertGBACart(); void onInsertGBAAddon(); + void onEjectGBACart(); void onSaveState(); void onLoadState(); void onUndoStateLoad(); @@ -300,8 +301,6 @@ private: QMenu *recentMenu; void updateRecentFilesMenu(); - //QString pickAndExtractFileFromArchive(QString archiveFileName, QByteArray *romBuffer); - bool verifySetup(); QString pickFileFromArchive(QString archiveFileName); QStringList pickROM(bool gba); @@ -321,14 +320,13 @@ public: ScreenPanelNative* panelNative; QAction* actOpenROM; - //QAction* actOpenROMArchive; QAction* actBootFirmware; QAction* actCurrentCart; QAction* actInsertCart; QAction* actEjectCart; QAction* actCurrentGBACart; QAction* actInsertGBACart; - QAction* actInsertGBAAddon[16]; + QAction* actInsertGBAAddon[1]; QAction* actEjectGBACart; QAction* actImportSavefile; QAction* actSaveState[9];