From 18c7629451813dfa0185c3a8643ce2971007813f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 2 Jan 2022 15:09:09 +0100 Subject: [PATCH] * proper check for whether direct boot is required * proof-of-concept cart insert/eject. it works! --- src/NDS.cpp | 21 ++++++++ src/NDS.h | 2 + src/SPI.cpp | 1 + src/SPI.h | 1 + src/frontend/qt_sdl/ROMLoader.cpp | 40 ++++++++++---- src/frontend/qt_sdl/ROMLoader.h | 53 +------------------ src/frontend/qt_sdl/main.cpp | 88 +++++++++++++++++-------------- src/frontend/qt_sdl/main.h | 3 +- 8 files changed, 108 insertions(+), 101 deletions(-) diff --git a/src/NDS.cpp b/src/NDS.cpp index bad80f1c..ea538c3a 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -353,6 +353,27 @@ void InitTimings() // handled later: GBA slot, wifi } +bool NeedsDirectBoot() +{ + if (ConsoleType == 1) + { + // for now, DSi mode requires original BIOS/NAND + return false; + } + else + { + // internal BIOS does not support direct boot + if (!Platform::GetConfigBool(Platform::ExternalBIOSEnable)) + return true; + + // DSi/3DS firmwares aren't bootable + if (SPI_Firmware::GetFirmwareLength() == 0x20000) + return true; + + return false; + } +} + void SetupDirectBoot(std::string romname) { if (ConsoleType == 1) diff --git a/src/NDS.h b/src/NDS.h index a7299ecd..d3bee637 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -240,6 +240,8 @@ void LoadBIOS(); bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen); void EjectCart(); + +bool NeedsDirectBoot(); void SetupDirectBoot(std::string romname); bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen); diff --git a/src/SPI.cpp b/src/SPI.cpp index 80ef336c..1641a267 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -463,6 +463,7 @@ void SetupDirectBoot(bool dsi) } } +u32 GetFirmwareLength() { return FirmwareLength; } u8 GetConsoleType() { return Firmware[0x1D]; } u8 GetWifiVersion() { return Firmware[0x2F]; } u8 GetNWifiVersion() { return Firmware[0x1FD]; } // for DSi; will return 0xFF on a DS diff --git a/src/SPI.h b/src/SPI.h index d82485b8..d98d3c25 100644 --- a/src/SPI.h +++ b/src/SPI.h @@ -28,6 +28,7 @@ void SetupDirectBoot(bool dsi); u32 FixFirmwareLength(u32 originalLength); +u32 GetFirmwareLength(); u8 GetConsoleType(); u8 GetWifiVersion(); u8 GetNWifiVersion(); diff --git a/src/frontend/qt_sdl/ROMLoader.cpp b/src/frontend/qt_sdl/ROMLoader.cpp index 88e84efb..f063aeb9 100644 --- a/src/frontend/qt_sdl/ROMLoader.cpp +++ b/src/frontend/qt_sdl/ROMLoader.cpp @@ -255,6 +255,19 @@ QString VerifySetup() } +bool LoadBIOS() +{ + if (NDS::NeedsDirectBoot()) + return false; + + FullROMPath = ""; + BaseROMDir = ""; + BaseROMName = ""; + + NDS::Reset(); + return true; +} + bool LoadROM(QStringList filepath, bool reset) { if (filepath.empty()) return false; @@ -262,6 +275,7 @@ bool LoadROM(QStringList filepath, bool reset) u8* filedata; u32 filelen; + std::string fullpath; std::string basepath; std::string romname; @@ -295,6 +309,8 @@ bool LoadROM(QStringList filepath, bool reset) fclose(f); filelen = (u32)len; + fullpath = filename; + int pos = LastSep(filename); basepath = filename.substr(0, pos); romname = filename.substr(pos+1); @@ -304,9 +320,7 @@ bool LoadROM(QStringList filepath, bool reset) { // file inside archive - QString archivepath = filepath.at(0); - - u32 lenread = Archive::ExtractFileFromArchive(archivepath, filepath.at(1), &filedata, &filelen); + u32 lenread = Archive::ExtractFileFromArchive(filepath.at(0), filepath.at(1), &filedata, &filelen); if (lenread < 0) return false; if (!filedata) return false; if (lenread != filelen) @@ -315,21 +329,20 @@ bool LoadROM(QStringList filepath, bool reset) return false; } - std::string std_archivepath = archivepath.toStdString(); + 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); + + fullpath = std_archivepath + "//" + std_romname; } #endif else return false; - // - printf("BASE PATH IS %s\n", basepath.c_str()); - printf("ROM NAME IS %s\n", romname.c_str()); + FullROMPath = fullpath; BaseROMDir = basepath; - BaseROMName = romname.substr(0, romname.rfind('.')); if (reset) @@ -356,7 +369,7 @@ bool LoadROM(QStringList filepath, bool reset) bool res = NDS::LoadCart(filedata, filelen, savedata, savelen); if (res) { - if (Config::DirectBoot) + if (Config::DirectBoot || NDS::NeedsDirectBoot()) { NDS::SetupDirectBoot(romname); } @@ -367,6 +380,15 @@ bool LoadROM(QStringList filepath, bool reset) return res; } +void EjectCart() +{ + NDS::EjectCart(); + + FullROMPath = ""; + BaseROMDir = ""; + BaseROMName = ""; +} + diff --git a/src/frontend/qt_sdl/ROMLoader.h b/src/frontend/qt_sdl/ROMLoader.h index 284950b8..4265b09d 100644 --- a/src/frontend/qt_sdl/ROMLoader.h +++ b/src/frontend/qt_sdl/ROMLoader.h @@ -28,7 +28,9 @@ namespace ROMLoader { QString VerifySetup(); +bool LoadBIOS(); bool LoadROM(QStringList filepath, bool reset); +void EjectCart(); enum { @@ -65,58 +67,7 @@ enum Load_ROMLoadError, }; -extern std::string ROMPath [ROMSlot_MAX]; -extern std::string SRAMPath[ROMSlot_MAX]; -extern bool SavestateLoaded; -// Stores type of nds rom i.e. nds/srl/dsi. Should be updated everytime an NDS rom is loaded from an archive -extern std::string NDSROMExtension; - -// initialize the ROM handling utility -void Init_ROM(); - -// deinitialize the ROM handling utility -void DeInit_ROM(); - -// load the BIOS/firmware and boot from it -int LoadBIOS(); - -// load a ROM file to the specified cart slot -// note: loading a ROM to the NDS slot resets emulation -int LoadROM(const char* file, int slot); -int LoadROM(const u8 *romdata, u32 romlength, const char *archivefilename, const char *romfilename, const char *sramfilename, int slot); - -// unload the ROM loaded in the specified cart slot -// simulating ejection of the cartridge -void UnloadROM(int slot); - -void ROMIcon(u8 (&data)[512], u16 (&palette)[16], u32* iconRef); -void AnimatedROMIcon(u8 (&data)[8][512], u16 (&palette)[8][16], u16 (&sequence)[64], u32 (&animatedTexRef)[32 * 32 * 64], std::vector &animatedSequenceRef); - -// reset execution of the current ROM -int Reset(); - -// get the filename associated with the given savestate slot (1-8) -std::string GetSavestateName(int slot); - -// determine whether the given savestate slot does contain a savestate -bool SavestateExists(int slot); - -// load the given savestate file -// if successful, emulation will continue from the savestate's point -bool LoadState(std::string filename); - -// save the current emulator state to the given file -bool SaveState(std::string filename); - -// undo the latest savestate load -void UndoStateLoad(); - -// imports savedata from an external file. Returns the difference between the filesize and the SRAM size -int ImportSRAM(const char* filename); - -// enable or disable cheats -void EnableCheats(bool enable); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 0b68ffb7..1aec415f 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1312,8 +1312,10 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actCurrentCart->setEnabled(false); actInsertCart = menu->addAction("Insert cart..."); + connect(actInsertCart, &QAction::triggered, this, &MainWindow::onInsertCart); actEjectCart = menu->addAction("Eject cart"); + connect(actEjectCart, &QAction::triggered, this, &MainWindow::onEjectCart); menu->addSeparator(); @@ -2122,15 +2124,6 @@ void MainWindow::onOpenFile() { 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(); @@ -2153,31 +2146,9 @@ void MainWindow::onOpenFile() emuThread->emuUnpause(); return; } -printf("PROEUPRAON\n"); - NDS::Start();printf("PROOT\n"); - emuThread->emuRun();printf("ASSFAZIL\n"); -} -void MainWindow::onOpenFileArchive() -{ - /*emuThread->emuPause(); - - QString archiveFileName = QFileDialog::getOpenFileName(this, - "Open ROM Archive", - QString::fromStdString(Config::LastROMFolder), - "Archived ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *.tar.bz2);;Any file (*.*)"); - if (archiveFileName.isEmpty()) - { - emuThread->emuUnpause(); - return; - } - - QByteArray romBuffer; - QString romFileName = pickAndExtractFileFromArchive(archiveFileName, &romBuffer); - if(!romFileName.isEmpty()) - { - loadROM(&romBuffer, archiveFileName, romFileName); - }*/ + NDS::Start(); + emuThread->emuRun(); } /*QString MainWindow::pickAndExtractFileFromArchive(QString archiveFileName, QByteArray *romBuffer) @@ -2322,18 +2293,55 @@ void MainWindow::onBootFirmware() emuThread->emuPause(); - int res = Frontend::LoadBIOS(); - if (res != Frontend::Load_OK) + if (!verifySetup()) { - QMessageBox::critical(this, - "melonDS", - loadErrorStr(res)); emuThread->emuUnpause(); + return; } - else + + if (!ROMLoader::LoadBIOS()) { - emuThread->emuRun(); + // TODO: better error reporting? + QMessageBox::critical(this, "melonDS", "This firmware is not bootable."); + emuThread->emuUnpause(); + return; } + + NDS::Start(); + emuThread->emuRun(); +} + +void MainWindow::onInsertCart() +{ + emuThread->emuPause(); + + QStringList file = pickROM(false); + if (file.isEmpty()) + { + emuThread->emuUnpause(); + return; + } + + // TODO: add to recent ROM list?? + + if (!ROMLoader::LoadROM(file, false)) + { + // TODO: better error reporting? + QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); + emuThread->emuUnpause(); + return; + } + + emuThread->emuUnpause(); +} + +void MainWindow::onEjectCart() +{ + emuThread->emuPause(); + + ROMLoader::EjectCart(); + + emuThread->emuUnpause(); } void MainWindow::onSaveState() diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 2438217d..0f0eee88 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -230,10 +230,11 @@ signals: private slots: void onOpenFile(); - void onOpenFileArchive(); void onClickRecentFile(); void onClearRecentFiles(); void onBootFirmware(); + void onInsertCart(); + void onEjectCart(); void onSaveState(); void onLoadState(); void onUndoStateLoad();