about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--pkgs/games/gog/default.nix1
-rw-r--r--pkgs/games/gog/homm3/default.nix97
-rw-r--r--pkgs/games/gog/homm3/launcher-execl.patch36
3 files changed, 134 insertions, 0 deletions
diff --git a/pkgs/games/gog/default.nix b/pkgs/games/gog/default.nix
index 1ef58c30..122a8365 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 { };
+    homm3 = callPackage ./homm3 {};
     overload = callPackage ./overload.nix {};
     party-hard = callPackage ./party-hard.nix {};
     satellite-reign = callPackage ./satellite-reign.nix {};
diff --git a/pkgs/games/gog/homm3/default.nix b/pkgs/games/gog/homm3/default.nix
new file mode 100644
index 00000000..5aecb8f2
--- /dev/null
+++ b/pkgs/games/gog/homm3/default.nix
@@ -0,0 +1,97 @@
+{ stdenv, lib, buildSandbox, fetchGog, runCommand, makeWrapper, fetchFromGitHub
+, cmake, pkgconfig, python3, boost, zlib, minizip, qt5
+, SDL2, SDL2_image, SDL2_mixer, SDL2_ttf
+, innoextract, parallel, ffmpeg
+}:
+
+let
+  data = runCommand "homm3-complete-data" rec {
+    version = "4.0";
+
+    # We need a newer version that 1.7, because GOG uses a newer archive
+    # format.
+    nativeBuildInputs = lib.singleton (innoextract.overrideAttrs (drv: {
+      src = fetchFromGitHub {
+        owner = "dscharrer";
+        repo = "innoextract";
+        rev = "4c61bc4da822fc89f2e05bdb2c45e6c4dd7a3673";
+        sha256 = "197pr7dzlza4isssvhqhvnrr7wzc9c4b3wnnp03sxpmhviyidln1";
+      };
+    })) ++ [ parallel ffmpeg ];
+
+    data = fetchGog {
+      name = "setup_homm_3_complete_${version}.bin";
+      productId = 1207658787;
+      downloadName = "en1installer1";
+      sha256 = "1wfly3024yi64kaczfdca4wx5g09053dpc1gwp08w637833n4kq4";
+    };
+
+    setup = fetchGog {
+      name = "setup_homm_3_complete_${version}.exe";
+      productId = 1207658787;
+      downloadName = "en1installer0";
+      sha256 = "1cwr28ml9z3iq6q9z1vs1jkbnjjrkv2m39bhqw78a5hvj43mgxza";
+    };
+  } ''
+    ln -s "$data" archive-1.bin
+    ln -s "$setup" archive.exe
+    innoextract -L -I Data -I Maps -I Mp3 archive.exe
+    mkdir -p "$out/music"
+    parallel -v ffmpeg -hide_banner -loglevel warning -i {} -acodec libvorbis \
+      "$out/music/{/.}.ogg" ::: mp3/*.mp3
+    mv -t "$out" data maps
+  '';
+
+  engine = stdenv.mkDerivation rec {
+    name = "vcmi-${version}";
+    version = "20190609";
+
+    src = fetchFromGitHub {
+      owner = "vcmi";
+      repo = "vcmi";
+      rev = "e7bced112cf36007da8f418ba3313d2dd4b3e045";
+      sha256 = "0qk0mpz3amg2kw5m99bk3qi19rwcwjj6s1lclby1ws0v8nxh2cmb";
+      fetchSubmodules = true;
+    };
+
+    inherit data;
+
+    patches = [ ./launcher-execl.patch ];
+
+    postPatch = ''
+      find -type f -name '*.cpp' -exec sed -i -e '/^ *# *include/ {
+        s!["<]SDL_\(ttf\|image\|mixer\)\.h[">]!<SDL2/SDL_\1.h>!
+      }' {} +
+
+      sed -i -e 's/"Mp3"/"music"/' config/filesystem.json
+    '';
+
+    cmakeFlags = [ "-DCMAKE_INSTALL_LIBDIR=lib" "-DENABLE_TEST=0" ];
+    enableParallelBuilding = true;
+    nativeBuildInputs = [ cmake pkgconfig python3 makeWrapper ];
+    buildInputs = [
+      boost zlib minizip SDL2 SDL2_image SDL2_mixer SDL2_ttf ffmpeg
+      qt5.qtbase
+    ];
+    postInstall = let
+      inherit (qt5.qtbase) qtPluginPrefix;
+      qtPlugins = "${qt5.qtbase}/${qtPluginPrefix}";
+    in ''
+      rm "$out/bin/vcmibuilder"
+      for i in "$out/bin/"*; do
+        rpath="$(patchelf --print-rpath "$i")"
+        patchelf --set-rpath "$out/lib/vcmi:$rpath" "$i"
+      done
+
+      wrapProgram "$out/bin/vcmilauncher" \
+        --suffix QT_PLUGIN_PATH : ${lib.escapeShellArg qtPlugins}
+      cp -rst "$out/share/vcmi" "$data"/*
+    '';
+    dontStrip = true;
+  };
+
+in buildSandbox engine {
+  allowBinSh = true;
+  paths.required = [ "$XDG_DATA_HOME/vcmi" "$XDG_CONFIG_HOME/vcmi" ];
+  paths.runtimeVars = [ "LD_LIBRARY_PATH" "LOCALE_ARCHIVE" ];
+}
diff --git a/pkgs/games/gog/homm3/launcher-execl.patch b/pkgs/games/gog/homm3/launcher-execl.patch
new file mode 100644
index 00000000..fae0fa80
--- /dev/null
+++ b/pkgs/games/gog/homm3/launcher-execl.patch
@@ -0,0 +1,36 @@
+diff --git a/launcher/mainwindow_moc.cpp b/launcher/mainwindow_moc.cpp
+index a07774ed2..3275af71a 100644
+--- a/launcher/mainwindow_moc.cpp
++++ b/launcher/mainwindow_moc.cpp
+@@ -11,7 +11,7 @@
+ #include "mainwindow_moc.h"
+ #include "ui_mainwindow_moc.h"
+ 
+-#include <QProcess>
++#include <unistd.h>
+ #include <QDir>
+ 
+ #include "../lib/CConfigHandler.h"
+@@ -77,19 +77,11 @@ void MainWindow::on_startGameButton_clicked()
+ 
+ void MainWindow::startExecutable(QString name)
+ {
+-	QProcess process;
+-
+-	// Start the executable
+-	if(process.startDetached(name))
+-	{
+-		close(); // exit launcher
+-	}
+-	else
+-	{
++	if (execl(name.toLatin1().data(), "vcmiclient", nullptr) == -1) {
++		QString msg("Failed to start %1\nReason: %2");
+ 		QMessageBox::critical(this,
+ 		                      "Error starting executable",
+-		                      "Failed to start " + name + "\n"
+-		                      "Reason: " + process.errorString(),
++							  msg.arg(name).arg(strerror(errno)),
+ 		                      QMessageBox::Ok,
+ 		                      QMessageBox::Ok);
+ 		return;