about summary refs log tree commit diff
path: root/pkgs/games/gog/albion/default.nix
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2018-02-19 04:32:32 +0100
committeraszlig <aszlig@nix.build>2018-02-21 20:38:34 +0100
commit77a0f47d06f3d21b78c7f34a129bc3f75d69fbf7 (patch)
treefe50abea68d2ce04b104058f097aa6aa89737bb2 /pkgs/games/gog/albion/default.nix
parent73b4b0bfb78998a53b73ce2501f4d2b8bc73198d (diff)
games/gog: Add statically recompiled Albion
We only fetch the data files from GOG here and use the port from
OpenPandora (https://repo.openpandora.org/?page=detail&app=albion_sr)
for the main game executable.

Instead of using the binaries of the static recompiler, this is
completely compiled from source and comes with a few changes in the form
of a few patches:

  config.patch:

    Hide the mouse cursor and set the default scaled resolution to
    1280x960 (the window can still be resized) in the default
    albion.cfg.

  error-log-stderr.patch:

    Whenever an error happens, the game usually creates a file called
    "error.log", which contains the actual error message. This patch
    makes sure the file isn't created but the error message is printed
    to stderr.

  scons.patch:

    Fixes a few SConstruct/SConscript files to use the builder's
    environment, so that it can find executables such as gcc.

  sdl2.patch:

    SDL 2 has dropped support for the keysym.unicode field at some
    point, so use keysym.sym instead. This has the disadvantage that it
    doesn't recognize key modifiers, so we might want to switch this to
    use the SDL_TEXTINPUT event.

  xdg-paths.patch:

    We want to use XDG_CONFIG_HOME and XDG_DATA_HOME instead of writing
    everything to one directory, so this patch makes sure that the paths
    are correctly read depending on whether its an XDG directory or one
    of the store paths of the game.

Signed-off-by: aszlig <aszlig@nix.build>
Diffstat (limited to 'pkgs/games/gog/albion/default.nix')
-rw-r--r--pkgs/games/gog/albion/default.nix183
1 files changed, 183 insertions, 0 deletions
diff --git a/pkgs/games/gog/albion/default.nix b/pkgs/games/gog/albion/default.nix
new file mode 100644
index 00000000..1242ecb7
--- /dev/null
+++ b/pkgs/games/gog/albion/default.nix
@@ -0,0 +1,183 @@
+{ stdenv, lib, buildSandbox, fetchGog, fetchzip, innoextract, SDL2, SDL2_mixer
+, bchunk, p7zip, alsaLib, writeText
+
+# For static recompilation
+, fetchFromGitHub, scons, judy, python, nasm, autoreconfHook
+
+, language ? "en"
+}:
+
+let
+  version = "1.6.1";
+
+  staticRecompilerSource = fetchFromGitHub {
+    owner = "M-HT";
+    repo = "SR";
+    rev = "albion_v${version}";
+    sha256 = "0yspgssfk5xbrs5krq0sin561rgb0fva4hk7mlxlcrvs0xpqf5z8";
+  };
+
+  mkPatchedWildMidi = variant: stdenv.mkDerivation {
+    name = "${variant}-0.2.3.5patched";
+    src = "${staticRecompilerSource}/midi-libs/${variant}-0.2.3.5svn";
+    nativeBuildInputs = [ autoreconfHook ];
+    buildInputs = [ alsaLib ];
+    postPatch = "sed -i -e '/^CFLAGS/s/-pedantic//' configure.ac";
+  };
+
+  compileMidiPlugin = variant: let
+    commonDrvAttrs = rec {
+      name = "midi-plugin-${variant}";
+      soname = "midi-${variant}";
+      sourceFile = "${soname}.c";
+      midiLib = "WildMidi";
+
+      src = "${staticRecompilerSource}/midi-plugins";
+
+      buildInputs = lib.singleton (mkPatchedWildMidi variant);
+
+      timidityCfg = let
+        gusPatches = lib.overrideDerivation (fetchzip {
+          url = "http://sebt3.openpandora.org/pnd/timidity_midi_installer.pnd";
+          sha256 = "0nznac8lxcbj0fwbg0njlnh3ysa3d3c5i24n2cw0yv5yqji4cdsb";
+          stripRoot = false;
+        }) (lib.const { unpackCmd = "${p7zip}/bin/7z x \"$curSrc\""; });
+      in writeText "timidity-albion.cfg" ''
+        dir ${gusPatches}/eawpats
+        source ${gusPatches}/eawpats/sounds.cfg
+      '';
+
+      postPatch = ''
+        sed -i -e 's!getenv("TIMIDITY_CFG")!"'"$timidityCfg"'"!' \
+          midi-wildmidi.c
+      '';
+
+      buildPhase = ''
+        gcc -shared -Wl,-soname,"$soname.so" -I. \
+          -o "$soname.so" -fpic -m32 -O2 -Wall \
+          "$sourceFile" -l"$midiLib"
+      '';
+
+      installPhase = ''
+        install -vD "$soname.so" "$out/lib/$soname.so"
+      '';
+    };
+
+    extraAttrs = lib.optionalAttrs (variant == "wildmidiA") {
+      soname = "midiA-wildmidi";
+      sourceFile = "albion/midiA-wildmidi.c";
+      midiLib = "WildMidiA";
+    };
+
+  in stdenv.mkDerivation (commonDrvAttrs // extraAttrs);
+
+  udis86 = stdenv.mkDerivation {
+    name = "udis86";
+    src = "${staticRecompilerSource}/SR/udis86-1.6";
+    postPatch = "chmod +x configure mkinstalldirs";
+    preInstall = "mkdir -p \"$out/lib\" \"$out/bin\"";
+  };
+
+  gameData = stdenv.mkDerivation rec {
+    name = "albion-game-data-${version}";
+    version = "3";
+
+    src = fetchGog {
+      productId = 1436955815;
+      downloadName = "${language}1installer1";
+      sha256 = ({
+        de = "0ylhma70kcj255i03gy5xa3adb8hfw2xpk1m2pp5880aqkmr06k7";
+        en = "0x0s2q0x7kjz6qfhb9qs5d959caijiinpc7xv4rx9n7mmb7xlh5m";
+      }).${language};
+    };
+
+    outputs = [ "out" "dev" ];
+
+    nativeBuildInputs = [ innoextract ];
+    phases = [ "unpackPhase" "patchPhase" "installPhase" ];
+    unpackCmd = toString [
+      "innoextract"
+      "--include" "game.gog"
+      "--include" "game.ins"
+      "--include" "MAIN.EXE"
+      "--include" "SETUP.INI"
+      "-m" "\"$curSrc\""
+    ];
+    patchPhase = ''
+      sed -i -e '
+        s,^SOURCE_PATH=.*,SOURCE_PATH=C:\\,
+        s/^\(MODE_[^=]*=\)N$/\1Y/
+      ' SETUP.INI
+    '';
+    installPhase = ''
+      ${bchunk}/bin/bchunk game.gog game.ins game_cd
+      ${p7zip}/bin/7z x game_cd01.iso ALBION
+      mv ALBION "$out"
+      install -vD -m 0644 SETUP.INI "$out/setup.ini"
+      install -vD -m 0644 MAIN.EXE "$dev/albion_main.exe"
+    '';
+  };
+
+in buildSandbox (stdenv.mkDerivation {
+  name = "albion-${version}";
+  inherit version;
+
+  src = staticRecompilerSource;
+
+  patches = [
+    ./scons.patch ./xdg-paths.patch ./config.patch ./sdl2.patch
+    ./error-log-stderr.patch ./cdpath-is-gamedir.patch
+    ./storepaths.patch
+  ];
+
+  wildmidi = compileMidiPlugin "wildmidi";
+  wildmidiA = compileMidiPlugin "wildmidiA";
+
+  postPatch = ''
+    substituteInPlace games/Albion/SR-Main/main.c \
+      --subst-var-by GAME_CONFIG_FILE "$out/etc/albion.cfg" \
+      --subst-var-by GAME_DATA_PATH ${lib.escapeShellArg gameData.out}
+
+    substituteInPlace games/Albion/SR-Main/virtualfs.c \
+      --subst-var-by SETUP_INI_PATH "${gameData.out}/setup.ini"
+
+    substituteInPlace games/Albion/SR-Main/Albion-music-midiplugin.c \
+      --replace ./midi-wildmidi.so "$wildmidi/lib/midi-wildmidi.so" \
+      --replace ./midiA-wildmidi.so "$wildmidiA/lib/midiA-wildmidi.so" \
+  '';
+
+  nativeBuildInputs = [ scons judy python nasm udis86 ];
+  buildInputs = [ SDL2 SDL2_mixer ];
+
+  NIX_CFLAGS_COMPILE = "-I${lib.getDev SDL2}/include/SDL2";
+
+  buildPhase = ''
+    scons -C SR debug=1
+
+    mkdir tmp
+    pushd tmp
+    cp ../SR-games/Albion/SR/x86/*.sci .
+    ../SR/SR.exe ${gameData.dev}/albion_main.exe Albion-main.asm
+    rm *.sci
+    python ../SR-games/Albion/SR/compact_source.py
+    nasm -felf -dELF -O1 -w+orphan-labels -w-number-overflow \
+      -i../SR-games/Albion/SR/x86/ Albion-main_linux.asm 2> a.a || :
+    python ../SR-games/Albion/SR/repair_short_jumps.py
+    popd
+
+    mv tmp/seg*.inc tmp/Albion-main.asm tmp/Albion-main_linux.asm \
+      games/Albion/SR-Main/x86
+    rm -r tmp
+
+    scons -C games/Albion/SR-Main debug=1 device=pc-linux sdl2=1
+  '';
+
+  installPhase = ''
+    install -vD -m 0644 games/Albion/release/linux/Albion.cfg \
+      "$out/etc/albion.cfg"
+    install -vD games/Albion/SR-Main/SR-Main "$out/bin/albion"
+  '';
+}) {
+  paths.required = [ "$XDG_DATA_HOME/albion" "$XDG_CONFIG_HOME/albion" ];
+  paths.runtimeVars = [ "LD_LIBRARY_PATH" ];
+}