diff options
| author | Philip Dubé <159546+serprex@users.noreply.github.com> | 2026-09-28 00:46:39 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-28 00:46:39 +0000 |
| commit | b939163c3d45e4048ca98186aa244cf8ecd3bdac (patch) | |
| tree | 34d87a2addd4994cae8c70f15e9eb7e9ca619cfa | |
| parent | ca1e4c22505a7c2101ca816c31023daaf4e2638e (diff) | |
publish appimage unzipped, store to ~/.local/share/soh when SHIP_HOME unset (#7252)
| -rw-r--r-- | .github/workflows/generate-builds.yml | 5 | ||||
| -rw-r--r-- | README.md | 17 | ||||
| -rw-r--r-- | soh/soh/Extractor/Extract.cpp | 6 | ||||
| -rw-r--r-- | soh/soh/OTRGlobals.cpp | 38 |
4 files changed, 44 insertions, 22 deletions
diff --git a/.github/workflows/generate-builds.yml b/.github/workflows/generate-builds.yml index 40c63424b..2148ce3f5 100644 --- a/.github/workflows/generate-builds.yml +++ b/.github/workflows/generate-builds.yml @@ -165,7 +165,6 @@ jobs: cmake --build build-cmake --config Release -j4 (cd build-cmake && cpack -G External) - mv README.md readme.txt mv build-cmake/*.appimage soh.appimage env: CC: gcc-12 @@ -174,9 +173,7 @@ jobs: uses: actions/upload-artifact@v7 with: name: soh-linux - path: | - soh.appimage - readme.txt + path: soh.appimage - name: Save Cache deps folder if: ${{ github.ref_name == github.event.repository.default_branch }} uses: actions/cache/save@v5 @@ -21,27 +21,14 @@ You can verify you have dumped a supported copy of the game by using the compati * Launch `soh.exe` #### Linux -* Place your supported copy of the game in the same folder as the appimage. * Execute `soh.appimage`. You may have to `chmod +x` the appimage via terminal. +* When prompted, select your supported copy of the game. +* Saves, settings and `oot.o2r` are stored in `~/.local/share/soh/`. If the folder you launch from already has `shipofharkinian.json`, `oot.o2r` or `oot-mq.o2r`, that folder is used instead. Set `SHIP_HOME` to choose another folder. #### macOS * Run `soh.app`. When prompted, select your supported copy of the game. * You should see a notification saying `Processing OTR`, then, once the process is complete, you should get a notification saying `OTR Successfully Generated`, then the game should start. -#### Nintendo Switch -* Run one of the PC releases to generate an `oot.o2r` and/or `oot-mq.o2r` file. After launching the game on PC, you will be able to find these files in the same directory as `soh.exe` or `soh.appimage`. On macOS, these files can be found in `/Users/<username>/Library/Application Support/com.shipofharkinian.soh/` -* Copy the files to your sd card -``` -sdcard -└── switch - └── soh - ├── oot-mq.o2r - ├── oot.o2r - ├── soh.nro - └── soh.o2r -``` -* Launch via Atmosphere's `Game+R` launcher method. - ### 4. Play! Congratulations, you are now sailing with the Ship of Harkinian! Have fun! diff --git a/soh/soh/Extractor/Extract.cpp b/soh/soh/Extractor/Extract.cpp index b4c98f392..4e6e26b76 100644 --- a/soh/soh/Extractor/Extract.cpp +++ b/soh/soh/Extractor/Extract.cpp @@ -257,15 +257,15 @@ void Extractor::GetRoms(std::vector<std::string>& roms) { // Go through each file in the directory while ((dir = readdir(d)) != NULL) { struct stat path; + std::string fullPath = mSearchPath + "/" + dir->d_name; // Check if current entry is not folder - stat(dir->d_name, &path); - if (S_ISREG(path.st_mode)) { + if (stat(fullPath.c_str(), &path) == 0 && S_ISREG(path.st_mode)) { // Get the position of the extension character. char* ext = strrchr(dir->d_name, '.'); if (ext != NULL && (strcmp(ext, ".z64") == 0 || strcmp(ext, ".n64") == 0 || strcmp(ext, ".v64") == 0)) { - roms.push_back(dir->d_name); + roms.push_back(fullPath); } } } diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 30b7dcd91..0341e4f36 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2,6 +2,7 @@ #include "OTRAudio.h" #include <algorithm> #include <atomic> +#include <cstdlib> #include <filesystem> #include <fstream> #include <vector> @@ -1545,7 +1546,44 @@ bool VerifyArchiveVersion(OTRVersion version) { return version.major != INT16_MAX && version.major != gBuildVersionMajor; } +#ifdef __linux__ +// When run as an AppImage, keep user data in ~/.local/share/soh instead of the launch folder. +// Keep using the launch folder if it already has data from older versions. +static void SetAppImageHome() { + if (getenv("APPIMAGE") == nullptr || getenv("SHIP_HOME") != nullptr) { + return; + } + + for (const char* file : { "shipofharkinian.json", "oot.o2r", "oot-mq.o2r" }) { + if (std::filesystem::exists(file)) { + return; + } + } + + std::filesystem::path home; + const char* dataHome = getenv("XDG_DATA_HOME"); + const char* userHome = getenv("HOME"); + if (dataHome != nullptr && std::filesystem::path(dataHome).is_absolute()) { + home = dataHome; + } else if (userHome != nullptr && userHome[0] != '\0') { + home = std::filesystem::path(userHome) / ".local" / "share"; + } else { + return; + } + home /= appShortName; + + std::error_code ec; + std::filesystem::create_directories(home, ec); + if (!ec) { + setenv("SHIP_HOME", home.c_str(), 0); + } +} +#endif + extern "C" void InitOTR(int argc, char* argv[]) { +#ifdef __linux__ + SetAppImageHome(); +#endif OTRGlobals::Instance = new OTRGlobals(); OTRGlobals::Instance->RunExtract(argc, argv); |
