diff options
author | patata <patataofcourse@gmail.com> | 2022-10-28 12:27:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-28 12:27:55 +0200 |
commit | 561781b9542fb5667ed43a38ac28c6b90a318405 (patch) | |
tree | f3d90129e80f5021f8b260b071c586037dab124e /src | |
parent | 936011964ce69158367654cbcdbc30bb0d06376a (diff) |
CLI 2.0: Electric Boogaloo (#1546)
* CLI: begin QT reimplementation
* Add first batch of parameters
* ROM loading (no archives yet)
* --fullscreen
* --boot (non-functional???)
* fix --boot
* archives!
* Add disclaimer that a.zip|b.nds is kind of fucky
* remove shit7 debugging
* Apply requested changes
Diffstat (limited to 'src')
-rw-r--r-- | src/frontend/qt_sdl/CLI.cpp | 135 | ||||
-rw-r--r-- | src/frontend/qt_sdl/CLI.h | 41 | ||||
-rw-r--r-- | src/frontend/qt_sdl/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/frontend/qt_sdl/ROMManager.cpp | 17 | ||||
-rw-r--r-- | src/frontend/qt_sdl/main.cpp | 72 | ||||
-rw-r--r-- | src/frontend/qt_sdl/main.h | 2 |
6 files changed, 235 insertions, 35 deletions
diff --git a/src/frontend/qt_sdl/CLI.cpp b/src/frontend/qt_sdl/CLI.cpp new file mode 100644 index 0000000..5d8ebd1 --- /dev/null +++ b/src/frontend/qt_sdl/CLI.cpp @@ -0,0 +1,135 @@ +/* + Copyright 2021-2022 melonDS team + + 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/. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <QApplication> +#include <QCommandLineParser> +#include <QStringList> + +#include "CLI.h" + +namespace CLI +{ + +CommandLineOptions* ManageArgs(QApplication& melon) +{ + QCommandLineParser parser; + parser.addHelpOption(); + + parser.addPositionalArgument("nds", "Nintendo DS ROM (or an archive file which contains it) to load into Slot-1"); + parser.addPositionalArgument("gba", "GBA ROM (or an archive file which contains it) to load into Slot-2"); + + parser.addOption(QCommandLineOption({"b", "boot"}, "Whether to boot firmware on startup. Defaults to \"auto\" (boot if NDS rom given)", "auto/always/never", "auto")); + parser.addOption(QCommandLineOption({"f", "fullscreen"}, "Start melonDS in fullscreen mode")); + +#ifdef ARCHIVE_SUPPORT_ENABLED + parser.addOption(QCommandLineOption({"a", "archive-file"}, "Specify file to load inside an archive given (NDS)", "rom")); + parser.addOption(QCommandLineOption({"A", "archive-file-gba"}, "Specify file to load inside an archive given (GBA)", "rom")); +#endif + + parser.process(melon); + + CommandLineOptions* options = new CommandLineOptions; + + options->fullscreen = parser.isSet("fullscreen"); + + QStringList posargs = parser.positionalArguments(); + switch (posargs.size()) + { + default: + printf("Too many positional arguments; ignoring 3 onwards\n"); + case 2: + options->gbaRomPath = QStringList(posargs[1]); + case 1: + options->dsRomPath = QStringList(posargs[0]); + case 0: + break; + } + + QString bootMode = parser.value("boot"); + if (bootMode == "auto") + { + options->boot = posargs.size() > 0; + } + else if (bootMode == "always") + { + options->boot = true; + } + else if (bootMode == "never") + { + options->boot = false; + } + else + { + printf("ERROR: -b/--boot only accepts auto/always/never as arguments\n"); + exit(1); + } + +#ifdef ARCHIVE_SUPPORT_ENABLED + if (parser.isSet("archive-file")) + { + if (options->dsRomPath.isEmpty()) + { + options->errorsToDisplay += "Option -a/--archive-file given, but no archive specified!"; + } + else + { + options->dsRomPath += parser.value("archive-file"); + } + } + else if (!options->dsRomPath.isEmpty()) + { + //TODO-CLI: try to automatically find ROM + QStringList paths = options->dsRomPath[0].split("|"); + if (paths.size() >= 2) + { + printf("Warning: use the a.zip|b.nds format at your own risk!\n"); + options->dsRomPath = paths; + } + } + + if (parser.isSet("archive-file-gba")) + { + if (options->gbaRomPath.isEmpty()) + { + options->errorsToDisplay += "Option -A/--archive-file-gba given, but no archive specified!"; + } + else + { + options->gbaRomPath += parser.value("archive-file-gba"); + } + } + else if (!options->gbaRomPath.isEmpty()) + { + //TODO-CLI: try to automatically find ROM + QStringList paths = options->gbaRomPath[0].split("|"); + if (paths.size() >= 2) + { + printf("Warning: use the a.zip|b.gba format at your own risk!\n"); + options->gbaRomPath = paths; + } + } +#endif + + return options; +} + +}
\ No newline at end of file diff --git a/src/frontend/qt_sdl/CLI.h b/src/frontend/qt_sdl/CLI.h new file mode 100644 index 0000000..18520fa --- /dev/null +++ b/src/frontend/qt_sdl/CLI.h @@ -0,0 +1,41 @@ +/* + Copyright 2021-2022 melonDS team + + 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/. +*/ + +#ifndef CLI_H +#define CLI_H + +#include <QApplication> +#include <QStringList> + +namespace CLI { + +struct CommandLineOptions +{ + QStringList errorsToDisplay = {}; + + QStringList dsRomPath; + QStringList gbaRomPath; + bool fullscreen; + bool boot; +}; + +extern CommandLineOptions* ManageArgs(QApplication& melon); + +} + +#endif diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index bfa58bf..6b964f3 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -49,6 +49,9 @@ set(SOURCES_QT_SDL ../duckstation/gl/context.cpp ${CMAKE_SOURCE_DIR}/res/melon.qrc + + CLI.h + CLI.cpp ) if (APPLE) diff --git a/src/frontend/qt_sdl/ROMManager.cpp b/src/frontend/qt_sdl/ROMManager.cpp index 716a454..e5479b2 100644 --- a/src/frontend/qt_sdl/ROMManager.cpp +++ b/src/frontend/qt_sdl/ROMManager.cpp @@ -503,6 +503,7 @@ bool LoadROM(QStringList filepath, bool reset) if (len > 0x40000000) { fclose(f); + delete[] filedata; return false; } @@ -528,14 +529,14 @@ bool LoadROM(QStringList filepath, bool reset) { // 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; - } + s32 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)); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index bea8c6d..e8e30a7 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -36,6 +36,7 @@ #include <QKeyEvent> #include <QMimeData> #include <QVector> +#include <QCommandLineParser> #ifndef _WIN32 #include <QGuiApplication> #include <QSocketNotifier> @@ -94,6 +95,8 @@ #include "ArchiveUtil.h" #include "CameraManager.h" +#include "CLI.h" + // TODO: uniform variable spelling bool RunningSomething; @@ -2126,7 +2129,7 @@ bool MainWindow::verifySetup() return true; } -bool MainWindow::preloadROMs(QString filename, QString gbafilename) +bool MainWindow::preloadROMs(QStringList file, QStringList gbafile, bool boot) { if (!verifySetup()) { @@ -2134,9 +2137,8 @@ bool MainWindow::preloadROMs(QString filename, QString gbafilename) } bool gbaloaded = false; - if (!gbafilename.isEmpty()) + if (!gbafile.isEmpty()) { - QStringList gbafile = gbafilename.split('|'); if (!ROMManager::LoadGBAROM(gbafile)) { // TODO: better error reporting? @@ -2147,20 +2149,33 @@ bool MainWindow::preloadROMs(QString filename, QString gbafilename) gbaloaded = true; } - QStringList file = filename.split('|'); - if (!ROMManager::LoadROM(file, true)) + bool ndsloaded = false; + if (!file.isEmpty()) { - // TODO: better error reporting? - QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); - return false; + if (!ROMManager::LoadROM(file, true)) + { + // TODO: better error reporting? + QMessageBox::critical(this, "melonDS", "Failed to load the ROM."); + return false; + } + recentFileList.removeAll(file.join("|")); + recentFileList.prepend(file.join("|")); + updateRecentFilesMenu(); + ndsloaded = true; } - recentFileList.removeAll(filename); - recentFileList.prepend(filename); - updateRecentFilesMenu(); - - NDS::Start(); - emuThread->emuRun(); + if (boot) + { + if (ndsloaded) + { + NDS::Start(); + emuThread->emuRun(); + } + else + { + onBootFirmware(); + } + } updateCartInserted(false); @@ -2428,7 +2443,7 @@ void MainWindow::onBootFirmware() } if (!ROMManager::LoadBIOS()) - { +{ // TODO: better error reporting? QMessageBox::critical(this, "melonDS", "This firmware is not bootable."); emuThread->emuUnpause(); @@ -3115,8 +3130,7 @@ void MainWindow::onTitleUpdate(QString title) setWindowTitle(title); } -void MainWindow::onFullscreenToggled() -{ +void ToggleFullscreen(MainWindow* mainWindow) { if (!mainWindow->isFullScreen()) { mainWindow->showFullScreen(); @@ -3130,6 +3144,11 @@ void MainWindow::onFullscreenToggled() } } +void MainWindow::onFullscreenToggled() +{ + ToggleFullscreen(this); +} + void MainWindow::onEmuStart() { for (int i = 1; i < 9; i++) @@ -3217,7 +3236,7 @@ bool MelonApplication::event(QEvent *event) QFileOpenEvent *openEvent = static_cast<QFileOpenEvent*>(event); emuThread->emuPause(); - if (!mainWindow->preloadROMs(openEvent->file(), "")) + if (!mainWindow->preloadROMs(openEvent->file().split("|"), {}, true)) emuThread->emuUnpause(); } @@ -3233,10 +3252,16 @@ int main(int argc, char** argv) printf("melonDS " MELONDS_VERSION "\n"); printf(MELONDS_URL "\n"); + // easter egg - not worth checking other cases for something so dumb + if (argc != 0 && (!strcasecmp(argv[0], "derpDS") || !strcasecmp(argv[0], "./derpDS"))) + printf("did you just call me a derp???\n"); + Platform::Init(argc, argv); MelonApplication melon(argc, argv); + CLI::CommandLineOptions* options = CLI::ManageArgs(melon); + // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); @@ -3339,6 +3364,8 @@ int main(int argc, char** argv) Input::OpenJoystick(); mainWindow = new MainWindow(); + if (options->fullscreen) + ToggleFullscreen(mainWindow); emuThread = new EmuThread(); emuThread->start(); @@ -3348,14 +3375,7 @@ int main(int argc, char** argv) QObject::connect(&melon, &QApplication::applicationStateChanged, mainWindow, &MainWindow::onAppStateChanged); - if (argc > 1) - { - QString file = argv[1]; - QString gbafile = ""; - if (argc > 2) gbafile = argv[2]; - - mainWindow->preloadROMs(file, gbafile); - } + mainWindow->preloadROMs(options->dsRomPath, options->gbaRomPath, options->boot); int ret = melon.exec(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 2e2a9ab..9f9fc7c 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -238,7 +238,7 @@ public: bool hasOGL; GL::Context* getOGLContext(); - bool preloadROMs(QString filename, QString gbafilename); + bool preloadROMs(QStringList file, QStringList gbafile, bool boot); void onAppStateChanged(Qt::ApplicationState state); |