From 410ff8acc53ad2548ea0c5f9caee073bfb4d5596 Mon Sep 17 00:00:00 2001 From: aszlig Date: Sun, 7 Jun 2020 07:26:59 +0200 Subject: games/gog: Add Freedom Planet version 1.21.5 A game that I had laying around since quite a while but I was too lazy to patch properly, since the game expects its data files as well as its save files in the current working directory. While I did patch the game via an LD_PRELOAD wrapper of fopen it also feels kinda rendundant with code we have in preloaders of other games. So in the long term we might want to implement something a bit more generic, but for now the game works and config and saves are properly placed in XDG_CONFIG_HOME and XDG_DATA_HOME. Signed-off-by: aszlig --- pkgs/games/gog/default.nix | 1 + pkgs/games/gog/freedom-planet.nix | 117 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 pkgs/games/gog/freedom-planet.nix (limited to 'pkgs/games') diff --git a/pkgs/games/gog/default.nix b/pkgs/games/gog/default.nix index aa672b4f..723392b7 100644 --- a/pkgs/games/gog/default.nix +++ b/pkgs/games/gog/default.nix @@ -15,6 +15,7 @@ let crosscode = callPackage ./crosscode.nix {}; dungeons3 = callPackage ./dungeons3.nix {}; epistory = callPackage ./epistory.nix { }; + freedom-planet = callPackage ./freedom-planet.nix {}; homm3 = callPackage ./homm3 {}; kingdoms-and-castles = callPackage ./kingdoms-and-castles.nix {}; overload = callPackage ./overload.nix {}; diff --git a/pkgs/games/gog/freedom-planet.nix b/pkgs/games/gog/freedom-planet.nix new file mode 100644 index 00000000..05a9b869 --- /dev/null +++ b/pkgs/games/gog/freedom-planet.nix @@ -0,0 +1,117 @@ +{ stdenv, buildGame, fetchGog, writeText, SDL2, libudev }: + +buildGame rec { + name = "freedom-planet-${version}"; + version = "1.21.5"; + + src = fetchGog { + productId = 1207667013; + downloadName = "en3installer0"; + sha256 = "1rsa2bswzvc4a8crpzhcw3vjan0f9avk7g1gyqibnyppib63i42w"; + }; + + binDir = "bin${if stdenv.is64bit then "64" else "32"}"; + buildInputs = [ SDL2 ]; + runtimeDependencies = [ libudev ]; + + buildPhase = '' + cc -Werror -Wall -std=gnu11 -shared "$preloader" -o preload.so -fPIC \ + -DDATA_DIR="\"$out/share/freedom-planet\"" + patchelf \ + --add-needed "$out/libexec/freedom-planet/libpreload.so" \ + "$binDir/Chowdren" + ''; + + preloader = writeText "freedom-planet-preloader.c" '' + #define _GNU_SOURCE + #include + #include + #include + #include + + static char *mkDataPath(const char *path) + { + size_t pathlen; + char *buf; + + pathlen = strlen(path); + buf = malloc(pathlen + sizeof(DATA_DIR)); + if (buf == NULL) return NULL; + + memcpy(buf, DATA_DIR, sizeof(DATA_DIR) - 1); + memcpy(buf + sizeof(DATA_DIR) - 1, path, pathlen + 1); + + return buf; + } + + static char *mkSavePath(const char *path) + { + char *env; + char *buf; + + if ((env = getenv("XDG_DATA_HOME")) != NULL) { + if (asprintf(&buf, "%s/freedom-planet%s", env, path + 1) == -1) + return NULL; + } else if ((env = getenv("HOME")) != NULL) { + if (asprintf(&buf, "%s/.local/share/freedom-planet%s", env, + path + 1) == -1) + return NULL; + } + + return buf; + } + + static char *mkCfgPath(const char *path) + { + char *env; + char *buf; + + if ((env = getenv("XDG_CONFIG_HOME")) != NULL) { + if (asprintf(&buf, "%s/freedom-planet%s", env, path + 1) == -1) + return NULL; + } else if ((env = getenv("HOME")) != NULL) { + if (asprintf(&buf, "%s/.config/freedom-planet%s", env, path + 1) == -1) + return NULL; + } + + return buf; + } + + FILE *fopen(const char *path, const char *mode) { + FILE *ret; + char *buf; + + static FILE *(*_fopen) (const char *, const char *) = NULL; + if (_fopen == NULL) _fopen = dlsym(RTLD_NEXT, "fopen"); + + if (strncmp(path, "./Assets.dat", 13) == 0) { + buf = mkDataPath(path + 1); + } else if (strncmp(path, "./Data/", 7) == 0) { + buf = mkDataPath(path + 6); + } else if (strncmp(path, "./records.dat", 14) == 0 || + strncmp(path, "./file", 6) == 0 || + strncmp(path, "./save", 6) == 0) { + buf = mkSavePath(path); + } else if (strncmp(path, "./control_", 10) == 0) { + buf = mkCfgPath(path); + } else { + return _fopen(path, mode); + } + if (buf == NULL) return NULL; + ret = fopen(buf, mode); + free(buf); + return ret; + } + ''; + + installPhase = '' + install -m 0644 -vD Assets.dat "$out/share/freedom-planet/Assets.dat" + install -vD "$binDir/Chowdren" "$out/bin/freedom-planet" + install -vD preload.so "$out/libexec/freedom-planet/libpreload.so" + cp -rt "$out/share/freedom-planet" Data/BGM Data/font.bmp Data/voices + ''; + + sandbox.paths.required = [ + "$XDG_DATA_HOME/freedom-planet" "$XDG_CONFIG_HOME/freedom-planet" + ]; +} -- cgit 1.4.1