summary refs log tree commit diff
path: root/pkgs/games/dwarf-fortress
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/games/dwarf-fortress')
-rw-r--r--pkgs/games/dwarf-fortress/default.nix229
-rw-r--r--pkgs/games/dwarf-fortress/dfhack-run.in11
-rw-r--r--pkgs/games/dwarf-fortress/dfhack/default.nix49
-rw-r--r--pkgs/games/dwarf-fortress/dfhack/use-system-libraries.patch138
-rw-r--r--pkgs/games/dwarf-fortress/dwarf-fortress-hacked.in13
-rw-r--r--pkgs/games/dwarf-fortress/dwarf-fortress.in14
-rw-r--r--pkgs/games/dwarf-fortress/dwarf-therapist/default.nix40
-rw-r--r--pkgs/games/dwarf-fortress/dwarf-therapist/wrapper.nix43
-rw-r--r--pkgs/games/dwarf-fortress/export-libs.sh.in12
-rw-r--r--pkgs/games/dwarf-fortress/export-workaround.sh1
-rw-r--r--pkgs/games/dwarf-fortress/game.nix48
-rw-r--r--pkgs/games/dwarf-fortress/install-df-data-content-to-home.sh4
-rw-r--r--pkgs/games/dwarf-fortress/install-df-data-to-home.sh12
-rw-r--r--pkgs/games/dwarf-fortress/install-dfhack-data-to-home.sh16
-rw-r--r--pkgs/games/dwarf-fortress/themes/phoebus.nix33
-rw-r--r--pkgs/games/dwarf-fortress/unfuck.nix41
-rw-r--r--pkgs/games/dwarf-fortress/wrapper/default.nix68
-rw-r--r--pkgs/games/dwarf-fortress/wrapper/dfhack.in11
-rw-r--r--pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in41
-rw-r--r--pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in6
20 files changed, 540 insertions, 290 deletions
diff --git a/pkgs/games/dwarf-fortress/default.nix b/pkgs/games/dwarf-fortress/default.nix
index 97c793b8a39..d91c110c34c 100644
--- a/pkgs/games/dwarf-fortress/default.nix
+++ b/pkgs/games/dwarf-fortress/default.nix
@@ -1,218 +1,33 @@
-{ stdenv, fetchgit, fetchurl, cmake, glew, ncurses
-, SDL, SDL_image, SDL_ttf, gtk2, glib
-, mesa, openal, pango, atk, gdk_pixbuf, glibc, libsndfile
-# begin dfhack-only parameters
-, XMLLibXML
-, XMLLibXSLT
-, perl
-, zlib
-# end dfhack-only parameters
-, enableDFHack ? false
-}:
+{ pkgs, pkgsi686Linux }:
 
 let
-  baseVersion = "40";
-  patchVersion = "24";
-  srcs = {
-    df_unfuck = fetchgit {
-      url = "https://github.com/svenstaro/dwarf_fortress_unfuck";
-      rev = "39742d64d2886fb594d79e7cc4b98fb917f26811";
-      sha256 = "19vwx6kpv1sf93bx5v8x47f7x2cgxsqk82v6j1a72sa3q7m5cpc7";
-    };
+  callPackage = pkgs.newScope self;
+  callPackage_i686 = pkgsi686Linux.newScope self;
 
-    dfhack = fetchgit {
-      url = "https://github.com/DFHack/dfhack.git";
-      rev = "0849099f2083e100cae6f64940b4eff4c28ce2eb";
-      sha256 = "0lnqrayi8hwfivkrxb7fw8lb6v95i04pskny1px7084n7nzvyv8b";
-    };
+  self = rec {
+    dwarf-fortress-original = callPackage_i686 ./game.nix { };
 
-    df = fetchurl {
-      url = "http://www.bay12games.com/dwarves/df_${baseVersion}_${patchVersion}_linux.tar.bz2";
-      sha256 = "0d4jrs45qj89vq9mjg7fxxhis7zivvb0vzjpmkk274b778kccdys";
+    dfhack = callPackage_i686 ./dfhack {
+      inherit (pkgsi686Linux.perlPackages) XMLLibXML XMLLibXSLT;
     };
-  };
-
-  dfHackWorksWithCurrentVersion = true;
-  dfHackEnabled = dfHackWorksWithCurrentVersion && enableDFHack;
-
-in
-
-assert stdenv.system == "i686-linux";
-
-stdenv.mkDerivation rec {
-  name = "dwarf-fortress-0.${baseVersion}.${patchVersion}";
-
-  inherit baseVersion patchVersion;
-
-  buildInputs = [
-    SDL
-    SDL_image
-    SDL_ttf
-    gtk2
-    glib
-    glew
-    mesa
-    ncurses
-    openal
-    glibc
-    libsndfile
-    pango
-    atk
-    cmake
-    gdk_pixbuf
-    XMLLibXML
-    XMLLibXSLT
-    perl
-    zlib
-  ];
-  src = "${srcs.df_unfuck} ${srcs.df}" + stdenv.lib.optionalString dfHackEnabled " ${srcs.dfhack}";
-
-  sourceRoot = srcs.df_unfuck.name;
-  dfHackSourceRoot = srcs.dfhack.name;
-
-  cmakeFlags = [
-    "-DGTK2_GLIBCONFIG_INCLUDE_DIR=${glib.out}/lib/glib-2.0/include"
-    "-DGTK2_GDKCONFIG_INCLUDE_DIR=${gtk2.out}/lib/gtk-2.0/include"
-  ];
-
-  permission = ./df_permission;
-  dfHackTemplate = ./dwarf-fortress-hacked.in;
-  dfHackRunTemplate = ./dfhack-run.in;
-  dwarfFortressTemplate = ./dwarf-fortress.in;
-  installDfDataToHome = ./install-df-data-to-home.sh;
-  installDfhackDataToHome = ./install-dfhack-data-to-home.sh;
-  installDfDataContentToHome = ./install-df-data-content-to-home.sh;
-  exportLibsTemplate = ./export-libs.sh.in;
-  exportWorkaround = ./export-workaround.sh;
-
-  postUnpack = stdenv.lib.optionalString dfHackEnabled ''
-    if [ "$dontMakeSourcesWritable" != 1 ]; then
-      chmod -R u+w "$dfHackSourceRoot"
-    fi
-  '';
-
-  preConfigure = stdenv.lib.optionalString dfHackEnabled ''
-    export cmakeFlags="-DCMAKE_INSTALL_PREFIX=$out/share/df_linux $cmakeFlags"
-    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/build/depends/protobuf
-  '';
-
-  postConfigure = stdenv.lib.optionalString dfHackEnabled ''
-    if [ -z "$originalSourceRoot" ]; then
-
-      originalSourceRoot=$sourceRoot
-      export sourceRoot=$dfHackSourceRoot
-
-      pushd ../../$sourceRoot
-
-      eval "''${configurePhase:-configurePhase}"
-
-      popd
-
-      export sourceRoot=$originalSourceRoot
-      unset originalSourceRoot
-    fi
-  '';
-
-  # outputs TODO: probably wrong path-substitutions below
-  installPhase = ''
-    set -x
-    mkdir -p $out/bin
-    mkdir -p $out/share/df_linux
-    pushd ../../
-    cp -r ./df_linux/* $out/share/df_linux
-    rm $out/share/df_linux/libs/lib*
 
-    # Store the original hash
-    orig_hash=$(md5sum $out/share/df_linux/libs/Dwarf_Fortress | awk '{ print $1 }')
-    echo $orig_hash | cut -c1-8 > $out/share/df_linux/hash.md5.orig  # for dwarf-therapist
-    echo $orig_hash > $out/share/df_linux/full-hash-orig.md5  # for dfhack
+    dwarf-fortress-unfuck = callPackage_i686 ./unfuck.nix { };
 
-    cp -f ./${srcs.df_unfuck.name}/build/libgraphics.so $out/share/df_linux/libs/libgraphics.so
-
-    cp $permission $out/share/df_linux/nix_permission
-
-    # Placeholder files for hashes of patched binary
-    touch $out/share/df_linux/hash.md5.patched
-    touch $out/share/df_linux/full-hash-patched.md5
-
-    mkdir -p $out/share/df_linux/shell
-    cp $installDfDataToHome $out/share/df_linux/shell/install-df-data-to-home.sh
-    cp $installDfhackDataToHome $out/share/df_linux/shell/install-dfhack-data-to-home.sh
-    cp $installDfDataContentToHome $out/share/df_linux/shell/install-df-data-content-to-home.sh
-    cp $exportWorkaround $out/share/df_linux/shell/export-workaround.sh
-    substitute $exportLibsTemplate $out/share/df_linux/shell/export-libs.sh \
-        --subst-var-by stdenv_cc ${stdenv.cc} \
-        --subst-var-by SDL ${SDL} \
-        --subst-var-by SDL_image ${SDL_image} \
-        --subst-var-by SDL_ttf ${SDL_ttf} \
-        --subst-var-by gtk2 ${gtk2} \
-        --subst-var-by glib ${glib} \
-        --subst-var-by libsndfile ${libsndfile} \
-        --subst-var-by mesa ${mesa} \
-        --subst-var-by openal ${openal} \
-        --subst-var-by zlib ${zlib} \
-
-    substitute $dwarfFortressTemplate $out/bin/dwarf-fortress \
-        --subst-var-by stdenv_shell ${stdenv.shell} \
-        --subst-var prefix
-
-    chmod 755 $out/bin/dwarf-fortress
-
-    popd
-  '' + stdenv.lib.optionalString dfHackEnabled ''
-
-    originalSourceRoot=$sourceRoot
-    export sourceRoot=$dfHackSourceRoot
-
-    pushd ../../$sourceRoot/build
-
-    mkdir -p $out/dfhack
-
-    make install
-
-    cp ../package/linux/dfhack $out/dfhack/
-
-    mkdir -p $out/bin
-
-    substitute $dfHackTemplate $out/bin/dfhack \
-        --subst-var-by stdenv_shell ${stdenv.shell} \
-        --subst-var prefix
-    chmod 755 $out/bin/dfhack
-
-    substitute $dfHackRunTemplate $out/bin/dfhack-run \
-        --subst-var-by stdenv_shell ${stdenv.shell} \
-        --subst-var prefix
-    chmod 755 $out/bin/dfhack-run
-
-    popd
-
-    export sourceRoot=$originalSourceRoot
-    unset originalSourceRoot
-  '';
-
-  fixupPhase = ''
-    # Fix rpath
-    patchelf --set-rpath "${stdenv.lib.makeLibraryPath [ stdenv.cc.cc stdenv.glibc ]}:$out/share/df_linux/libs" $out/share/df_linux/libs/Dwarf_Fortress
-
-    patchelf --set-interpreter ${glibc.out}/lib/ld-linux.so.2 $out/share/df_linux/libs/Dwarf_Fortress
+    dwarf-fortress = callPackage ./wrapper {
+      themes = {
+        "phoebus" = phoebus-theme;
+      };
+    };
 
-    # Store new hash
-    patched_hash=$(md5sum $out/share/df_linux/libs/Dwarf_Fortress | awk '{ print $1 }')
-    echo $patched_hash | cut -c1-8 > $out/share/df_linux/hash.md5.patched  # for dwarf-therapist
-    echo $patched_hash > $out/share/df_linux/full-hash-patched.md5  # for dfhack
-  '' + stdenv.lib.optionalString dfHackEnabled ''
-    find $out/share/df_linux/hack \( \
-        \( -type f -a -name "*.so*" \) -o \
-        \( -type f -a -perm +0100 \) \
-        \) -print -exec patchelf --shrink-rpath {} \;
+    dwarf-therapist-original = callPackage ./dwarf-therapist {
+      texlive = pkgs.texlive.combine {
+        inherit (pkgs.texlive) scheme-basic float caption wrapfig adjmulticol sidecap preprint enumitem;
+      };
+    };
 
-    sed -i "s/$(cat $out/share/df_linux/full-hash-orig.md5)/$(cat $out/share/df_linux/full-hash-patched.md5)/" $out/share/df_linux/hack/symbols.xml
-  '';
+    dwarf-therapist = callPackage ./dwarf-therapist/wrapper.nix { };
 
-  meta = {
-    description = "A single-player fantasy game with a randomly generated adventure world";
-    homepage = http://www.bay12games.com/dwarves;
-    license = stdenv.lib.licenses.unfreeRedistributable;
-    maintainers = with stdenv.lib.maintainers; [ a1russell robbinch roconnor the-kenny ];
+    phoebus-theme = callPackage ./themes/phoebus.nix { };
   };
-}
+
+in self
diff --git a/pkgs/games/dwarf-fortress/dfhack-run.in b/pkgs/games/dwarf-fortress/dfhack-run.in
deleted file mode 100644
index 590e5b25acf..00000000000
--- a/pkgs/games/dwarf-fortress/dfhack-run.in
+++ /dev/null
@@ -1,11 +0,0 @@
-#!@stdenv_shell@
-
-data_dir=${XDG_DATA_HOME:-$HOME/.local/share}/df_linux
-pkg_dir=@prefix@/share/df_linux
-
-. $pkg_dir/shell/install-df-data-to-home.sh
-. $pkg_dir/shell/install-dfhack-data-to-home.sh
-. $pkg_dir/shell/export-libs.sh
-
-cd "$data_dir"
-exec ./dfhack-run "$@"
diff --git a/pkgs/games/dwarf-fortress/dfhack/default.nix b/pkgs/games/dwarf-fortress/dfhack/default.nix
new file mode 100644
index 00000000000..92b9d57da42
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/dfhack/default.nix
@@ -0,0 +1,49 @@
+{ stdenv, fetchgit, cmake, writeScriptBin
+, perl, XMLLibXML, XMLLibXSLT
+, zlib
+, jsoncpp, protobuf, tinyxml
+}:
+
+let
+  rev = "f61ff9147e00f3c379ac0458e79eb556a5de1b68";
+  dfVersion = "0.42.05";
+
+  fakegit = writeScriptBin "git" ''
+    #! ${stdenv.shell}
+    if [ "$*" = "describe --tags --long" ]; then
+      echo "${dfVersion}-unknown"
+    elif [ "$*" = "rev-parse HEAD" ]; then
+      echo "${rev}"
+    else
+      exit 1
+    fi
+  '';
+
+in stdenv.mkDerivation {
+  name = "dfhack-20160118";
+
+  # Beware of submodules
+  src = fetchgit {
+    url = "https://github.com/DFHack/dfhack";
+    inherit rev;
+    sha256 = "1ah3cplp4mb9pq7rm1cmn8klfjxw3y2xfzy7734i81b3iwiwlpi4";
+  };
+
+  patches = [ ./use-system-libraries.patch ];
+
+  nativeBuildInputs = [ cmake perl XMLLibXML XMLLibXSLT fakegit ];
+  # we can't use native Lua; upstream uses private headers
+  buildInputs = [ zlib jsoncpp protobuf tinyxml ];
+
+  enableParallelBuilding = true;
+
+  passthru = { inherit dfVersion; };
+
+  meta = with stdenv.lib; {
+    description = "Memory hacking library for Dwarf Fortress and a set of tools that use it";
+    homepage = https://github.com/DFHack/dfhack/;
+    license = licenses.zlib;
+    platforms = [ "i686-linux" ];
+    maintainers = with maintainers; [ robbinch a1russell abbradar ];
+  };
+}
diff --git a/pkgs/games/dwarf-fortress/dfhack/use-system-libraries.patch b/pkgs/games/dwarf-fortress/dfhack/use-system-libraries.patch
new file mode 100644
index 00000000000..2ae3620fff6
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/dfhack/use-system-libraries.patch
@@ -0,0 +1,138 @@
+From 1196fcb987b6aadb49075d817b3615bf8a6d7d51 Mon Sep 17 00:00:00 2001
+From: Nikolay Amiantov <ab@fmap.me>
+Date: Wed, 6 Jan 2016 03:07:20 +0300
+Subject: [PATCH 2/2] Use as much system libraries as possible
+
+---
+ CMakeLists.txt                    |  5 -----
+ depends/CMakeLists.txt            |  3 ---
+ library/CMakeLists.txt            | 10 +++++-----
+ plugins/CMakeLists.txt            |  4 ++--
+ plugins/mapexport/CMakeLists.txt  |  4 ++--
+ plugins/stockpiles/CMakeLists.txt |  4 ++--
+ 6 files changed, 11 insertions(+), 19 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 1933390..d871df4 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -152,8 +152,6 @@ ELSEIF(MSVC)
+   SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od")
+ ENDIF()
+ 
+-# use shared libraries for protobuf
+-ADD_DEFINITIONS(-DPROTOBUF_USE_DLLS)
+ ADD_DEFINITIONS(-DLUA_BUILD_AS_DLL)
+ 
+ if(APPLE)
+@@ -173,11 +171,8 @@ if(NOT UNIX)
+ endif()
+ set(ZLIB_ROOT /usr/lib/i386-linux-gnu)
+ find_package(ZLIB REQUIRED)
+-include_directories(depends/protobuf)
+ include_directories(depends/lua/include)
+ include_directories(depends/md5)
+-include_directories(depends/jsoncpp)
+-include_directories(depends/tinyxml)
+ include_directories(depends/tthread)
+ include_directories(${ZLIB_INCLUDE_DIRS})
+ include_directories(depends/clsocket/src)
+diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt
+index bf0345b..2a1a852 100644
+--- a/depends/CMakeLists.txt
++++ b/depends/CMakeLists.txt
+@@ -1,10 +1,7 @@
+ #list depends here.
+ add_subdirectory(lua)
+ add_subdirectory(md5)
+-add_subdirectory(protobuf)
+-add_subdirectory(tinyxml)
+ add_subdirectory(tthread)
+-add_subdirectory(jsoncpp)
+ # build clsocket static and only as a dependency. Setting those options here overrides its own default settings.
+ OPTION(CLSOCKET_SHARED "Build clsocket lib as shared." OFF)
+ OPTION(CLSOCKET_DEP_ONLY "Build for use inside other CMake projects as dependency." ON)
+diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
+index 5071d9e..d346d1e 100644
+--- a/library/CMakeLists.txt
++++ b/library/CMakeLists.txt
+@@ -203,10 +203,10 @@ LIST(APPEND PROJECT_SOURCES ${PROJECT_PROTO_SRCS})
+ 
+ ADD_CUSTOM_COMMAND(
+     OUTPUT ${PROJECT_PROTO_SRCS} ${PROJECT_PROTO_HDRS}
+-    COMMAND protoc-bin -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/
++    COMMAND protoc -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/
+             --cpp_out=dllexport_decl=DFHACK_EXPORT:${CMAKE_CURRENT_SOURCE_DIR}/proto/
+             ${PROJECT_PROTOS}
+-    DEPENDS protoc-bin ${PROJECT_PROTOS}
++    DEPENDS ${PROJECT_PROTOS}
+ )
+ 
+ # Merge headers into sources
+@@ -249,12 +249,12 @@ IF(UNIX)
+ ENDIF()
+ 
+ IF(APPLE)
+-  SET(PROJECT_LIBS dl dfhack-md5 dfhack-tinyxml dfhack-tinythread)
++  SET(PROJECT_LIBS dl dfhack-md5 tinyxml dfhack-tinythread)
+ ELSEIF(UNIX)
+-  SET(PROJECT_LIBS rt dl dfhack-md5 dfhack-tinyxml dfhack-tinythread)
++  SET(PROJECT_LIBS rt dl dfhack-md5 tinyxml dfhack-tinythread)
+ ELSE(WIN32)
+   #FIXME: do we really need psapi?
+-  SET(PROJECT_LIBS psapi dfhack-md5 dfhack-tinyxml dfhack-tinythread)
++  SET(PROJECT_LIBS psapi dfhack-md5 tinyxml dfhack-tinythread)
+ ENDIF()
+ 
+ ADD_LIBRARY(dfhack-version STATIC DFHackVersion.cpp)
+diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
+index 9781401..ece508c 100644
+--- a/plugins/CMakeLists.txt
++++ b/plugins/CMakeLists.txt
+@@ -69,11 +69,11 @@ STRING(REPLACE ".proto" ".pb.h" PROJECT_PROTO_HDRS "${PROJECT_PROTOS}")
+ 
+ ADD_CUSTOM_COMMAND(
+     OUTPUT ${PROJECT_PROTO_SRCS} ${PROJECT_PROTO_HDRS}
+-    COMMAND protoc-bin -I=${dfhack_SOURCE_DIR}/library/proto/
++    COMMAND protoc -I=${dfhack_SOURCE_DIR}/library/proto/
+                        -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/
+             --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/proto/
+             ${PROJECT_PROTOS}
+-    DEPENDS protoc-bin ${PROJECT_PROTOS}
++    DEPENDS ${PROJECT_PROTOS}
+ )
+ add_custom_target(generate_proto DEPENDS ${PROJECT_PROTO_SRCS} ${PROJECT_PROTO_HDRS})
+ 
+diff --git a/plugins/mapexport/CMakeLists.txt b/plugins/mapexport/CMakeLists.txt
+index 429507a..7e2390a 100644
+--- a/plugins/mapexport/CMakeLists.txt
++++ b/plugins/mapexport/CMakeLists.txt
+@@ -32,8 +32,8 @@ LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS})
+ #Generate sources from our proto files and store them in the source tree
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${PROJECT_PROTO_SRCS} ${PROJECT_PROTO_HDRS}
+-COMMAND protoc-bin -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/ --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/proto/ ${PROJECT_PROTOS}
+-DEPENDS protoc-bin ${PROJECT_PROTOS}
++COMMAND protoc -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/ --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/proto/ ${PROJECT_PROTOS}
++DEPENDS ${PROJECT_PROTOS}
+ )
+ 
+ IF(WIN32)
+diff --git a/plugins/stockpiles/CMakeLists.txt b/plugins/stockpiles/CMakeLists.txt
+index 713c3d6..dd2d4cb 100644
+--- a/plugins/stockpiles/CMakeLists.txt
++++ b/plugins/stockpiles/CMakeLists.txt
+@@ -33,8 +33,8 @@ LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS})
+ #Generate sources from our proto files and store them in the source tree
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${PROJECT_PROTO_SRCS} ${PROJECT_PROTO_HDRS}
+-COMMAND protoc-bin -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/ --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/proto/ ${PROJECT_PROTOS}
+-DEPENDS protoc-bin ${PROJECT_PROTOS}
++COMMAND protoc -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/ --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/proto/ ${PROJECT_PROTOS}
++DEPENDS ${PROJECT_PROTOS}
+ )
+ 
+ IF(WIN32)
+-- 
+2.6.3
+
diff --git a/pkgs/games/dwarf-fortress/dwarf-fortress-hacked.in b/pkgs/games/dwarf-fortress/dwarf-fortress-hacked.in
deleted file mode 100644
index 027720fc378..00000000000
--- a/pkgs/games/dwarf-fortress/dwarf-fortress-hacked.in
+++ /dev/null
@@ -1,13 +0,0 @@
-#!@stdenv_shell@
-
-data_dir=${XDG_DATA_HOME:-$HOME/.local/share}/df_linux
-pkg_dir=@prefix@/share/df_linux
-
-. $pkg_dir/shell/install-df-data-to-home.sh
-. $pkg_dir/shell/install-dfhack-data-to-home.sh
-. $pkg_dir/shell/install-df-data-content-to-home.sh
-. $pkg_dir/shell/export-libs.sh
-. $pkg_dir/shell/export-workaround.sh
-
-cd "$data_dir"
-exec ./dfhack "$@"
diff --git a/pkgs/games/dwarf-fortress/dwarf-fortress.in b/pkgs/games/dwarf-fortress/dwarf-fortress.in
deleted file mode 100644
index db06d34efd0..00000000000
--- a/pkgs/games/dwarf-fortress/dwarf-fortress.in
+++ /dev/null
@@ -1,14 +0,0 @@
-#!@stdenv_shell@
-
-set -ex
-
-data_dir=${XDG_DATA_HOME:-$HOME/.local/share}/df_linux
-pkg_dir=@prefix@/share/df_linux
-
-. $pkg_dir/shell/install-df-data-to-home.sh
-. $pkg_dir/shell/install-df-data-content-to-home.sh
-. $pkg_dir/shell/export-libs.sh
-. $pkg_dir/shell/export-workaround.sh
-
-cd $data_dir
-$pkg_dir/libs/Dwarf_Fortress "$@"
diff --git a/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix b/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix
new file mode 100644
index 00000000000..07714168e0e
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix
@@ -0,0 +1,40 @@
+{ stdenv, fetchFromGitHub, coreutils, qt4, texlive }:
+
+let
+  version = "36.0.0";
+in
+stdenv.mkDerivation {
+  name = "dwarf-therapist-original-${version}";
+
+  src = fetchFromGitHub {
+    owner = "splintermind";
+    repo = "Dwarf-Therapist";
+    rev = "v${version}";
+    sha256 = "08xjawb25sibkkfqwd4mlq73dgmgc6lxbbd673rx7yhrsjh4z4h3";
+  };
+
+  outputs = [ "out" "layouts" ];
+  buildInputs = [ qt4 ];
+  nativeBuildInputs = [ texlive ];
+
+  enableParallelBuilding = false;
+
+  configurePhase = ''
+    qmake PREFIX=$out
+  '';
+
+  # Move layout files so they cannot be found by Therapist
+  postInstall = ''
+    mkdir -p $layouts
+    mv $out/share/dwarftherapist/memory_layouts/* $layouts
+    rmdir $out/share/dwarftherapist/memory_layouts
+  '';
+
+  meta = {
+    description = "Tool to manage dwarves in in a running game of Dwarf Fortress";
+    maintainers = with stdenv.lib.maintainers; [ the-kenny abbradar ];
+    license = stdenv.lib.licenses.mit;
+    platforms = stdenv.lib.platforms.linux;
+    homepage = https://code.google.com/r/splintermind-attributes/;
+  };
+}
diff --git a/pkgs/games/dwarf-fortress/dwarf-therapist/wrapper.nix b/pkgs/games/dwarf-fortress/dwarf-therapist/wrapper.nix
new file mode 100644
index 00000000000..a16c1284a67
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/dwarf-therapist/wrapper.nix
@@ -0,0 +1,43 @@
+{ buildEnv, lib, dwarf-therapist-original, dwarf-fortress-original, makeWrapper }:
+
+let
+  df = dwarf-fortress-original;
+  dt = dwarf-therapist-original;
+  inifile = "linux/v0${df.baseVersion}.${df.patchVersion}.ini";
+  dfHashFile = "${df}/hash.md5";
+
+in buildEnv {
+  name = "dwarf-therapist-${lib.getVersion dt}";
+
+  paths = [ dt ];
+
+  buildInputs = [ makeWrapper ];
+
+  postBuild = ''
+    # DwarfTherapist assumes it's run in $out/share/dwarftherapist and
+    # therefore uses many relative paths.
+    rm $out/bin
+    mkdir $out/bin
+    makeWrapper ${dt}/bin/DwarfTherapist $out/bin/DwarfTherapist \
+      --run "cd $out/share/dwarftherapist"
+
+    # Fix checksum of memory access directives. We really need #4621 fixed!
+    recreate_dir() {
+      rm "$out/$1"
+      mkdir -p "$out/$1"
+      for i in "${dt}/$1/"*; do
+        ln -s "$i" "$out/$1"
+      done
+    }
+
+    recreate_dir share
+    recreate_dir share/dwarftherapist
+    mkdir -p $out/share/dwarftherapist/memory_layouts/linux
+    origmd5=$(cat "${dfHashFile}.orig" | cut -c1-8)
+    patchedmd5=$(cat "${dfHashFile}" | cut -c1-8)
+    substitute \
+      ${dt.layouts}/${inifile} \
+      $out/share/dwarftherapist/memory_layouts/${inifile} \
+      --replace "$origmd5" "$patchedmd5"
+  '';
+}
diff --git a/pkgs/games/dwarf-fortress/export-libs.sh.in b/pkgs/games/dwarf-fortress/export-libs.sh.in
deleted file mode 100644
index 453295ca6dd..00000000000
--- a/pkgs/games/dwarf-fortress/export-libs.sh.in
+++ /dev/null
@@ -1,12 +0,0 @@
-export LD_LIBRARY_PATH=\
-@stdenv_cc@/lib:\
-@SDL@/lib:\
-@SDL_image@/lib/:\
-@SDL_ttf@/lib/:\
-@gtk2@/lib/:\
-@glib@/lib/:\
-@mesa@/lib/:\
-@openal@/lib/:\
-@libsndfile@/lib:\
-@zlib@/lib:\
-$data_dir/df_linux/libs/
diff --git a/pkgs/games/dwarf-fortress/export-workaround.sh b/pkgs/games/dwarf-fortress/export-workaround.sh
deleted file mode 100644
index 716d171625c..00000000000
--- a/pkgs/games/dwarf-fortress/export-workaround.sh
+++ /dev/null
@@ -1 +0,0 @@
-export SDL_DISABLE_LOCK_KEYS=1  # Work around for bug in Debian/Ubuntu SDL patch.
diff --git a/pkgs/games/dwarf-fortress/game.nix b/pkgs/games/dwarf-fortress/game.nix
new file mode 100644
index 00000000000..7e0c1b34af7
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/game.nix
@@ -0,0 +1,48 @@
+{ stdenv, lib, fetchurl
+, SDL, dwarf-fortress-unfuck
+}:
+
+let
+  baseVersion = "42";
+  patchVersion = "05";
+  dfVersion = "0.${baseVersion}.${patchVersion}";
+  libpath = lib.makeLibraryPath [ stdenv.cc.cc stdenv.glibc dwarf-fortress-unfuck SDL ];
+
+in
+
+assert dwarf-fortress-unfuck.dfVersion == dfVersion;
+
+stdenv.mkDerivation {
+  name = "dwarf-fortress-original-${dfVersion}";
+
+  src = fetchurl {
+    url = "http://www.bay12games.com/dwarves/df_${baseVersion}_${patchVersion}_linux.tar.bz2";
+    sha256 = "0g7r0v2lsqj9ryxh12q8yrk96bgs00rf2ncw228cwwqgmps3xcws";
+  };
+
+  installPhase = ''
+    mkdir -p $out
+    cp -r * $out
+    rm $out/libs/lib*
+
+    # Store the original hash
+    md5sum $out/libs/Dwarf_Fortress | awk '{ print $1 }' > $out/hash.md5.orig
+
+    patchelf \
+      --set-interpreter $(cat ${stdenv.cc}/nix-support/dynamic-linker) \
+      --set-rpath "${libpath}" \
+      $out/libs/Dwarf_Fortress
+
+    # Store the new hash
+    md5sum $out/libs/Dwarf_Fortress | awk '{ print $1 }' > $out/hash.md5
+  '';
+
+  passthru = { inherit baseVersion patchVersion dfVersion; };
+
+  meta = {
+    description = "A single-player fantasy game with a randomly generated adventure world";
+    homepage = http://www.bay12games.com/dwarves;
+    license = lib.licenses.unfreeRedistributable;
+    maintainers = with lib.maintainers; [ a1russell robbinch roconnor the-kenny abbradar ];
+  };
+}
diff --git a/pkgs/games/dwarf-fortress/install-df-data-content-to-home.sh b/pkgs/games/dwarf-fortress/install-df-data-content-to-home.sh
deleted file mode 100644
index 600af677322..00000000000
--- a/pkgs/games/dwarf-fortress/install-df-data-content-to-home.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-for link in announcement art dipscript help index initial_movies movies shader.fs shader.vs sound speech; do
-  cp -r $pkg_dir/data/$link "$data_dir/data/$link"
-  chmod -R u+rw "$data_dir/data/$link"
-done
diff --git a/pkgs/games/dwarf-fortress/install-df-data-to-home.sh b/pkgs/games/dwarf-fortress/install-df-data-to-home.sh
deleted file mode 100644
index 42c8c464809..00000000000
--- a/pkgs/games/dwarf-fortress/install-df-data-to-home.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-mkdir -p $data_dir
-if [[ $(readlink $data_dir/raw) != "$pkg_dir/raw" ]]; then
-  rm -f $data_dir/raw
-  ln -s $pkg_dir/raw $data_dir/raw
-fi
-if [[ $(readlink $data_dir/libs) != "$pkg_dir/libs" ]]; then
-  rm -f $data_dir/libs
-  ln -s $pkg_dir/libs $data_dir/libs
-fi
-mkdir -p "$data_dir/data"
-cp -rn $pkg_dir/data/init $data_dir/data/init
-chmod -R u+rw $data_dir/data/init
diff --git a/pkgs/games/dwarf-fortress/install-dfhack-data-to-home.sh b/pkgs/games/dwarf-fortress/install-dfhack-data-to-home.sh
deleted file mode 100644
index 9d316fde949..00000000000
--- a/pkgs/games/dwarf-fortress/install-dfhack-data-to-home.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-if [[ $(readlink $data_dir/hack) != "$pkg_dir/hack" ]]; then
-  rm -f $data_dir/hack
-  ln -s $pkg_dir/hack $data_dir/hack
-fi
-if [[ $(readlink $data_dir/dfhack) != "$pkg_dir/dfhack" ]]; then
-  rm -f $data_dir/dfhack
-  ln -s $pkg_dir/dfhack $data_dir/dfhack
-fi
-if [[ $(readlink $data_dir/dfhack.init-example) != "$pkg_dir/dfhack.init-example" ]]; then
-  rm -f $data_dir/dfhack.init-example
-  ln -s $pkg_dir/dfhack.init-example $data_dir/dfhack.init-example
-fi
-if [[ $(readlink $data_dir/dfhack-run) != "$pkg_dir/dfhack-run" ]]; then
-  rm -f $data_dir/dfhack-run
-  ln -s $pkg_dir/dfhack-run $data_dir/dfhack-run
-fi
diff --git a/pkgs/games/dwarf-fortress/themes/phoebus.nix b/pkgs/games/dwarf-fortress/themes/phoebus.nix
new file mode 100644
index 00000000000..2183a6245c0
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/themes/phoebus.nix
@@ -0,0 +1,33 @@
+{ stdenv, fetchFromGitHub }:
+
+# On upgrade check https://github.com/fricy/Phoebus/blob/master/manifest.json
+# for compatibility information.
+
+stdenv.mkDerivation {
+  name = "phoebus-theme-20160118";
+
+  src = fetchFromGitHub {
+    owner = "fricy";
+    repo = "Phoebus";
+    rev = "2c5777b0f307b1d752a8a484c6a05b67531c84a9";
+    sha256 = "0a5ixm181wz7crr3rpa2mh0drb371j5hvizqninvdnhah2mypz8v";
+  };
+
+  installPhase = ''
+    mkdir $out
+    cp -r data raw $out
+  '';
+
+  passthru.dfVersion = "0.42.05";
+
+  preferLocalBuild = true;
+
+  meta = with stdenv.lib; {
+    description = "Phoebus graphics set for Dwarf Fortress";
+    homepage = "http://www.bay12forums.com/smf/index.php?topic=137096.0";
+    platforms = platforms.all;
+    maintainers = with maintainers; [ a1russell abbradar ];
+    # https://github.com/fricy/Phoebus/issues/5
+    license = licenses.free;
+  };
+}
diff --git a/pkgs/games/dwarf-fortress/unfuck.nix b/pkgs/games/dwarf-fortress/unfuck.nix
new file mode 100644
index 00000000000..92f4a954330
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/unfuck.nix
@@ -0,0 +1,41 @@
+{ stdenv, fetchgit, cmake
+, mesa, SDL, SDL_image, SDL_ttf, glew, openalSoft
+, ncurses, glib, gtk2, libsndfile
+}:
+
+stdenv.mkDerivation {
+  name = "dwarf_fortress_unfuck-20160118";
+
+  src = fetchgit {
+    url = "https://github.com/svenstaro/dwarf_fortress_unfuck";
+    rev = "9a796c6d3cd7d41784e9d1d22a837a1ee0ff8553";
+    sha256 = "0ibxdn684zpk3v2gigardq6z9mydc2s9hns8hlxjyyyhnk1ar61g";
+  };
+
+  cmakeFlags = [
+    "-DGTK2_GLIBCONFIG_INCLUDE_DIR=${glib}/lib/glib-2.0/include"
+    "-DGTK2_GDKCONFIG_INCLUDE_DIR=${gtk2}/lib/gtk-2.0/include"
+  ];
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [
+    mesa SDL SDL_image SDL_ttf glew openalSoft
+    ncurses gtk2 libsndfile
+  ];
+
+  installPhase = ''
+    install -D -m755 ../build/libgraphics.so $out/lib/libgraphics.so
+  '';
+
+  enableParallelBuilding = true;
+
+  passthru.dfVersion = "0.42.05";
+
+  meta = with stdenv.lib; {
+    description = "Unfucked multimedia layer for Dwarf Fortress";
+    homepage = https://github.com/svenstaro/dwarf_fortress_unfuck;
+    license = licenses.free;
+    platforms = [ "i686-linux" ];
+    maintainers = with maintainers; [ abbradar ];
+  };
+}
diff --git a/pkgs/games/dwarf-fortress/wrapper/default.nix b/pkgs/games/dwarf-fortress/wrapper/default.nix
new file mode 100644
index 00000000000..5493cdb3faf
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/wrapper/default.nix
@@ -0,0 +1,68 @@
+{ stdenv, lib, buildEnv, dwarf-fortress-original, substituteAll
+, enableDFHack ? false, dfhack
+, themes ? {}
+, theme ? null
+}:
+
+let
+  ptheme =
+    if builtins.isString theme
+    then builtins.getAttr theme themes
+    else theme;
+
+  # These are in inverse order for first packages to override the next ones.
+  pkgs = lib.optional (theme != null) ptheme
+         ++ lib.optional enableDFHack dfhack
+         ++ [ dwarf-fortress-original ];
+
+  env = buildEnv {
+    name = "dwarf-fortress-env-${dwarf-fortress-original.dfVersion}";
+    paths = pkgs;
+    ignoreCollisions = true;
+    postBuild = lib.optionalString enableDFHack ''
+      # #4621
+      if [ -L "$out/hack" ]; then
+        rm $out/hack
+        mkdir $out/hack
+        for i in ${dfhack}/hack/*; do
+          ln -s $i $out/hack
+        done
+      fi
+      rm $out/hack/symbols.xml
+      substitute ${dfhack}/hack/symbols.xml $out/hack/symbols.xml \
+        --replace $(cat ${dwarf-fortress-original}/hash.md5.orig) \
+                  $(cat ${dwarf-fortress-original}/hash.md5)
+    '';
+  };
+in
+
+assert lib.all (x: x.dfVersion == dwarf-fortress-original.dfVersion) pkgs;
+
+stdenv.mkDerivation rec {
+  name = "dwarf-fortress-${dwarf-fortress-original.dfVersion}";
+
+  dfInit = substituteAll {
+    name = "dwarf-fortress-init";
+    src = ./dwarf-fortress-init.in;
+    inherit env;
+  };
+
+  runDF = ./dwarf-fortress.in;
+  runDFHack = ./dfhack.in;
+
+  buildCommand = ''
+    mkdir -p $out/bin
+
+    substitute $runDF $out/bin/dwarf-fortress \
+      --subst-var-by stdenv_shell ${stdenv.shell} \
+      --subst-var dfInit
+    chmod 755 $out/bin/dwarf-fortress
+  '' + lib.optionalString enableDFHack ''
+    substitute $runDFHack $out/bin/dfhack \
+      --subst-var-by stdenv_shell ${stdenv.shell} \
+      --subst-var dfInit
+    chmod 755 $out/bin/dfhack
+  '';
+
+  preferLocalBuild = true;
+}
diff --git a/pkgs/games/dwarf-fortress/wrapper/dfhack.in b/pkgs/games/dwarf-fortress/wrapper/dfhack.in
new file mode 100644
index 00000000000..d53769ca4b6
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/wrapper/dfhack.in
@@ -0,0 +1,11 @@
+#!@stdenv_shell@ -e
+
+source @dfInit@
+
+for i in dfhack.init-example dfhack-config/default hack/*; do
+  update_path "$i"
+done
+
+cd "$DF_DIR"
+LD_LIBRARY_PATH="$env_dir/hack/libs:$env_dir/hack:$LD_LIBRARY_PATH" \
+  LD_PRELOAD=$env_dir/hack/libdfhack.so exec $env_dir/libs/Dwarf_Fortress "$@"
diff --git a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in
new file mode 100644
index 00000000000..1fd6178895d
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in
@@ -0,0 +1,41 @@
+shopt -s extglob
+
+[ -z "$DF_DIR" ] && DF_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/df_linux"
+env_dir="@env@"
+
+update_path() {
+  local path="$1"
+
+  mkdir -p "$DF_DIR/$(dirname "$path")"
+  # If user has replaced these data directories, let them stay.
+  if [ ! -e "$DF_DIR/$path" ] || [ -L "$DF_DIR/$path" ]; then
+    rm -f "$DF_DIR/$path"
+    ln -s "$env_dir/$path" "$DF_DIR/$path"
+  fi
+}
+
+forcecopy_path() {
+  local path="$1"
+
+  mkdir -p "$DF_DIR/$(dirname "$path")"
+  rm -rf "$DF_DIR/$path"
+  cp -rL --no-preserve=all "$env_dir/$path" "$DF_DIR/$path"
+}
+
+mkdir -p "$DF_DIR"
+
+cat <<EOF >&2
+Using $DF_DIR as Dwarf Fortress overlay directory.
+If you do any changes in it, don't forget to clean it when updating the game version!
+We try to detect changes based on data directories being symbolic links -- keep this in mind.
+
+EOF
+
+cd "$env_dir"
+for i in data/init/* data/!(init|index|announcement) raw; do
+  update_path "$i"
+done
+
+forcecopy_path data/index
+# For some reason, it's needed to be writable...
+forcecopy_path data/announcement
diff --git a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in
new file mode 100644
index 00000000000..f405f1b0e39
--- /dev/null
+++ b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in
@@ -0,0 +1,6 @@
+#!@stdenv_shell@ -e
+
+source @dfInit@
+
+cd "$DF_DIR"
+exec "$env_dir/libs/Dwarf_Fortress" "$@"