From 4b576d066e4b0513eacaba5c62018d1a850bbce1 Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Wed, 24 Jan 2024 01:27:25 -0800 Subject: [PATCH] Add support for using a portable directory without special build flags. (#1956) --- src/frontend/qt_sdl/CMakeLists.txt | 12 ++--- src/frontend/qt_sdl/Platform.cpp | 78 +++++++++++++++--------------- src/frontend/qt_sdl/main.cpp | 4 +- 3 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 8eeb44a4..1dec174b 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -166,11 +166,13 @@ target_link_libraries(melonDS PRIVATE ${QT_LINK_LIBS} ${CMAKE_DL_LIBS}) target_include_directories(melonDS PRIVATE "${Slirp_INCLUDE_DIRS}") target_link_libraries(melonDS PRIVATE "${Slirp_LINK_LIBRARIES}") -if (UNIX) - option(PORTABLE "Make a portable build that looks for its configuration in the current directory" OFF) -elseif (WIN32) +if (WIN32) option(PORTABLE "Make a portable build that looks for its configuration in the current directory" ON) + if (PORTABLE) + target_compile_definitions(melonDS PRIVATE WIN32_PORTABLE) + endif() + configure_file("${CMAKE_SOURCE_DIR}/res/melon.rc.in" "${CMAKE_BINARY_DIR}/res/melon.rc") target_sources(melonDS PUBLIC "${CMAKE_BINARY_DIR}/res/melon.rc") target_include_directories(melonDS PRIVATE "${CMAKE_BINARY_DIR}/res") @@ -189,10 +191,6 @@ elseif (WIN32) set_target_properties(melonDS PROPERTIES LINK_FLAGS_DEBUG "-mconsole") endif() -if (PORTABLE) - target_compile_definitions(melonDS PRIVATE PORTABLE) -endif() - if (APPLE) target_sources(melonDS PRIVATE sem_timedwait.cpp) diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index efd33400..222e512a 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -60,6 +61,42 @@ void emuStop(); namespace melonDS::Platform { +void PathInit(int argc, char** argv) +{ + // First, check for the portable directory next to the executable. + QString appdirpath = QCoreApplication::applicationDirPath(); + QString portablepath = appdirpath + QDir::separator() + "portable"; + +#if defined(__APPLE__) + // On Apple platforms we may need to navigate outside an app bundle. + // The executable directory would be "melonDS.app/Contents/MacOS", so we need to go a total of three steps up. + QDir bundledir(appdirpath); + if (bundledir.cd("..") && bundledir.cd("..") && bundledir.dirName().endsWith(".app") && bundledir.cd("..")) + { + portablepath = bundledir.absolutePath() + QDir::separator() + "portable"; + } +#endif + + QDir portabledir(portablepath); + if (portabledir.exists()) + { + EmuDirectory = portabledir.absolutePath().toStdString(); + } + else + { + // If no overrides are specified, use the default path. +#if defined(__WIN32__) && defined(WIN32_PORTABLE) + EmuDirectory = appdirpath.toStdString(); +#else + QString confdir; + QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + config.mkdir("melonDS"); + confdir = config.absolutePath() + QDir::separator() + "melonDS"; + EmuDirectory = confdir.toStdString(); +#endif + } +} + QSharedMemory* IPCBuffer = nullptr; int IPCInstanceID; @@ -133,38 +170,7 @@ void IPCDeInit() void Init(int argc, char** argv) { -#if defined(__WIN32__) || defined(PORTABLE) - if (argc > 0 && strlen(argv[0]) > 0) - { - int len = strlen(argv[0]); - while (len > 0) - { - if (argv[0][len] == '/') break; - if (argv[0][len] == '\\') break; - len--; - } - if (len > 0) - { - std::string emudir = argv[0]; - EmuDirectory = emudir.substr(0, len); - } - else - { - EmuDirectory = "."; - } - } - else - { - EmuDirectory = "."; - } -#else - QString confdir; - QDir config(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); - config.mkdir("melonDS"); - confdir = config.absolutePath() + "/melonDS/"; - EmuDirectory = confdir.toStdString(); -#endif - + PathInit(argc, argv); IPCInit(); } @@ -284,15 +290,7 @@ FileHandle* OpenLocalFile(const std::string& path, FileMode mode) } else { -#ifdef PORTABLE fullpath = QString::fromStdString(EmuDirectory) + QDir::separator() + qpath; -#else - // Check user configuration directory - QDir config(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); - config.mkdir("melonDS"); - fullpath = config.absolutePath() + "/melonDS/"; - fullpath.append(qpath); -#endif } return OpenFile(fullpath.toStdString(), mode); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 38c0ab16..3a5c1a11 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -299,10 +299,10 @@ int main(int argc, char** argv) 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); + Platform::Init(argc, argv); + CLI::CommandLineOptions* options = CLI::ManageArgs(melon); // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl