From d6efb03248e3c7751b0c7e5d3b6398ea671325b0 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 20:59:11 +0200 Subject: HARK HARK HARK --- src/frontend/Util_ROM.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/frontend/Util_ROM.cpp (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp new file mode 100644 index 0000000..b3077f7 --- /dev/null +++ b/src/frontend/Util_ROM.cpp @@ -0,0 +1,17 @@ +/* + Copyright 2016-2020 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/. +*/ -- cgit v1.2.3 From 931da1c66fb50138109f8bf4cb157db8f1e79c64 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 22:02:45 +0200 Subject: add a bunch of code --- src/CMakeLists.txt | 2 + src/Config.h | 2 + src/frontend/FrontendUtil.h | 38 ++++++- src/frontend/Util_ROM.cpp | 236 +++++++++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.cpp | 19 ++-- 5 files changed, 284 insertions(+), 13 deletions(-) (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64d922c..dca0ca9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,8 @@ add_library(core STATIC Savestate.cpp SPI.cpp SPU.cpp + types.h + version.h Wifi.cpp WifiAP.cpp ) diff --git a/src/Config.h b/src/Config.h index 84fd57b..0aeab85 100644 --- a/src/Config.h +++ b/src/Config.h @@ -19,6 +19,8 @@ #ifndef CONFIG_H #define CONFIG_H +#include + #include "types.h" namespace Config diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 6a199b7..7e171ce 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -21,10 +21,44 @@ #include "types.h" -namespace FrontendUtil +namespace Frontend { -// +enum +{ + ROMSlot_NDS = 0, + ROMSlot_GBA, + + ROMSlot_MAX +}; + +extern char ROMPath [ROMSlot_MAX][1024]; +extern char SRAMPath[ROMSlot_MAX][1024]; +extern bool SavestateLoaded; + + +// initialize the ROM handling utility +void Init_ROM(); + +// load a ROM file to the specified cart slot +// note: loading a ROM to the NDS slot resets emulation +bool LoadROM(char* file, int slot); + +// get the filename associated with the given savestate slot +void GetSavestateName(int slot, char* filename, int len); + +// 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(const char* filename); + +// save the current emulator state to the given file +bool SaveState(const char* filename); + +// undo the latest savestate load +void UndoStateLoad(); } diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index b3077f7..574148b 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -15,3 +15,239 @@ You should have received a copy of the GNU General Public License along with melonDS. If not, see http://www.gnu.org/licenses/. */ + +#include +#include + +#include "FrontendUtil.h" +#include "Config.h" +#include "qt_sdl/PlatformConfig.h" // FIXME!!! +#include "Platform.h" + +#include "NDS.h" +#include "GBACart.h" + + +namespace Frontend +{ + +char ROMPath [ROMSlot_MAX][1024]; +char SRAMPath [ROMSlot_MAX][1024]; +char PrevSRAMPath[ROMSlot_MAX][1024]; // for savestate 'undo load' + +bool SavestateLoaded; + + +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); +} + +void SetupSRAMPath(int slot) +{ + strncpy(SRAMPath[slot], ROMPath[slot], 1023); + SRAMPath[slot][1023] = '\0'; + strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); +} + +bool LoadROM(char* file, int slot) +{ + 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); + + if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], Config::DirectBoot)) + { + SavestateLoaded = false; + + // Reload the inserted GBA cartridge (if any) + if (ROMPath[ROMSlot_GBA][0] != '\0') NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]); + + strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety + return true; + } + else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot])) + { + SavestateLoaded = false; + + strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety + return true; + } + else + { + strncpy(ROMPath[slot], oldpath, 1024); + strncpy(SRAMPath[slot], oldsram, 1024); + return false; + } +} + + +// 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 + { + int l = strlen(ROMPath[ROMSlot_NDS]); + pos = l; + while (ROMPath[ROMSlot_NDS][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); + } + 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); + } + } + + /*char msg[64]; + if (slot > 0) sprintf(msg, "State saved to slot %d", slot); + else sprintf(msg, "State saved to file"); + OSD::AddMessage(0, msg);*/ + 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); + } + + //OSD::AddMessage(0, "State load undone"); +} + +} diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 4999d94..648cd99 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -49,11 +49,6 @@ char* EmuDirectory; bool RunningSomething; -char ROMPath[2][1024]; -char SRAMPath[2][1024]; -char PrevSRAMPath[2][1024]; // for savestate 'undo load' - -bool SavestateLoaded; MainWindow* mainWindow; EmuThread* emuThread; @@ -334,8 +329,8 @@ void EmuThread::emuPause(bool refresh) { int status = refresh ? 2:3; PrevEmuStatus = EmuRunning; - EmuRunning = status;printf("emuPause %d -> %d %d\n", PrevEmuStatus, EmuRunning, EmuStatus); - while (EmuStatus != status);printf("wait done\n"); + EmuRunning = status; + while (EmuStatus != status); } void EmuThread::emuUnpause() @@ -370,7 +365,7 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { - setWindowTitle("melonDS - assfucking Qt version"); + setWindowTitle("melonDS " MELONDS_VERSION); QMenuBar* menubar = new QMenuBar(); { @@ -569,6 +564,7 @@ int main(int argc, char** argv) emuThread->start(); emuThread->emuPause(true); + #if 0 if (argc > 1) { char* file = argv[1]; @@ -601,11 +597,12 @@ int main(int argc, char** argv) } } } + #endif int ret = melon.exec(); -printf("melon over\n"); - emuThread->emuStop();printf("STOP\n"); - emuThread->wait();printf("farked\n"); + + emuThread->emuStop(); + emuThread->wait(); Config::Save(); -- cgit v1.2.3 From 3c883a2152c699b432c951b3498a1adc3d4c21b1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 22:32:33 +0200 Subject: hey look, it runs shit now! --- src/frontend/FrontendUtil.h | 2 +- src/frontend/Util_ROM.cpp | 2 +- src/frontend/qt_sdl/main.cpp | 60 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 6 deletions(-) (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 7e171ce..91f3cdd 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -42,7 +42,7 @@ void Init_ROM(); // load a ROM file to the specified cart slot // note: loading a ROM to the NDS slot resets emulation -bool LoadROM(char* file, int slot); +bool LoadROM(const char* file, int slot); // get the filename associated with the given savestate slot void GetSavestateName(int slot, char* filename, int len); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 574148b..ffee69a 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -57,7 +57,7 @@ void SetupSRAMPath(int slot) strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); } -bool LoadROM(char* file, int slot) +bool LoadROM(const char* file, int slot) { char oldpath[1024]; char oldsram[1024]; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 648cd99..6b4c873 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -35,13 +35,15 @@ #include "types.h" #include "version.h" +#include "FrontendUtil.h" + #include "NDS.h" -#include "GBACart.h" #include "GPU.h" #include "SPU.h" #include "Wifi.h" #include "Platform.h" #include "Config.h" +#include "PlatformConfig.h" #include "Savestate.h" @@ -102,7 +104,7 @@ void EmuThread::run() char melontitle[100]; SDL_mutex* titlemutex = SDL_CreateMutex(); void* titledata[2] = {melontitle, titlemutex}; -printf("emu thread start: %d\n", EmuRunning); + while (EmuRunning != 0) { /*ProcessInput(); @@ -389,8 +391,56 @@ MainWindow::~MainWindow() void MainWindow::onOpenFile() { - QString filename = QFileDialog::getOpenFileName(this, "Open ROM", "", "DS ROMs (*.nds *.srl);;Any file (*.*)"); - printf("fark: %p %d %s\n", filename, filename.isEmpty(), filename.toStdString().c_str()); + emuThread->emuPause(true); + + QString filename = QFileDialog::getOpenFileName(this, + "Open ROM", + Config::LastROMFolder, + "DS ROMs (*.nds *.srl);;GBA ROMs (*.gba);;Any file (*.*)"); + if (filename.isEmpty()) + { + emuThread->emuUnpause(); + return; + } + + // this shit is stupid + char file[1024]; + strncpy(file, filename.toStdString().c_str(), 1023); file[1023] = '\0'; + + int pos = strlen(file)-1; + while (file[pos] != '/' && file[pos] != '\\' && pos > 0) pos--; + strncpy(Config::LastROMFolder, file, pos); + Config::LastROMFolder[pos] = '\0'; + char* ext = &file[strlen(file)-3]; + + int slot; bool res; + if (!strcasecmp(ext, "gba")) + { + slot = 1; + res = Frontend::LoadROM(file, Frontend::ROMSlot_GBA); + } + else + { + slot = 0; + res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS); + } + + if (!res) + { + QMessageBox::critical(this, + "melonDS", + "Failed to load the ROM.\n\nMake sure the file is accessible and isn't used by another application."); + emuThread->emuUnpause(); + } + else if (slot == 1) + { + // checkme + emuThread->emuUnpause(); + } + else + { + emuThread->emuRun(); + } } @@ -557,6 +607,8 @@ int main(int argc, char** argv) } #endif + RunningSomething = false; + mainWindow = new MainWindow(); mainWindow->show(); -- cgit v1.2.3 From 63efc2e02aa51c44c9cb5abc621624aa1d7bf1e5 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 28 Apr 2020 22:45:11 +0200 Subject: add menu items for running the firmware and for quitting. --- src/frontend/FrontendUtil.h | 3 +++ src/frontend/Util_ROM.cpp | 16 ++++++++++++++++ src/frontend/qt_sdl/main.cpp | 44 +++++++++++++++++++++++++++++++++++++++++--- src/frontend/qt_sdl/main.h | 9 +++++++++ 4 files changed, 69 insertions(+), 3 deletions(-) (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 91f3cdd..eb4cb38 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -40,6 +40,9 @@ extern bool SavestateLoaded; // initialize the ROM handling utility void Init_ROM(); +// load the BIOS/firmware and boot from it +bool LoadBIOS(); + // load a ROM file to the specified cart slot // note: loading a ROM to the NDS slot resets emulation bool LoadROM(const char* file, int slot); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index ffee69a..cf40a78 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -57,6 +57,22 @@ void SetupSRAMPath(int slot) strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); } +bool LoadBIOS() +{ + // 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::LoadBIOS(); + + // TODO: error reporting? + return true; +} + bool LoadROM(const char* file, int slot) { char oldpath[1024]; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index e9b9122..cadcec9 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -394,10 +394,17 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) QMenuBar* menubar = new QMenuBar(); { QMenu* menu = menubar->addMenu("File"); - QAction* act; - act = menu->addAction("Open file..."); - connect(act, &QAction::triggered, this, &MainWindow::onOpenFile); + actOpenROM = menu->addAction("Open file..."); + connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile); + + actBootFirmware = menu->addAction("Launch DS menu"); + connect(actBootFirmware, &QAction::triggered, this, &MainWindow::onBootFirmware); + + menu->addSeparator(); + + actQuit = menu->addAction("Quit"); + connect(actQuit, &QAction::triggered, this, &MainWindow::onQuit); } setMenuBar(menubar); @@ -411,6 +418,12 @@ MainWindow::~MainWindow() } +void MainWindow::keyPressEvent(QKeyEvent* event) +{ + printf("key press. %d %d %08X %08X\n", event->key(), event->nativeScanCode(), event->modifiers(), event->nativeModifiers()); +} + + void MainWindow::onOpenFile() { emuThread->emuPause(true); @@ -465,6 +478,31 @@ void MainWindow::onOpenFile() } } +void MainWindow::onBootFirmware() +{ + // TODO: ensure the firmware is actually bootable!! + // TODO: check the whole GBA cart shito + + emuThread->emuPause(true); + + bool res = Frontend::LoadBIOS(); + if (!res) + { + // TODO! + + emuThread->emuUnpause(); + } + else + { + emuThread->emuRun(); + } +} + +void MainWindow::onQuit() +{ + QApplication::quit(); +} + void MainWindow::onTitleUpdate(QString title) { diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index a1093fe..9ccbddd 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -75,13 +75,22 @@ public: explicit MainWindow(QWidget* parent = nullptr); ~MainWindow(); +protected: + void keyPressEvent(QKeyEvent* event) override; + private slots: void onOpenFile(); + void onBootFirmware(); + void onQuit(); void onTitleUpdate(QString title); private: MainWindowPanel* panel; + + QAction* actOpenROM; + QAction* actBootFirmware; + QAction* actQuit; }; #endif // MAIN_H -- cgit v1.2.3 From 5fbad464c27fd5290c837d78a72378215ee8e77f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 29 Apr 2020 00:50:23 +0200 Subject: hook up savestate shito --- src/frontend/FrontendUtil.h | 2 +- src/frontend/Util_ROM.cpp | 2 + src/frontend/qt_sdl/main.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++- src/frontend/qt_sdl/main.h | 6 ++ 4 files changed, 149 insertions(+), 2 deletions(-) (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index eb4cb38..d9f5c58 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -47,7 +47,7 @@ bool LoadBIOS(); // note: loading a ROM to the NDS slot resets emulation bool LoadROM(const char* file, int slot); -// get the filename associated with the given savestate slot +// get the filename associated with the given savestate slot (1-8) void GetSavestateName(int slot, char* filename, int len); // determine whether the given savestate slot does contain a savestate diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index cf40a78..19c8eb9 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -69,6 +69,8 @@ bool LoadBIOS() NDS::LoadBIOS(); + SavestateLoaded = false; + // TODO: error reporting? return true; } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index af4fd4b..a6a1423 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -395,7 +395,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { QMenu* menu = menubar->addMenu("File"); - actOpenROM = menu->addAction("Open file..."); + actOpenROM = menu->addAction("Open ROM..."); connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile); //actBootFirmware = menu->addAction("Launch DS menu"); @@ -404,6 +404,49 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) menu->addSeparator(); + { + QMenu* submenu = menu->addMenu("Save state"); + + for (int i = 1; i < 9; i++) + { + char title[16]; + sprintf(title, "%d", i); + actSaveState[i] = submenu->addAction(title); + actSaveState[i]->setShortcut(QKeySequence(Qt::ShiftModifier | (Qt::Key_F1+i-1))); + actSaveState[i]->setData(QVariant(i)); + connect(actSaveState[i], &QAction::triggered, this, &MainWindow::onSaveState); + } + + actSaveState[0] = submenu->addAction("File..."); + actSaveState[0]->setShortcut(QKeySequence(Qt::ShiftModifier | Qt::Key_F9)); + actSaveState[0]->setData(QVariant(0)); + connect(actSaveState[0], &QAction::triggered, this, &MainWindow::onSaveState); + } + { + QMenu* submenu = menu->addMenu("Load state"); + + for (int i = 1; i < 9; i++) + { + char title[16]; + sprintf(title, "%d", i); + actLoadState[i] = submenu->addAction(title); + actLoadState[i]->setShortcut(QKeySequence(Qt::Key_F1+i-1)); + actLoadState[i]->setData(QVariant(i)); + connect(actLoadState[i], &QAction::triggered, this, &MainWindow::onLoadState); + } + + actLoadState[0] = submenu->addAction("File..."); + actLoadState[0]->setShortcut(QKeySequence(Qt::Key_F9)); + actLoadState[0]->setData(QVariant(0)); + connect(actLoadState[0], &QAction::triggered, this, &MainWindow::onLoadState); + } + + actUndoStateLoad = menu->addAction("Undo state load"); + actUndoStateLoad->setShortcut(QKeySequence(Qt::Key_F12)); + connect(actUndoStateLoad, &QAction::triggered, this, &MainWindow::onUndoStateLoad); + + menu->addSeparator(); + actQuit = menu->addAction("Quit"); connect(actQuit, &QAction::triggered, this, &MainWindow::onQuit); } @@ -499,6 +542,102 @@ void MainWindow::onBootFirmware() } } +void MainWindow::onSaveState() +{ + int slot = ((QAction*)sender())->data().toInt(); + + emuThread->emuPause(true); + + char filename[1024]; + if (slot > 0) + { + Frontend::GetSavestateName(slot, filename, 1024); + } + else + { + // TODO: specific 'last directory' for savestate files? + QString qfilename = QFileDialog::getSaveFileName(this, + "Save state", + Config::LastROMFolder, + "melonDS savestates (*.mln);;Any file (*.*)"); + if (qfilename.isEmpty()) + { + emuThread->emuUnpause(); + return; + } + + strncpy(filename, qfilename.toStdString().c_str(), 1023); filename[1023] = '\0'; + } + + if (Frontend::SaveState(filename)) + { + // TODO: OSD message + } + else + { + // TODO: OSD error message? + } + + emuThread->emuUnpause(); +} + +void MainWindow::onLoadState() +{ + int slot = ((QAction*)sender())->data().toInt(); + + emuThread->emuPause(true); + + char filename[1024]; + if (slot > 0) + { + Frontend::GetSavestateName(slot, filename, 1024); + } + else + { + // TODO: specific 'last directory' for savestate files? + QString qfilename = QFileDialog::getOpenFileName(this, + "Load state", + Config::LastROMFolder, + "melonDS savestates (*.ml*);;Any file (*.*)"); + if (qfilename.isEmpty()) + { + emuThread->emuUnpause(); + return; + } + + strncpy(filename, qfilename.toStdString().c_str(), 1023); filename[1023] = '\0'; + } + + if (!Platform::FileExists(filename)) + { + /*char msg[64]; + if (slot > 0) sprintf(msg, "State slot %d is empty", slot); + else sprintf(msg, "State file does not exist"); + OSD::AddMessage(0xFFA0A0, msg);*/ + + emuThread->emuUnpause(); + return; + } + + if (Frontend::LoadState(filename)) + { + // TODO: OSD message + } + else + { + // TODO: OSD error message? + } + + emuThread->emuUnpause(); +} + +void MainWindow::onUndoStateLoad() +{ + emuThread->emuPause(true); + Frontend::UndoStateLoad(); + emuThread->emuUnpause(); +} + void MainWindow::onQuit() { QApplication::quit(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 9ccbddd..8694838 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -81,6 +81,9 @@ protected: private slots: void onOpenFile(); void onBootFirmware(); + void onSaveState(); + void onLoadState(); + void onUndoStateLoad(); void onQuit(); void onTitleUpdate(QString title); @@ -90,6 +93,9 @@ private: QAction* actOpenROM; QAction* actBootFirmware; + QAction* actSaveState[9]; + QAction* actLoadState[9]; + QAction* actUndoStateLoad; QAction* actQuit; }; -- cgit v1.2.3 From c5c9434ac9abaa0ae9c3125ee6e8bc4653846ebd Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 05:42:09 +0200 Subject: verify BIOS and firmware before booting games/firmware --- src/NDS.cpp | 2 +- src/frontend/FrontendUtil.h | 22 +++++++++- src/frontend/Util_ROM.cpp | 100 +++++++++++++++++++++++++++++++++++++++---- src/frontend/qt_sdl/main.cpp | 41 +++++++++++++++--- src/frontend/qt_sdl/main.h | 2 + 5 files changed, 149 insertions(+), 18 deletions(-) (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/NDS.cpp b/src/NDS.cpp index 1d425a8..745ed28 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -587,7 +587,7 @@ bool DoSavestate_Scheduler(Savestate* file) } if (funcid == -1) { - printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK STAPLEBUTTER.\n", i); + printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK ARISOTURA.\n", i); return false; } } diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 32f28d1..f4f6850 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -32,6 +32,24 @@ enum ROMSlot_MAX }; +enum +{ + Load_OK = 0, + + Load_BIOS9Missing, + Load_BIOS9Bad, + + Load_BIOS7Missing, + Load_BIOS7Bad, + + Load_FirmwareMissing, + Load_FirmwareBad, + Load_FirmwareNotBootable, + + // TODO: more precise errors for ROM loading + Load_ROMLoadError, +}; + extern char ROMPath [ROMSlot_MAX][1024]; extern char SRAMPath[ROMSlot_MAX][1024]; extern bool SavestateLoaded; @@ -41,11 +59,11 @@ extern bool SavestateLoaded; void Init_ROM(); // load the BIOS/firmware and boot from it -bool LoadBIOS(); +int LoadBIOS(); // load a ROM file to the specified cart slot // note: loading a ROM to the NDS slot resets emulation -bool LoadROM(const char* file, int slot); +int LoadROM(const char* file, int slot); // get the filename associated with the given savestate slot (1-8) void GetSavestateName(int slot, char* filename, int len); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 19c8eb9..3200de4 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -57,8 +57,77 @@ void SetupSRAMPath(int slot) strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); } -bool LoadBIOS() +int VerifyDSBIOS() { + FILE* f; + long len; + + 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 VerifyDSFirmware() +{ + FILE* f; + long len; + + f = Platform::OpenLocalFile(Config::FirmwarePath, "rb"); + if (!f) return Load_FirmwareMissing; + + 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 LoadBIOS() +{ + int res; + + res = VerifyDSBIOS(); + if (res != Load_OK) return res; + + 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? @@ -71,12 +140,26 @@ bool LoadBIOS() SavestateLoaded = false; - // TODO: error reporting? - return true; + return Load_OK; } -bool LoadROM(const char* file, int slot) +int LoadROM(const char* file, int slot) { + int res; + bool directboot = Config::DirectBoot != 0; + + res = VerifyDSBIOS(); + if (res != Load_OK) return res; + + 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); @@ -88,28 +171,29 @@ bool LoadROM(const char* file, int slot) SetupSRAMPath(0); SetupSRAMPath(1); - if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], Config::DirectBoot)) + if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], directboot)) { SavestateLoaded = false; // 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 true; + return Load_OK; } else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot])) { SavestateLoaded = false; strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety - return true; + return Load_OK; } else { strncpy(ROMPath[slot], oldpath, 1024); strncpy(SRAMPath[slot], oldsram, 1024); - return false; + return Load_ROMLoadError; } } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 8b97320..ec4b04b 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -570,6 +570,27 @@ void MainWindow::keyPressEvent(QKeyEvent* event) } +QString MainWindow::loadErrorStr(int error) +{ + switch (error) + { + case Frontend::Load_BIOS9Missing: return "DS ARM9 BIOS was not found or could not be accessed."; + 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."; + 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."; + 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_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."; + } +} + + void MainWindow::onOpenFile() { emuThread->emuPause(true); @@ -584,6 +605,11 @@ void MainWindow::onOpenFile() return; } + // TODO: validate the input file!! + // * check that it is a proper ROM + // * ensure the binary offsets are sane + // * etc + // this shit is stupid char file[1024]; strncpy(file, filename.toStdString().c_str(), 1023); file[1023] = '\0'; @@ -594,7 +620,7 @@ void MainWindow::onOpenFile() Config::LastROMFolder[pos] = '\0'; char* ext = &file[strlen(file)-3]; - int slot; bool res; + int slot; int res; if (!strcasecmp(ext, "gba")) { slot = 1; @@ -606,11 +632,11 @@ void MainWindow::onOpenFile() res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS); } - if (!res) + if (res != Frontend::Load_OK) { QMessageBox::critical(this, "melonDS", - "Failed to load the ROM.\n\nMake sure the file is accessible and isn't used by another application."); + loadErrorStr(res)); emuThread->emuUnpause(); } else if (slot == 1) @@ -631,11 +657,12 @@ void MainWindow::onBootFirmware() emuThread->emuPause(true); - bool res = Frontend::LoadBIOS(); - if (!res) + int res = Frontend::LoadBIOS(); + if (res != Frontend::Load_OK) { - // TODO! - + QMessageBox::critical(this, + "melonDS", + loadErrorStr(res)); emuThread->emuUnpause(); } else diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index bb5e903..ee0094f 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -110,6 +110,8 @@ private slots: void onOpenEmuSettings(); private: + QString loadErrorStr(int error); + MainWindowPanel* panel; QAction* actOpenROM; -- cgit v1.2.3 From 2ebb21ce3bcf1a445dce7b13f64e44d6098a3acd Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 22:22:22 +0200 Subject: hook up pause and reset, w/ relevant hotkeys --- src/frontend/FrontendUtil.h | 3 ++ src/frontend/Util_ROM.cpp | 47 +++++++++++++++++++++- src/frontend/qt_sdl/main.cpp | 93 +++++++++++++++++++++++--------------------- src/frontend/qt_sdl/main.h | 10 +++-- 4 files changed, 104 insertions(+), 49 deletions(-) (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index f4f6850..d838b63 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -65,6 +65,9 @@ int LoadBIOS(); // note: loading a ROM to the NDS slot resets emulation int LoadROM(const char* file, int slot); +// reset execution of the current ROM +int Reset(); + // get the filename associated with the given savestate slot (1-8) void GetSavestateName(int slot, char* filename, int len); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 3200de4..e13eb2c 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -50,6 +50,11 @@ void Init_ROM() memset(PrevSRAMPath[ROMSlot_GBA], 0, 1024); } +// 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); @@ -184,7 +189,7 @@ int LoadROM(const char* file, int slot) } else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot])) { - SavestateLoaded = false; + SavestateLoaded = false; // checkme?? strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety return Load_OK; @@ -197,6 +202,46 @@ int LoadROM(const char* file, int slot) } } +int Reset() +{ + int res; + bool directboot = Config::DirectBoot != 0; + + res = VerifyDSBIOS(); + if (res != Load_OK) return res; + + res = VerifyDSFirmware(); + if (res != Load_OK) + { + if (res == Load_FirmwareNotBootable) + directboot = true; + else + return res; + } + + SavestateLoaded = false; + + if (ROMPath[ROMSlot_NDS][0] == '\0') + { + NDS::LoadBIOS(); + } + else + { + SetupSRAMPath(0); + if (!NDS::LoadROM(ROMPath[ROMSlot_NDS], SRAMPath[ROMSlot_NDS], directboot)) + return Load_ROMLoadError; + } + + if (ROMPath[ROMSlot_GBA][0] != '\0') + { + SetupSRAMPath(1); + if (!NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA])) + return Load_ROMLoadError; + } + + return Load_OK; +} + // SAVESTATE TODO // * configurable paths. not everyone wants their ROM directory to be polluted, I guess. diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 35eac70..a73362d 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -113,6 +113,8 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString))); connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart())); connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop())); + connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger())); + connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger())); emit windowEmuStop(); } @@ -152,14 +154,10 @@ void EmuThread::run() { Input::Process(); - /*if (Input::HotkeyPressed(HK_FastForwardToggle)) - { - Config::LimitFPS = !Config::LimitFPS; - // TODO: reflect in UI! - }*/ + if (Input::HotkeyPressed(HK_FastForwardToggle)) emit windowLimitFPSChange(); - //if (Input::HotkeyPressed(HK_Pause)) uiQueueMain(TogglePause, NULL); - //if (Input::HotkeyPressed(HK_Reset)) uiQueueMain(Reset, NULL); + if (Input::HotkeyPressed(HK_Pause)) emit windowEmuPause(); + if (Input::HotkeyPressed(HK_Reset)) emit windowEmuReset(); if (GBACart::CartInserted && GBACart::HasSolarSensor) { @@ -318,18 +316,15 @@ void EmuThread::run() lastmeasuretick = lasttick; fpslimitcount = 0; - if (EmuRunning == 2) + /*if (Screen_UseGL) { - /*if (Screen_UseGL) - { - uiGLBegin(GLContext); - uiGLMakeContextCurrent(GLContext); - GLScreen_DrawScreen(); - uiGLEnd(GLContext); - } - uiAreaQueueRedrawAll(MainDrawArea);*/ - mainWindow->update(); + uiGLBegin(GLContext); + uiGLMakeContextCurrent(GLContext); + GLScreen_DrawScreen(); + uiGLEnd(GLContext); } + uiAreaQueueRedrawAll(MainDrawArea);*/ + mainWindow->update(); //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); @@ -338,7 +333,7 @@ void EmuThread::run() sprintf(melontitle, "melonDS " MELONDS_VERSION); changeWindowTitle(melontitle); - SDL_Delay(100); + SDL_Delay(75); } } @@ -375,12 +370,11 @@ void EmuThread::emuRun() if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); } -void EmuThread::emuPause(bool refresh) +void EmuThread::emuPause() { - int status = refresh ? 2:3; PrevEmuStatus = EmuRunning; - EmuRunning = status; - while (EmuStatus != status); + EmuRunning = 2; + while (EmuStatus != 2); //emit windowEmuPause(); if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); @@ -774,7 +768,7 @@ 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(true); + emuThread->emuPause(); QString filename = urls.at(0).toLocalFile(); QString ext = filename.right(3); @@ -836,7 +830,7 @@ QString MainWindow::loadErrorStr(int error) void MainWindow::onOpenFile() { - emuThread->emuPause(true); + emuThread->emuPause(); QString filename = QFileDialog::getOpenFileName(this, "Open ROM", @@ -897,7 +891,7 @@ void MainWindow::onBootFirmware() { // TODO: check the whole GBA cart shito - emuThread->emuPause(true); + emuThread->emuPause(); int res = Frontend::LoadBIOS(); if (res != Frontend::Load_OK) @@ -917,7 +911,7 @@ void MainWindow::onSaveState() { int slot = ((QAction*)sender())->data().toInt(); - emuThread->emuPause(true); + emuThread->emuPause(); char filename[1024]; if (slot > 0) @@ -958,7 +952,7 @@ void MainWindow::onLoadState() { int slot = ((QAction*)sender())->data().toInt(); - emuThread->emuPause(true); + emuThread->emuPause(); char filename[1024]; if (slot > 0) @@ -1006,7 +1000,7 @@ void MainWindow::onLoadState() void MainWindow::onUndoStateLoad() { - emuThread->emuPause(true); + emuThread->emuPause(); Frontend::UndoStateLoad(); emuThread->emuUnpause(); } @@ -1019,9 +1013,11 @@ void MainWindow::onQuit() void MainWindow::onPause(bool checked) { - if (emuThread->emuIsRunning()) + if (!RunningSomething) return; + + if (checked) { - emuThread->emuPause(true); + emuThread->emuPause(); } else { @@ -1031,7 +1027,26 @@ void MainWindow::onPause(bool checked) void MainWindow::onReset() { - // + if (!RunningSomething) return; + + emuThread->emuPause(); + + actUndoStateLoad->setEnabled(false); + + int res = Frontend::Reset(); + if (res != Frontend::Load_OK) + { + QMessageBox::critical(this, + "melonDS", + loadErrorStr(res)); + emuThread->emuUnpause(); + } + else + { + // OSD::AddMessage(0, "Reset"); + + emuThread->emuRun(); + } } void MainWindow::onStop() @@ -1047,7 +1062,7 @@ void MainWindow::onOpenEmuSettings() void MainWindow::onOpenInputConfig() { - emuThread->emuPause(true); + emuThread->emuPause(); InputConfigDialog* dlg = InputConfigDialog::openDlg(this); connect(dlg, &InputConfigDialog::finished, this, &MainWindow::onInputConfigFinished); @@ -1143,7 +1158,7 @@ void MainWindow::onEmuStart() } actSaveState[0]->setEnabled(true); actLoadState[0]->setEnabled(true); - actUndoStateLoad->setEnabled(true); + actUndoStateLoad->setEnabled(false); actPause->setEnabled(true); actPause->setChecked(false); @@ -1165,16 +1180,6 @@ void MainWindow::onEmuStop() actStop->setEnabled(false); } -void MainWindow::onEmuPause() -{ - // -} - -void MainWindow::onEmuUnpause() -{ - // -} - int main(int argc, char** argv) @@ -1281,7 +1286,7 @@ int main(int argc, char** argv) emuThread = new EmuThread(); emuThread->start(); - emuThread->emuPause(true); + emuThread->emuPause(); if (argc > 1) { diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index b478f4e..22f045f 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -38,7 +38,7 @@ public: // to be called from the UI thread void emuRun(); - void emuPause(bool refresh); + void emuPause(); void emuUnpause(); void emuStop(); @@ -49,7 +49,10 @@ signals: void windowEmuStart(); void windowEmuStop(); - void windowPauseToggle(); + void windowEmuPause(); + void windowEmuReset(); + + void windowLimitFPSChange(); private: volatile int EmuStatus; @@ -130,14 +133,13 @@ private slots: void onEmuStart(); void onEmuStop(); - void onEmuPause(); - void onEmuUnpause(); private: QString loadErrorStr(int error); MainWindowPanel* panel; +public: QAction* actOpenROM; QAction* actBootFirmware; QAction* actSaveState[9]; -- cgit v1.2.3 From a9b275bc253510d77b8b6fcd80e6d24b56bc8680 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 22:58:04 +0200 Subject: reimplement Stop --- src/SPU.cpp | 3 +++ src/frontend/FrontendUtil.h | 4 ++++ src/frontend/Util_ROM.cpp | 14 ++++++++++++++ src/frontend/qt_sdl/Platform.cpp | 4 ++-- src/frontend/qt_sdl/main.cpp | 37 +++++++++++++++++++++++++++++++------ 5 files changed, 54 insertions(+), 8 deletions(-) (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/SPU.cpp b/src/SPU.cpp index 710533e..1ebfd4c 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -116,6 +116,9 @@ void Reset() void Stop() { memset(OutputBuffer, 0, 2*OutputBufferSize*2); + + OutputReadOffset = 0; + OutputWriteOffset = 0; } void DoSavestate(Savestate* file) diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index d838b63..faa29de 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -65,6 +65,10 @@ int LoadBIOS(); // note: loading a ROM to the NDS slot resets emulation int LoadROM(const char* file, int slot); +// unload the ROM loaded in the specified cart slot +// simulating ejection of the cartridge +void UnloadROM(int slot); + // reset execution of the current ROM int Reset(); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index e13eb2c..ec3186a 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -202,6 +202,20 @@ int LoadROM(const char* file, int slot) } } +void UnloadROM(int slot) +{ + if (slot == ROMSlot_NDS) + { + // TODO! + } + else if (slot == ROMSlot_GBA) + { + GBACart::Eject(); + } + + ROMPath[slot][0] = '\0'; +} + int Reset() { int res; diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 6a5b466..dd838d7 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -55,7 +55,7 @@ char* EmuDirectory; -void Stop(bool internal); +void emuStop(); namespace Platform @@ -133,7 +133,7 @@ void DeInit() void StopEmu() { - //Stop(true); + emuStop(); } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index a73362d..67272af 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -115,8 +115,6 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop())); connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger())); connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger())); - - emit windowEmuStop(); } void EmuThread::run() @@ -140,7 +138,6 @@ void EmuThread::run() } Input::Init(); - /*Touching = false;*/ u32 nframes = 0; u32 starttick = SDL_GetTicks(); @@ -376,7 +373,6 @@ void EmuThread::emuPause() EmuRunning = 2; while (EmuStatus != 2); - //emit windowEmuPause(); if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); } @@ -384,7 +380,6 @@ void EmuThread::emuUnpause() { EmuRunning = PrevEmuStatus; - //emit windowEmuUnpause(); if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); } @@ -703,6 +698,18 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) panel->setMinimumSize(256, 384); + for (int i = 0; i < 9; i++) + { + actSaveState[i]->setEnabled(false); + actLoadState[i]->setEnabled(false); + } + actUndoStateLoad->setEnabled(false); + + actPause->setEnabled(false); + actReset->setEnabled(false); + actStop->setEnabled(false); + + actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM != 0); actScreenRotation[Config::ScreenRotation]->setChecked(true); @@ -1051,7 +1058,10 @@ void MainWindow::onReset() void MainWindow::onStop() { - // + if (!RunningSomething) return; + + emuThread->emuPause(); + NDS::Stop(); } @@ -1168,6 +1178,8 @@ void MainWindow::onEmuStart() void MainWindow::onEmuStop() { + emuThread->emuPause(); + for (int i = 0; i < 9; i++) { actSaveState[i]->setEnabled(false); @@ -1181,6 +1193,19 @@ void MainWindow::onEmuStop() } +void emuStop() +{ + RunningSomething = false; + + Frontend::UnloadROM(Frontend::ROMSlot_NDS); + Frontend::UnloadROM(Frontend::ROMSlot_GBA); + + emit emuThread->windowEmuStop(); + + //OSD::AddMessage(0xFFC040, "Shutdown"); +} + + int main(int argc, char** argv) { -- cgit v1.2.3 From a2004785a4d49f02f8257a38489eb57a29ce4e91 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 18:22:02 +0200 Subject: re-add all old OSD messages --- src/frontend/Util_ROM.cpp | 6 ------ src/frontend/qt_sdl/main.cpp | 41 +++++++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 22 deletions(-) (limited to 'src/frontend/Util_ROM.cpp') diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index ec3186a..3f64b9d 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -384,10 +384,6 @@ bool SaveState(const char* filename) } } - /*char msg[64]; - if (slot > 0) sprintf(msg, "State saved to slot %d", slot); - else sprintf(msg, "State saved to file"); - OSD::AddMessage(0, msg);*/ return true; } @@ -407,8 +403,6 @@ void UndoStateLoad() strncpy(SRAMPath[ROMSlot_NDS], PrevSRAMPath[ROMSlot_NDS], 1024); NDS::RelocateSave(SRAMPath[ROMSlot_NDS], false); } - - //OSD::AddMessage(0, "State load undone"); } } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 78f64f6..bea33b0 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -364,16 +364,16 @@ void EmuThread::run() if (Input::HotkeyPressed(HK_SolarSensorDecrease)) { if (GBACart_SolarSensor::LightLevel > 0) GBACart_SolarSensor::LightLevel--; - //char msg[64]; - //sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); - //OSD::AddMessage(0, msg); + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); } if (Input::HotkeyPressed(HK_SolarSensorIncrease)) { if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; - //char msg[64]; - //sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); - //OSD::AddMessage(0, msg); + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); } } @@ -411,7 +411,7 @@ void EmuThread::run() { bool lid = !NDS::IsLidClosed(); NDS::SetLidClosed(lid); - //OSD::AddMessage(0, lid ? "Lid closed" : "Lid opened"); + OSD::AddMessage(0, lid ? "Lid closed" : "Lid opened"); } // microphone input @@ -1493,13 +1493,16 @@ void MainWindow::onSaveState() if (Frontend::SaveState(filename)) { - // TODO: OSD message + char msg[64]; + if (slot > 0) sprintf(msg, "State saved to slot %d", slot); + else sprintf(msg, "State saved to file"); + OSD::AddMessage(0, msg); actLoadState[slot]->setEnabled(true); } else { - // TODO: OSD error message? + OSD::AddMessage(0xFFA0A0, "State save failed"); } emuThread->emuUnpause(); @@ -1534,10 +1537,10 @@ void MainWindow::onLoadState() if (!Platform::FileExists(filename)) { - /*char msg[64]; + char msg[64]; if (slot > 0) sprintf(msg, "State slot %d is empty", slot); else sprintf(msg, "State file does not exist"); - OSD::AddMessage(0xFFA0A0, msg);*/ + OSD::AddMessage(0xFFA0A0, msg); emuThread->emuUnpause(); return; @@ -1545,11 +1548,14 @@ void MainWindow::onLoadState() if (Frontend::LoadState(filename)) { - // TODO: OSD message + char msg[64]; + if (slot > 0) sprintf(msg, "State loaded from slot %d", slot); + else sprintf(msg, "State loaded from file"); + OSD::AddMessage(0, msg); } else { - // TODO: OSD error message? + OSD::AddMessage(0xFFA0A0, "State load failed"); } emuThread->emuUnpause(); @@ -1560,6 +1566,8 @@ void MainWindow::onUndoStateLoad() emuThread->emuPause(); Frontend::UndoStateLoad(); emuThread->emuUnpause(); + + OSD::AddMessage(0, "State load undone"); } void MainWindow::onQuit() @@ -1575,10 +1583,12 @@ void MainWindow::onPause(bool checked) if (checked) { emuThread->emuPause(); + OSD::AddMessage(0, "Paused"); } else { emuThread->emuUnpause(); + OSD::AddMessage(0, "Resumed"); } } @@ -1600,8 +1610,7 @@ void MainWindow::onReset() } else { - // OSD::AddMessage(0, "Reset"); - + OSD::AddMessage(0, "Reset"); emuThread->emuRun(); } } @@ -1835,7 +1844,7 @@ void emuStop() emit emuThread->windowEmuStop(); - //OSD::AddMessage(0xFFC040, "Shutdown"); + OSD::AddMessage(0xFFC040, "Shutdown"); } -- cgit v1.2.3