diff options
Diffstat (limited to 'pkgs/games')
-rw-r--r-- | pkgs/games/humblebundle/default.nix | 1 | ||||
-rw-r--r-- | pkgs/games/humblebundle/owlboy.nix | 102 |
2 files changed, 103 insertions, 0 deletions
diff --git a/pkgs/games/humblebundle/default.nix b/pkgs/games/humblebundle/default.nix index 3ed0b3b6..4a0792c4 100644 --- a/pkgs/games/humblebundle/default.nix +++ b/pkgs/games/humblebundle/default.nix @@ -25,6 +25,7 @@ let liads = callPackage ./liads.nix {}; megabytepunch = callPackage_i686 ./megabytepunch.nix {}; opus-magnum = callPackage ./opus-magnum.nix {}; + owlboy = callPackage ./owlboy.nix {}; pico-8 = callPackage ./pico-8.nix {}; rocketbirds = callPackage ./rocketbirds.nix {}; spaz = callPackage ./spaz.nix {}; diff --git a/pkgs/games/humblebundle/owlboy.nix b/pkgs/games/humblebundle/owlboy.nix new file mode 100644 index 00000000..a6c42577 --- /dev/null +++ b/pkgs/games/humblebundle/owlboy.nix @@ -0,0 +1,102 @@ +{ stdenv, lib, buildGame, fetchHumbleBundle, unzip, makeWrapper, mono50 +, SDL2, SDL2_image, openal, libvorbis +, writeText +}: + +buildGame rec { + name = "owlboy-${version}"; + version = "20171229"; + + src = fetchHumbleBundle { + suffix = "bin"; + machineName = "owlboy_linux"; + md5 = "c2e99502013c7d2529bc2aefb6416dcf"; + }; + + unpackCmd = "${unzip}/bin/unzip -qq \"$curSrc\" 'data/*' || :"; + + nativeBuildInputs = [ makeWrapper ]; + + libdir = if stdenv.system == "x86_64-linux" then "lib64" else "lib"; + + prePatch = '' + find -type f -name '*.ini' -exec sed -i -e 's/${"\r"}$//' {} + + ''; + + buildPhase = let + dllmap = { + SDL2 = "${SDL2}/lib/libSDL2.so"; + SDL2_image = "${SDL2_image}/lib/libSDL2_image.so"; + soft_oal = "${openal}/lib/libopenal.so"; + libvorbisfile-3 = "${libvorbis}/lib/libvorbisfile.so"; + MojoShader = "$out/lib/owlboy/libmojoshader.so"; + }; + in '' + cc -Werror -shared "$preloader" -o preloader.so -ldl -fPIC \ + -DSTOREPATH=\"$out\" + '' + lib.concatStrings (lib.mapAttrsToList (dll: target: '' + sed -i -e '/<dllmap.*dll="${dll}\.dll".*os="linux"/ { + s!target="[^"]*"!target="'"${target}"'"! + }' FNA.dll.config + '') dllmap); + + # The game tries to open data files in read-write mode, so use LD_PRELOAD to + # avoid this whenever a store path is involved. + preloader = writeText "owlboy-preloader.c" '' + #define _GNU_SOURCE + #include <dlfcn.h> + #include <fcntl.h> + #include <stdarg.h> + #include <stdio.h> + #include <stdbool.h> + #include <string.h> + #include <sys/stat.h> + + static bool isDataPath(const char *path) { + return strncmp(path, "content/", 8) == 0 + || strncmp(path, STOREPATH, sizeof(STOREPATH) - 1) == 0; + } + + int access(const char *path, int mode) { + static int (*_access) (const char *, int) = NULL; + if (_access == NULL) _access = dlsym(RTLD_NEXT, "access"); + if (isDataPath(path) && mode & W_OK) + mode = mode & ~W_OK | R_OK; + return _access(path, mode); + } + + int open(const char *path, int flags, ...) { + va_list ap; + mode_t mode; + static int (*_open) (const char *, int, mode_t) = NULL; + if (_open == NULL) _open = dlsym(RTLD_NEXT, "open"); + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + if (isDataPath(path) && flags & O_RDWR) + flags = flags & ~O_RDWR | O_RDONLY; + return _open(path, flags, mode); + } + ''; + + installPhase = '' + mkdir -p "$out/bin" "$out/share" "$out/libexec/owlboy" + install -vD preloader.so "$out/lib/owlboy/preloader.so" + cp -rv content "$out/share/owlboy" + cp -rv monoconfig "$out/libexec/owlboy/Owlboy.exe.config" + cp -rvt "$out/libexec/owlboy" Owlboy.exe \ + FNA.dll* GamedevUtility.dll MoonSharp.Interpreter.dll TimSort.dll + cp -rvt "$out/lib/owlboy" "$libdir/libmojoshader.so" + ln -vs "$out/share/owlboy" "$out/libexec/owlboy/content" + + makeWrapper ${lib.escapeShellArg mono50}/bin/mono \ + "$out/bin/owlboy" \ + --set LD_PRELOAD "$out/lib/owlboy/preloader.so" \ + --add-flags "$out/libexec/owlboy/Owlboy.exe" \ + --run "cd '$out/libexec/owlboy'" + ''; + + sandbox.paths.required = [ + "$XDG_DATA_HOME/Owlboy" "$XDG_CONFIG_HOME/Owlboy" + ]; +} |