diff --git a/src/86box.c b/src/86box.c index 4eae7ab02..b1c969509 100644 --- a/src/86box.c +++ b/src/86box.c @@ -37,7 +37,6 @@ #ifdef __APPLE__ #include #include -#include "mac/macOSXGlue.h" #ifdef __aarch64__ #include #endif @@ -385,48 +384,6 @@ pc_log(const char *fmt, ...) #define pc_log(fmt, ...) #endif -void -add_rom_path(const char* path) -{ - static char cwd[1024]; - memset(cwd, 0x00, sizeof(cwd)); - rom_path_t* cur_rom_path = &rom_paths; - while (cur_rom_path->next != NULL) { - cur_rom_path = cur_rom_path->next; - } - if (!plat_path_abs((char*)path)) { - /* - * This looks like a relative path. - * - * Add it to the current working directory - * to convert it (back) to an absolute path. - */ - plat_getcwd(cwd, 1024); - plat_path_slash(cwd); - snprintf(cur_rom_path->rom_path, 1024, "%s%s%c", cwd, path, 0); - } - else { - /* - * The user-provided path seems like an - * absolute path, so just use that. - */ - strncpy(cur_rom_path->rom_path, path, 1024); - } - plat_path_slash(cur_rom_path->rom_path); - cur_rom_path->next = calloc(1, sizeof(rom_path_t)); -} - -// Copied over from Unix code, which in turn is lifted from musl. Needed for parsing XDG_DATA_DIRS. -static char *local_strsep(char **str, const char *sep) -{ - char *s = *str, *end; - if (!s) return NULL; - end = s + strcspn(s, sep); - if (*end) *end++ = 0; - else end = 0; - *str = end; - return s; -} /* * Perform initial startup of the PC. @@ -438,12 +395,12 @@ static char *local_strsep(char **str, const char *sep) int pc_init(int argc, char *argv[]) { - char path[2048], path2[2048]; + char *ppath = NULL, *rpath = NULL; char *cfg = NULL, *p; #if !defined(__APPLE__) && !defined(_WIN32) char *appimage; #endif - char temp[128]; + char temp[2048]; struct tm *info; time_t now; int c, vmrp = 0; @@ -456,6 +413,14 @@ pc_init(int argc, char *argv[]) p = plat_get_filename(exe_path); *p = '\0'; +#if !defined(_WIN32) && !defined(__APPLE__) + /* Grab the actual path if we are an AppImage. */ + appimage = getenv("APPIMAGE"); + if (appimage && (appimage[0] != '\0')) { + plat_get_dirname(exe_path, appimage); + } +#endif + /* * Get the current working directory. * @@ -467,9 +432,6 @@ pc_init(int argc, char *argv[]) plat_getcwd(usr_path, sizeof(usr_path) - 1); plat_getcwd(rom_path, sizeof(rom_path) - 1); - memset(path, 0x00, sizeof(path)); - memset(path2, 0x00, sizeof(path)); - for (c=1; cnext) { - pclog("# ROM path: %s\n", cur_rom_path->rom_path); - cur_rom_path = cur_rom_path->next; - } + for(rom_path_t *rom_path = &rom_paths; rom_path != NULL; rom_path = rom_path->next) { + pclog("# ROM path: %s\n", rom_path->path); } - else -#ifndef _WIN32 - pclog("# ROM path: %sroms/\n", exe_path); -#else - pclog("# ROM path: %sroms\\\n", exe_path); -#endif + pclog("# Configuration file: %s\n#\n\n", cfg_path); /* * We are about to read the configuration file, which MAY diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index 04fe94422..30c7c0561 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -42,13 +42,13 @@ typedef struct { typedef struct rom_path_t { - char rom_path[1024]; + char path[1024]; struct rom_path_t* next; } rom_path_t; extern rom_path_t rom_paths; -extern void add_rom_path(const char* path); +extern void rom_add_path(const char* path); extern uint8_t rom_read(uint32_t addr, void *p); extern uint16_t rom_readw(uint32_t addr, void *p); diff --git a/src/mac/CMakeLists.txt b/src/mac/CMakeLists.txt index ae3837f0e..2b71dd266 100644 --- a/src/mac/CMakeLists.txt +++ b/src/mac/CMakeLists.txt @@ -19,17 +19,16 @@ # Pick the bundle icon depending on the release channel if(RELEASE_BUILD) - set(APP_ICON_MACOSX icons/release/86Box.icns) + target_sources(86Box PRIVATE icons/release/86Box.icns) elseif(BETA_BUILD) - set(APP_ICON_MACOSX icons/beta/86Box.icns) + target_sources(86Box PRIVATE icons/beta/86Box.icns) elseif(ALPHA_BUILD) - set(APP_ICON_MACOSX icons/dev/86Box.icns) + target_sources(86Box PRIVATE icons/dev/86Box.icns) else() - set(APP_ICON_MACOSX icons/branch/86Box.icns) + target_sources(86Box PRIVATE icons/branch/86Box.icns) endif() target_link_libraries(86Box "-framework AppKit") -target_sources(86Box PRIVATE macOSXGlue.m ${APP_ICON_MACOSX}) # Make sure the icon is copied to the bundle set_source_files_properties(${APP_ICON_MACOSX} diff --git a/src/mem/rom.c b/src/mem/rom.c index 3dcbfe568..99d6bb582 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -57,47 +57,59 @@ rom_log(const char *fmt, ...) #define rom_log(fmt, ...) #endif +void +rom_add_path(const char* path) +{ + char cwd[1024] = { 0 }; + + rom_path_t* rom_path = &rom_paths; + + if (rom_paths.path[0] != '\0') + { + // Iterate to the end of the list. + while (rom_path->next != NULL) { + rom_path = rom_path->next; + } + + // Allocate the new entry. + rom_path = rom_path->next = calloc(1, sizeof(rom_path_t)); + } + + // Save the path, turning it into absolute if needed. + if (!plat_path_abs((char*) path)) { + plat_getcwd(cwd, 1024); + plat_path_slash(cwd); + snprintf(rom_path->path, 1024, "%s%s%c", cwd, path, 0); + } else { + strncpy(rom_path->path, path, 1024); + } + + // Ensure the path ends with a separator. + plat_path_slash(rom_path->path); +} + FILE * rom_fopen(char *fn, char *mode) { char temp[1024]; - char *fn2; + rom_path_t *rom_path = &rom_paths; + FILE *fp; - if ((strstr(fn, "roms/") == fn) || (strstr(fn, "roms\\") == fn)) { - /* Relative path */ - fn2 = (char *) malloc(strlen(fn) + 1); - memcpy(fn2, fn, strlen(fn) + 1); + if (strstr(fn, "roms/") == fn) { + /* Relative path */ + do { + plat_append_filename(temp, rom_path->path, fn + 5); - if (rom_paths.next) { - rom_path_t* cur_rom_path = &rom_paths; - memset(fn2, 0x00, strlen(fn) + 1); - memcpy(fn2, &(fn[5]), strlen(fn) - 4); - - while (cur_rom_path->next) { - memset(temp, 0, sizeof(temp)); - plat_append_filename(temp, cur_rom_path->rom_path, fn2); - if (rom_present(temp)) { - break; + if (fp = plat_fopen(temp, mode)) { + return fp; } - cur_rom_path = cur_rom_path->next; - } - } else { - /* Make sure to make it a backslash, just in case there's malformed - code calling us that assumes Windows. */ - if (fn2[4] == '\\') - fn2[4] = '/'; + } while(rom_path = rom_path->next); - plat_append_filename(temp, exe_path, fn2); - } - - free(fn2); - fn2 = NULL; - - return(plat_fopen(temp, mode)); + return fp; } else { - /* Absolute path */ - return(plat_fopen(fn, mode)); + /* Absolute path */ + return plat_fopen(fn, mode); } } @@ -105,54 +117,30 @@ rom_fopen(char *fn, char *mode) int rom_getfile(char *fn, char *s, int size) { - char temp[1024] = {'\0'}; - char *fn2; - int retval = 0; + char temp[1024]; + rom_path_t *rom_path = &rom_paths; - if ((strstr(fn, "roms/") == fn) || (strstr(fn, "roms\\") == fn)) { - /* Relative path */ - fn2 = (char *) malloc(strlen(fn) + 1); - memcpy(fn2, fn, strlen(fn) + 1); + if (strstr(fn, "roms/") == fn) { + /* Relative path */ + do { + plat_append_filename(temp, rom_path->path, fn + 5); - if (rom_paths.next) { - rom_path_t* cur_rom_path = &rom_paths; - memset(fn2, 0x00, strlen(fn) + 1); - memcpy(fn2, &(fn[5]), strlen(fn) - 4); - - while (cur_rom_path->next) { - memset(temp, 0, sizeof(temp)); - plat_append_filename(temp, cur_rom_path->rom_path, fn2); if (rom_present(temp)) { strncpy(s, temp, size); - retval = 1; - break; + return 1; } - cur_rom_path = cur_rom_path->next; - } - } else { - /* Make sure to make it a backslash, just in case there's malformed - code calling us that assumes Windows. */ - if (fn2[4] == '\\') - fn2[4] = '/'; + } while(rom_path = rom_path->next); - plat_append_filename(temp, exe_path, fn2); - if (rom_present(temp)) { - strncpy(s, temp, size); - retval = 1; - } - } - - free(fn2); - fn2 = NULL; + return 0; } else { /* Absolute path */ if (rom_present(fn)) { strncpy(s, fn, size); - retval = 1; + return 1; } + + return 0; } - - return(retval); } @@ -163,8 +151,8 @@ rom_present(char *fn) f = rom_fopen(fn, "rb"); if (f != NULL) { - (void)fclose(f); - return(1); + (void)fclose(f); + return(1); } return(0); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index e6e3256d3..af3d2b9e8 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -589,59 +590,18 @@ plat_chdir(char *path) void plat_init_rom_paths() { -#if defined __APPLE__ - QDir::root().mkpath(QStringLiteral("%1/Documents/86Box/roms/").arg(QDir::homePath())); - add_rom_path(QStringLiteral("%1/Documents/86Box/roms/").arg(QDir::homePath()).toUtf8().constData()); -#elif !defined _WIN32 - if (getenv("XDG_DATA_HOME")) { - char xdg_rom_path[1024 + 1] = { 0 }; - strncpy(xdg_rom_path, getenv("XDG_DATA_HOME"), 1024); - plat_path_slash(xdg_rom_path); - strncat(xdg_rom_path, "86Box/", 1024); + auto paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); - if (!plat_dir_check(xdg_rom_path)) - plat_dir_create(xdg_rom_path); - strcat(xdg_rom_path, "roms/"); +#ifdef _WIN32 + // HACK: The standard locations returned for GenericDataLocation include + // the EXE path and a `data` directory within it as the last two entries. - if (!plat_dir_check(xdg_rom_path)) - plat_dir_create(xdg_rom_path); - add_rom_path(xdg_rom_path); - } else { - char home_rom_path[1024] = { 0 }; - snprintf(home_rom_path, 1024, "%s/.local/share/86Box/", getenv("HOME") ? getenv("HOME") : QDir::homePath().toUtf8().constData()); - - if (!plat_dir_check(home_rom_path)) - plat_dir_create(home_rom_path); - strcat(home_rom_path, "roms/"); - - if (!plat_dir_check(home_rom_path)) - plat_dir_create(home_rom_path); - add_rom_path(home_rom_path); - } - if (getenv("XDG_DATA_DIRS")) { - char* xdg_rom_paths = strdup(getenv("XDG_DATA_DIRS")); - char* xdg_rom_paths_orig = xdg_rom_paths; - char* cur_xdg_rom_path = NULL; - if (xdg_rom_paths) { - while (xdg_rom_paths[strlen(xdg_rom_paths) - 1] == ':') { - xdg_rom_paths[strlen(xdg_rom_paths) - 1] = '\0'; - } - QStringList path_list = QString(xdg_rom_paths).split(":"); - for (auto& cur_path : path_list) { - if (cur_path.right(1) != '/') - cur_path.push_back('/'); - add_rom_path((cur_path + "86Box/roms").toUtf8().constData()); - } - } - free(xdg_rom_paths_orig); - } else { - add_rom_path("/usr/local/share/86Box/roms/"); - add_rom_path("/usr/share/86Box/roms/"); - } -#elif _WIN32 - auto appDataDir = QDir(qEnvironmentVariable("LOCALAPPDATA")); - appDataDir.mkdir("86Box"); - appDataDir.mkdir("86Box/roms"); - add_rom_path((appDataDir.path().replace("\\","/") + "/86Box/roms").toUtf8().constData()); + // Remove the entries as we don't need them. + paths.removeLast(); + paths.removeLast(); #endif + + for (auto& path : paths) { + rom_add_path(QDir(path).filePath("86Box/roms").toUtf8().constData()); + } } diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 1712288d2..6d1c01a34 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -28,3 +28,7 @@ target_link_libraries(86Box Threads::Threads) add_library(ui OBJECT unix_sdl.c unix_cdrom.c) target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) target_link_libraries(ui ${CMAKE_DL_LIBS}) + +if(APPLE) + target_sources(plat PRIVATE macOSXGlue.m) +endif() diff --git a/src/mac/macOSXGlue.h b/src/unix/macOSXGlue.h similarity index 100% rename from src/mac/macOSXGlue.h rename to src/unix/macOSXGlue.h diff --git a/src/mac/macOSXGlue.m b/src/unix/macOSXGlue.m similarity index 100% rename from src/mac/macOSXGlue.m rename to src/unix/macOSXGlue.m diff --git a/src/unix/unix.c b/src/unix/unix.c index 5f6429b89..36187d44a 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -36,6 +36,10 @@ #include <86box/ui.h> #include <86box/gdbstub.h> +#ifdef __APPLE__ +#include "macOSXGlue.h" +#endif + static int first_use = 1; static uint64_t StartingTime; static uint64_t Frequency; @@ -762,7 +766,7 @@ plat_init_rom_paths() if (!plat_dir_check(xdg_rom_path)) plat_dir_create(xdg_rom_path); - add_rom_path(xdg_rom_path); + rom_add_path(xdg_rom_path); } else { char home_rom_path[1024] = { 0 }; snprintf(home_rom_path, 1024, "%s/.local/share/86Box/", getenv("HOME") ? getenv("HOME") : getpwuid(getuid())->pw_dir); @@ -773,7 +777,7 @@ plat_init_rom_paths() if (!plat_dir_check(home_rom_path)) plat_dir_create(home_rom_path); - add_rom_path(home_rom_path); + rom_add_path(home_rom_path); } if (getenv("XDG_DATA_DIRS")) { char* xdg_rom_paths = strdup(getenv("XDG_DATA_DIRS")); @@ -788,21 +792,18 @@ plat_init_rom_paths() strcat(real_xdg_rom_path, cur_xdg_rom_path); plat_path_slash(real_xdg_rom_path); strcat(real_xdg_rom_path, "86Box/roms/"); - add_rom_path(real_xdg_rom_path); + rom_add_path(real_xdg_rom_path); } } free(xdg_rom_paths_orig); } else { - add_rom_path("/usr/local/share/86Box/roms/"); - add_rom_path("/usr/share/86Box/roms/"); + rom_add_path("/usr/local/share/86Box/roms/"); + rom_add_path("/usr/share/86Box/roms/"); } #else - char home_rom_path[1024] = { '\0' }; - snprintf(home_rom_path, 1024, "%s/Documents/86Box/", getenv("HOME") ? getenv("HOME") : getpwuid(getuid())->pw_dir); - plat_dir_create(home_rom_path); - strcat(home_rom_path, "roms/"); - plat_dir_create(home_rom_path); - add_rom_path(home_rom_path); + char default_rom_path[1024] = { '\0 '}; + getDefaultROMPath(default_rom_path); + rom_path_add(default_rom_path); #endif } diff --git a/src/win/win.c b/src/win/win.c index 06db20bad..b655b58cf 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -932,7 +932,7 @@ plat_init_rom_paths() CreateDirectoryW(appdata_dir, NULL); wcscat(appdata_dir, "\\"); c16stombs(appdata_dir_a, appdata_dir, 1024); - add_rom_path(appdata_dir_a); + rom_add_path(appdata_dir_a); } }