diff --git a/src/lime_qt/CMakeLists.txt b/src/lime_qt/CMakeLists.txt index 344c76bbe..7d61acc2a 100644 --- a/src/lime_qt/CMakeLists.txt +++ b/src/lime_qt/CMakeLists.txt @@ -294,9 +294,6 @@ create_target_directory_groups(lime-qt) target_link_libraries(lime-qt PRIVATE audio_core lime_common lime_core input_common network video_core) target_link_libraries(lime-qt PRIVATE Boost::boost nihstro-headers Qt6::Widgets Qt6::Multimedia Qt6::Concurrent) -if (MSVC) - target_link_libraries(lime-qt PRIVATE getopt) -endif() target_link_libraries(lime-qt PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) if (ENABLE_OPENGL) diff --git a/src/lime_qt/main.cpp b/src/lime_qt/main.cpp index ac96bebca..54689b489 100644 --- a/src/lime_qt/main.cpp +++ b/src/lime_qt/main.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include -#include #include #include #include @@ -17,14 +16,15 @@ #include #include #include -#undef _UNICODE -#include #ifdef __APPLE__ #include // for chdir #endif #ifdef _WIN32 #include #include +#else +#include +#include #endif #ifdef __unix__ #include @@ -158,6 +158,14 @@ static QString PrettyProductName() { return QSysInfo::prettyProductName(); } +void GMainWindow::ShowCommandOutput(std::string title, std::string message) { +#ifdef _WIN32 + QMessageBox::information(this, QString::fromStdString(title), QString::fromStdString(message)); +#else + std::cout << message << std::endl; +#endif +} + GMainWindow::GMainWindow(Core::System& system_) : ui{std::make_unique()}, system{system_}, movie{system.Movie()}, emu_thread{nullptr} { @@ -166,8 +174,6 @@ GMainWindow::GMainWindow(Core::System& system_) Debugger::ToggleConsole(); - CheckForMigration(); - this->config = std::make_unique(); #ifdef __unix__ @@ -219,6 +225,136 @@ GMainWindow::GMainWindow(Core::System& system_) SetDefaultUIGeometry(); RestoreUIState(); + QStringList args = QApplication::arguments(); + QString game_path; + for (int i = 1; i < args.size(); ++i) { + // Preserves drag/drop functionality + if (args.size() == 2 && !args[1].startsWith(QChar::fromLatin1('-'))) { + game_path = args[1]; + break; + } + + // Dump video + if (args[i] == QStringLiteral("-d")) { + if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { + continue; + } + if (!DynamicLibrary::FFmpeg::LoadFFmpeg()) { + ShowFFmpegErrorMessage(); + continue; + } + video_dumping_path = args[++i]; + video_dumping_on_start = true; + ui->action_Dump_Video->setChecked(true); + continue; + } + + // Launch game in fullscreen mode + if (args[i] == QStringLiteral("-f")) { + ui->action_Fullscreen->setChecked(true); + continue; + } + + // Enable GDB stub + if (args[i] == QStringLiteral("-g")) { + if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { + continue; + } + Settings::values.use_gdbstub = true; + Settings::values.gdbstub_port = strtoul(args[++i].toLatin1(), NULL, 0); + continue; + } + + if (args[i] == QStringLiteral("-h")) { + const std::string help_string = + std::string("Usage: ") + args[0].toStdString() + + " [options] \n" + "-d [path] Dump video recording of emulator playback to the given file path\n" + "-g [port] Enable gdb stub on the given port\n" + "-f Start in fullscreen mode\n" + "-h Display this help and exit\n" + "-i [path] Install a CIA file at the given path\n" + "-p [path] Play a TAS movie located at the given path\n" + "-r [path] Record a TAS movie to the given file path\n" + "-v Output version information and exit"; + + ShowCommandOutput("Help", help_string); + exit(0); + } + + if (args[i] == QStringLiteral("-i")) { + if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { + continue; + } + Service::AM::InstallStatus result = Service::AM::InstallCIA(args[++i].toStdString()); + if (result != Service::AM::InstallStatus::Success) { + std::string failure_reason; + + if (result == Service::AM::InstallStatus::ErrorFailedToOpenFile) + failure_reason = "Unable to open file."; + + if (result == Service::AM::InstallStatus::ErrorFileNotFound) + failure_reason = "File not found."; + + if (result == Service::AM::InstallStatus::ErrorAborted) + failure_reason = "Install was aborted."; + + if (result == Service::AM::InstallStatus::ErrorInvalid) + failure_reason = "CIA is invalid."; + + if (result == Service::AM::InstallStatus::ErrorEncrypted) + failure_reason = "CIA is encrypted."; + + std::string failure_string = "Failed to install CIA: " + failure_reason; + ShowCommandOutput("Failure", failure_string); + exit((int)result + + 2); // 2 is added here to avoid stepping on the toes of + // exit codes 1 and 2 which have pre-established conventional meanings + } + ShowCommandOutput("Success", "Installed CIA successfully."); + exit(0); + } + + if (args[i] == QStringLiteral("-p")) { + if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { + continue; + } + movie_playback_path = args[++i]; + movie_playback_on_start = true; + continue; + } + + if (args[i] == QStringLiteral("-r")) { + if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { + continue; + } + movie_record_path = args[++i]; + movie_record_on_start = true; + continue; + } + + if (args[i] == QStringLiteral("-v")) { + const std::string version_string = + std::string("Lime3DS ") + Common::g_scm_branch + " " + Common::g_scm_desc; + ShowCommandOutput("Version", version_string); + exit(0); + } + + // Launch game in windowed mode + if (args[i] == QStringLiteral("-w")) { + ui->action_Fullscreen->setChecked(false); + continue; + } + + // Launch game at path + if (i == args.size() - 1 && !args[i].startsWith(QChar::fromLatin1('-'))) { + game_path = args[i]; + continue; + } + } + + CheckForMigration(); + ConnectAppEvents(); ConnectMenuEvents(); ConnectWidgetEvents(); @@ -285,81 +421,6 @@ GMainWindow::GMainWindow(Core::System& system_) } #endif - QStringList args = QApplication::arguments(); - if (args.size() < 2) { - return; - } - - QString game_path; - for (int i = 1; i < args.size(); ++i) { - // Preserves drag/drop functionality - if (args.size() == 2 && !args[1].startsWith(QChar::fromLatin1('-'))) { - game_path = args[1]; - break; - } - - // Dump video - if (args[i] == QStringLiteral("-d")) { - if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { - continue; - } - if (!DynamicLibrary::FFmpeg::LoadFFmpeg()) { - ShowFFmpegErrorMessage(); - continue; - } - video_dumping_path = args[++i]; - video_dumping_on_start = true; - ui->action_Dump_Video->setChecked(true); - continue; - } - - // Launch game in fullscreen mode - if (args[i] == QStringLiteral("-f")) { - ui->action_Fullscreen->setChecked(true); - continue; - } - - // Enable GDB stub - if (args[i] == QStringLiteral("-g")) { - if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { - continue; - } - Settings::values.use_gdbstub = true; - Settings::values.gdbstub_port = strtoul(args[++i].toLatin1(), NULL, 0); - continue; - } - - if (args[i] == QStringLiteral("-p")) { - if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { - continue; - } - movie_playback_path = args[++i]; - movie_playback_on_start = true; - continue; - } - - if (args[i] == QStringLiteral("-r")) { - if (i >= args.size() - 1 || args[i + 1].startsWith(QChar::fromLatin1('-'))) { - continue; - } - movie_record_path = args[++i]; - movie_record_on_start = true; - continue; - } - - // Launch game in windowed mode - if (args[i] == QStringLiteral("-w")) { - ui->action_Fullscreen->setChecked(false); - continue; - } - - // Launch game at path - if (i == args.size() - 1 && !args[i].startsWith(QChar::fromLatin1('-'))) { - game_path = args[i]; - continue; - } - } - if (!game_path.isEmpty()) { BootGame(game_path); } @@ -3654,68 +3715,7 @@ static Qt::HighDpiScaleFactorRoundingPolicy GetHighDpiRoundingPolicy() { #endif } -static void PrintHelp(const char* argv0) { - std::cout << "Usage: " << argv0 - << " [options] \n" - "-d [path] Dump video recording of emulator playback to the given file path\n" - "-g [port] Enable gdb stub on the given port\n" - "-f Start in fullscreen mode\n" - "-h Display this help and exit\n" - "-i [path] Install a CIA file at the given path\n" - "-p [path] Play a TAS movie located at the given path\n" - "-r [path] Record a TAS movie to the given file path\n" - "-v Output version information and exit\n"; -} - -static void PrintVersion() { - std::cout << "Lime3DS " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl; -} - int main(int argc, char* argv[]) { - while (optind < argc) { - int arg = getopt(argc, argv, "d:fg:hi:p:r:v"); - if (arg != -1) { - switch (static_cast(arg)) { - case 'h': - PrintHelp(argv[0]); - return 0; - case 'i': { - Service::AM::InstallStatus result = Service::AM::InstallCIA(std::string(optarg)); - if (result != Service::AM::InstallStatus::Success) { - std::string failure_reason; - - if (result == Service::AM::InstallStatus::ErrorFailedToOpenFile) - failure_reason = "Unable to open file."; - - if (result == Service::AM::InstallStatus::ErrorFileNotFound) - failure_reason = "File not found."; - - if (result == Service::AM::InstallStatus::ErrorAborted) - failure_reason = "Install was aborted."; - - if (result == Service::AM::InstallStatus::ErrorInvalid) - failure_reason = "CIA is invalid."; - - if (result == Service::AM::InstallStatus::ErrorEncrypted) - failure_reason = "CIA is encrypted."; - - std::cout << "Failed to install CIA: " << failure_reason << std::endl; - return (int)result + - 2; // 2 is added here to avoid stepping on the toes of - // exit codes 1 and 2 which have pre-established conventional meanings - } - std::cout << "Installed CIA successfully." << std::endl; - return 0; - } - case 'v': - PrintVersion(); - return 0; - } - } else { - optind++; - } - } - Common::DetachedTasks detached_tasks; MicroProfileOnThreadCreate("Frontend"); SCOPE_EXIT({ MicroProfileShutdown(); }); diff --git a/src/lime_qt/main.h b/src/lime_qt/main.h index 0855f721f..f8aae8195 100644 --- a/src/lime_qt/main.h +++ b/src/lime_qt/main.h @@ -222,6 +222,7 @@ private: const std::string& keywords, const std::string& name, const bool& skip_tryexec); + void ShowCommandOutput(std::string title, std::string message); void ShowFFmpegErrorMessage(); private slots: