From 7af658f0897c6d6ad1f67b9d7a9bc60955c029a0 Mon Sep 17 00:00:00 2001 From: Nadia Holmquist Pedersen Date: Wed, 4 Dec 2019 22:46:33 +0100 Subject: Add a UNIX_PORTABLE build option, turning it off makes a build of melonDS suitable for systemwide installation. --- src/NDSCart.cpp | 2 +- src/Platform.h | 8 +++++- src/libui_sdl/CMakeLists.txt | 8 ++++++ src/libui_sdl/Platform.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++ src/libui_sdl/main.cpp | 32 +++++++++++++++++----- 5 files changed, 106 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 0ecd304..5654a7d 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -815,7 +815,7 @@ bool ReadROMParams(u32 gamecode, u32* params) // [gamecode] [ROM size] [save type] [reserved] // list must be sorted by gamecode - FILE* f = Platform::OpenLocalFile("romlist.bin", "rb"); + FILE* f = Platform::OpenDataFile("romlist.bin"); if (!f) return false; fseek(f, 0, SEEK_END); diff --git a/src/Platform.h b/src/Platform.h index ca6971e..dfe83d0 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -32,15 +32,21 @@ void StopEmu(); // can be optionally restricted to only opening a file that already exists. // * OpenLocalFile(): // opens files local to the emulator (melonDS.ini, BIOS, firmware, ...) -// checks, by order of priority: +// For Windows builds, or portable UNIX builds it checks, by order of priority: // * current working directory // * emulator directory (essentially where the melonDS executable is) if supported // * any platform-specific application data directories // in create mode, if the file doesn't exist, it will be created in the emulator // directory if supported, or in the current directory otherwise +// For regular UNIX builds, the user's configuration directory is always used. +// * OpenDataFile(): +// Opens a file that was installed alongside melonDS on UNIX systems in /usr/share, etc. +// Looks in the user's data directory first, then the system's. +// If on Windows or a portable UNIX build, this simply calls OpenLocalFile(). FILE* OpenFile(const char* path, const char* mode, bool mustexist=false); FILE* OpenLocalFile(const char* path, const char* mode); +FILE* OpenDataFile(const char* path); inline bool FileExists(const char* name) { diff --git a/src/libui_sdl/CMakeLists.txt b/src/libui_sdl/CMakeLists.txt index 64206bf..afd38e4 100644 --- a/src/libui_sdl/CMakeLists.txt +++ b/src/libui_sdl/CMakeLists.txt @@ -31,6 +31,11 @@ target_link_libraries(melonDS core ${SDL2_LIBRARIES} libui) if (UNIX) + option(UNIX_PORTABLE "Make a portable build that looks for its configuration in the current directory" ON) + if (UNIX_PORTABLE) + add_definitions(-DUNIX_PORTABLE) + endif() + find_package(PkgConfig REQUIRED) pkg_check_modules(GTK3 REQUIRED gtk+-3.0) pkg_check_modules(SDL2 REQUIRED sdl2) @@ -61,4 +66,7 @@ elseif (WIN32) target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi) endif () +install(FILES ../../melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) +install(FILES ../../icon/melon_256x256.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps) +install(FILES ../../romlist.bin DESTINATION ${CMAKE_INSTALL_PREFIX}/share/melonds) install(TARGETS melonDS RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/src/libui_sdl/Platform.cpp b/src/libui_sdl/Platform.cpp index 94b3791..5cbf344 100644 --- a/src/libui_sdl/Platform.cpp +++ b/src/libui_sdl/Platform.cpp @@ -135,6 +135,63 @@ FILE* OpenFile(const char* path, const char* mode, bool mustexist) return ret; } +#if !defined(UNIX_PORTABLE) && !defined(__WIN32__) + +FILE* OpenLocalFile(const char* path, const char* mode) +{ + std::string fullpath; + if (path[0] == '/') + { + // If it's an absolute path, just open that. + fullpath = std::string(path); + } + else + { + // Check user configuration directory + std::string confpath = std::string(g_get_user_config_dir()) + "/melonds/"; + g_mkdir_with_parents(confpath.c_str(), 0755); + fullpath = confpath + path; + } + + return OpenFile(fullpath.c_str(), mode, mode[0] != 'w'); +} + +FILE* OpenDataFile(const char* path) +{ + const char* melondir = "melonds"; + const char* const* sys_dirs = g_get_system_data_dirs(); + const char* user_dir = g_get_user_data_dir(); + + // First check the user's data directory + char* fullpath = g_build_path("/", user_dir, melondir, path, NULL); + if (access(fullpath, R_OK) == 0) + { + FILE* f = fopen(fullpath, "r"); + g_free(fullpath); + return f; + } + free(fullpath); + + // Then check the system data directories + for (size_t i = 0; sys_dirs[i] != NULL; i++) + { + const char* dir = sys_dirs[i]; + char* fullpath = g_build_path("/", dir, melondir, path, NULL); + + if (access(fullpath, R_OK) == 0) + { + FILE* f = fopen(fullpath, "r"); + g_free(fullpath); + return f; + } + free(fullpath); + } + + return NULL; +} + +#else + FILE* OpenLocalFile(const char* path, const char* mode) { bool relpath = false; @@ -257,6 +314,13 @@ FILE* OpenLocalFile(const char* path, const char* mode) return NULL; } +FILE* OpenDataFile(const char* path) +{ + return OpenLocalFile(path, "r"); +} + +#endif + void* Thread_Create(void (*func)()) { diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index d6aa460..40b7079 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -21,6 +21,10 @@ #include #include +#ifndef __WIN32__ +#include +#endif + #include #include "libui/ui.h" @@ -2589,6 +2593,7 @@ int main(int argc, char** argv) printf("melonDS " MELONDS_VERSION "\n"); printf(MELONDS_URL "\n"); +#if defined(__WIN32__) || defined(UNIX_PORTABLE) if (argc > 0 && strlen(argv[0]) > 0) { int len = strlen(argv[0]); @@ -2615,6 +2620,13 @@ int main(int argc, char** argv) EmuDirectory = new char[2]; strcpy(EmuDirectory, "."); } +#else + const char* confdir = g_get_user_config_dir(); + const char* confname = "/melonds"; + EmuDirectory = new char[strlen(confdir) + strlen(confname) + 1]; + strcat(EmuDirectory, confdir); + strcat(EmuDirectory, confname); +#endif // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); @@ -2650,15 +2662,23 @@ int main(int argc, char** argv) !Platform::LocalFileExists("bios9.bin") || !Platform::LocalFileExists("firmware.bin")) { - uiMsgBoxError( - NULL, - "BIOS/Firmware not found", +#if defined(__WIN32__) || defined(UNIX_PORTABLE) + const char* locationName = "the directory you run melonDS from"; +#else + char* locationName = EmuDirectory; +#endif + char msgboxtext[512]; + sprintf(msgboxtext, "One or more of the following required files don't exist or couldn't be accessed:\n\n" "bios7.bin -- ARM7 BIOS\n" "bios9.bin -- ARM9 BIOS\n" "firmware.bin -- firmware image\n\n" - "Dump the files from your DS and place them in the directory you run melonDS from.\n" - "Make sure that the files can be accessed."); + "Dump the files from your DS and place them in %s.\n" + "Make sure that the files can be accessed.", + locationName + ); + + uiMsgBoxError(NULL, "BIOS/Firmware not found", msgboxtext); uiUninit(); SDL_Quit(); @@ -2704,7 +2724,7 @@ int main(int argc, char** argv) } } { - FILE* f = Platform::OpenLocalFile("romlist.bin", "rb"); + FILE* f = Platform::OpenDataFile("romlist.bin"); if (f) { u32 data; -- cgit v1.2.3