diff options
Diffstat (limited to 'pkgs/games/gog')
-rw-r--r-- | pkgs/games/gog/albion/config.patch | 19 | ||||
-rw-r--r-- | pkgs/games/gog/albion/default.nix | 183 | ||||
-rw-r--r-- | pkgs/games/gog/albion/error-log-stderr.patch | 100 | ||||
-rw-r--r-- | pkgs/games/gog/albion/scons.patch | 74 | ||||
-rw-r--r-- | pkgs/games/gog/albion/sdl2.patch | 60 | ||||
-rw-r--r-- | pkgs/games/gog/albion/xdg-paths.patch | 259 | ||||
-rw-r--r-- | pkgs/games/gog/default.nix | 2 |
7 files changed, 697 insertions, 0 deletions
diff --git a/pkgs/games/gog/albion/config.patch b/pkgs/games/gog/albion/config.patch new file mode 100644 index 00000000..6bac229c --- /dev/null +++ b/pkgs/games/gog/albion/config.patch @@ -0,0 +1,19 @@ +diff --git a/games/Albion/release/linux/Albion.cfg b/games/Albion/release/linux/Albion.cfg +index 50d4327..8c901f1 100644 +--- a/games/Albion/release/linux/Albion.cfg ++++ b/games/Albion/release/linux/Albion.cfg +@@ -50,11 +50,11 @@ Audio_MIDI_Device= + # - this setting renders the 3d part of the game in the native resolution instead of rendering it in the original resolution and then scaling it + # - there are some minor issues, read the readme for more information + # Display_MouseCursor=normal/minimal/none - shape of SDL mouse cursor in window mode +-Display_ScaledWidth=720 +-Display_ScaledHeight=480 ++Display_ScaledWidth=1280 ++Display_ScaledHeight=960 + Display_Fullscreen=no + Display_Enhanced_3D_Rendering=on +-Display_MouseCursor=normal ++Display_MouseCursor=none + + + # Screenshot settings 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" ]; +} diff --git a/pkgs/games/gog/albion/error-log-stderr.patch b/pkgs/games/gog/albion/error-log-stderr.patch new file mode 100644 index 00000000..9819f1f1 --- /dev/null +++ b/pkgs/games/gog/albion/error-log-stderr.patch @@ -0,0 +1,100 @@ +diff --git a/games/Albion/SR-Main/Albion-proc-vfs.c b/games/Albion/SR-Main/Albion-proc-vfs.c +index c3d2d4f..faa90e7 100644 +--- a/games/Albion/SR-Main/Albion-proc-vfs.c ++++ b/games/Albion/SR-Main/Albion-proc-vfs.c +@@ -232,6 +232,8 @@ FILE *Game_fopen(const char *filename, const char *mode) + fprintf(stderr, "fopen: original name: %s\n", filename); + #endif + ++ if (strcasecmp(filename, "error.log") == 0) return stderr; ++ + vfs_err = vfs_get_real_name(filename, (char *) &temp_str, &realdir); + + #if defined(__DEBUG__) +@@ -260,6 +262,8 @@ int Game_open(const char *pathname, int flags, mode_t mode) + fprintf(stderr, "open: original name: %s\n", pathname); + #endif + ++ if (strcasecmp(pathname, "error.log") == 0) return STDERR_FILENO; ++ + vfs_err = vfs_get_real_name(pathname, (char *) &temp_str, &realdir); + + #if defined(__DEBUG__) +@@ -726,6 +730,16 @@ int Game_closedir(struct watcom_dirent *dirp) + return 0; + } + ++int Game_close(int fd) ++{ ++ return fd == STDERR_FILENO ? 0 : close(fd); ++} ++ ++int Game_fclose(FILE *stream) ++{ ++ return stream == stderr ? 0 : fclose(stream); ++} ++ + static void Conv_find(struct watcom_find_t *buffer, struct watcom_dirent *direntp) + { + // file attributes +diff --git a/games/Albion/SR-Main/Albion-proc-vfs.h b/games/Albion/SR-Main/Albion-proc-vfs.h +index 0cf4491..2e16671 100644 +--- a/games/Albion/SR-Main/Albion-proc-vfs.h ++++ b/games/Albion/SR-Main/Albion-proc-vfs.h +@@ -110,6 +110,8 @@ extern int Game_rename(const char *oldpath, const char *newpath); + extern struct watcom_dirent *Game_opendir(const char *dirname); + extern struct watcom_dirent *Game_readdir(struct watcom_dirent *dirp); + extern int Game_closedir(struct watcom_dirent *dirp); ++extern int Game_close(int fd); ++extern int Game_fclose(FILE *stream); + extern uint32_t Game_dos_findfirst(const char *path, const uint32_t attributes, struct watcom_find_t *buffer); + extern uint32_t Game_dos_findnext(struct watcom_find_t *buffer); + extern uint32_t Game_dos_findclose(struct watcom_find_t *buffer); +diff --git a/games/Albion/SR-Main/x86/SR-asm-calls.asm b/games/Albion/SR-Main/x86/SR-asm-calls.asm +index 3cb2cc8..e1741dc 100644 +--- a/games/Albion/SR-Main/x86/SR-asm-calls.asm ++++ b/games/Albion/SR-Main/x86/SR-asm-calls.asm +@@ -71,6 +71,8 @@ + %define Game_chdir _Game_chdir + %define close _close + %define Game_closedir _Game_closedir ++ %define Game_close _Game_close ++ %define Game_fclose _Game_fclose + %define ctime _ctime + %define Game_dos_findclose _Game_dos_findclose + %define Game_dos_findnext _Game_dos_findnext +@@ -171,14 +173,14 @@ extern Game_WaitFor2ndVerticalRetrace + ; 1 param + extern asctime + extern Game_chdir +-extern close ++extern Game_close + extern Game_closedir + extern ctime + extern Game_dos_findclose + extern Game_dos_findnext + extern Game_dos_getvect + extern Game_ExitMain_Asm +-extern fclose ++extern Game_fclose + extern Game_filelength + extern free + extern ftime +@@ -798,7 +800,7 @@ SR_j___close: + + ; eax = int handle + +- Game_Call_Asm_Reg1 close,'get_errno_val' ++ Game_Call_Asm_Reg1 Game_close,'get_errno_val' + + ; end procedure SR___close + +@@ -875,7 +877,7 @@ SR_fclose: + + ; eax = FILE *fp + +- Game_Call_Asm_Reg1 fclose,'get_errno_val' ++ Game_Call_Asm_Reg1 Game_fclose,'get_errno_val' + + ; end procedure SR_fclose + diff --git a/pkgs/games/gog/albion/scons.patch b/pkgs/games/gog/albion/scons.patch new file mode 100644 index 00000000..5a1c0d7b --- /dev/null +++ b/pkgs/games/gog/albion/scons.patch @@ -0,0 +1,74 @@ +diff --git a/SR/SConstruct b/SR/SConstruct +index 2fb2874..f2fb527 100644 +--- a/SR/SConstruct ++++ b/SR/SConstruct +@@ -20,6 +20,8 @@ + # SOFTWARE. + # + ++import os ++ + udis86_path = './udis86-1.6/' + + # set help text +@@ -30,7 +32,8 @@ Help(vars.GenerateHelpText(env)) + debug = env['debug'] + + # default settings +-env = Environment(CCFLAGS = '-O2', ++env = Environment(ENV = os.environ, ++ CCFLAGS = '-O2', + CPPPATH = '.', + INCPREFIX = '-I' + udis86_path, + LIBPATH = 'libudis86', +diff --git a/games/Albion/SR-Main/SConstruct b/games/Albion/SR-Main/SConstruct +index 96bbefb..6743470 100644 +--- a/games/Albion/SR-Main/SConstruct ++++ b/games/Albion/SR-Main/SConstruct +@@ -50,12 +50,14 @@ Help(vars.GenerateHelpText(env)) + if device == 'pc-linux': + # default settings + if sdl2 > 0: +- env = Environment(CCFLAGS = '-m32 -O2 -DUSE_SDL2', ++ env = Environment(ENV = os.environ, ++ CCFLAGS = '-m32 -O2 -DUSE_SDL2', + LINKFLAGS = '-m32', + LIBS = ['SDL2_mixer', 'SDL2', 'pthread', 'm', 'dl'] + ) + else: +- env = Environment(CCFLAGS = '-m32 -O2 -DALLOW_OPENGL', ++ env = Environment(ENV = os.environ, ++ CCFLAGS = '-m32 -O2 -DALLOW_OPENGL', + LINKFLAGS = '-m32', + LIBS = ['SDL_mixer', 'SDL', 'pthread', 'm', 'dl', 'GL'] + ) +diff --git a/games/Albion/SR-Main/x86/SConscript b/games/Albion/SR-Main/x86/SConscript +index c88c7e9..848efa8 100644 +--- a/games/Albion/SR-Main/x86/SConscript ++++ b/games/Albion/SR-Main/x86/SConscript +@@ -20,6 +20,7 @@ + # SOFTWARE. + # + ++import os + import re + + Import('device') +@@ -38,13 +39,13 @@ nasmscan = Scanner(function = nasmfile_scan, + SourceFileScanner.add_scanner('.asm', nasmscan) + + if device == 'pc-linux': +- env = Environment(tools=['nasm'], ASFLAGS = ' -felf -dELF -Ox -w+orphan-labels -w-number-overflow -ix86/') +- env2 = Environment(tools=['nasm'], ASFLAGS = ' -felf -dELF -O1 -w+orphan-labels -w-number-overflow -ix86/') ++ env = Environment(ENV=os.environ, tools=['nasm'], ASFLAGS = ' -felf -dELF -Ox -w+orphan-labels -w-number-overflow -ix86/') ++ env2 = Environment(ENV=os.environ, tools=['nasm'], ASFLAGS = ' -felf -dELF -O1 -w+orphan-labels -w-number-overflow -ix86/') + + obj = env2.Object('Albion-main_linux.asm') + else: +- env = Environment(tools=['nasm'], ASFLAGS = ' -fwin32 -Ox -w+orphan-labels -w-number-overflow -ix86/') +- env2 = Environment(tools=['nasm'], ASFLAGS = ' -fwin32 -O1 -w+orphan-labels -w-number-overflow -ix86/') ++ env = Environment(ENV=os.environ, tools=['nasm'], ASFLAGS = ' -fwin32 -Ox -w+orphan-labels -w-number-overflow -ix86/') ++ env2 = Environment(ENV=os.environ, tools=['nasm'], ASFLAGS = ' -fwin32 -O1 -w+orphan-labels -w-number-overflow -ix86/') + + obj = env2.Object('Albion-main.asm') + diff --git a/pkgs/games/gog/albion/sdl2.patch b/pkgs/games/gog/albion/sdl2.patch new file mode 100644 index 00000000..6b4bc93f --- /dev/null +++ b/pkgs/games/gog/albion/sdl2.patch @@ -0,0 +1,60 @@ +diff --git a/games/Albion/SR-Main/Albion-proc-events.c b/games/Albion/SR-Main/Albion-proc-events.c +index c323530..97eedd1 100644 +--- a/games/Albion/SR-Main/Albion-proc-events.c ++++ b/games/Albion/SR-Main/Albion-proc-events.c +@@ -893,19 +893,19 @@ void Game_ProcessKEvents(void) + else goto _after_switch1; + #endif + } +- else if ((cevent->key.keysym.unicode > 0) && (cevent->key.keysym.unicode < 128)) ++ else if ((cevent->key.keysym.sym > 0) && (cevent->key.keysym.sym < 128)) + { +- scancode = scancode_table[cevent->key.keysym.unicode]; +- ascii_code = cevent->key.keysym.unicode; ++ scancode = scancode_table[cevent->key.keysym.sym]; ++ ascii_code = cevent->key.keysym.sym; + } +- else if (cevent->key.keysym.unicode != 0) ++ else if (cevent->key.keysym.sym != 0) + { + scancode = 0; + ascii_code = 0; + + if ((ascii_code == 0) && (Albion_Font_Lang != AL_UNKNOWN)) + { +- switch (cevent->key.keysym.unicode) ++ switch (cevent->key.keysym.sym) + { + case 0x00E4: // ä + ascii_code = 0x84; +@@ -935,7 +935,7 @@ void Game_ProcessKEvents(void) + + if ((ascii_code == 0) && (Albion_Font_Lang == AL_ENG_FRE)) + { +- switch (cevent->key.keysym.unicode) ++ switch (cevent->key.keysym.sym) + { + case 0x00E9: // é + ascii_code = 0x82; +@@ -998,7 +998,7 @@ void Game_ProcessKEvents(void) + + if ((ascii_code == 0) && (Albion_Font_Lang == AL_CZE)) + { +- switch (cevent->key.keysym.unicode) ++ switch (cevent->key.keysym.sym) + { + case 0x00E9: // é + ascii_code = 0x82; +diff --git a/games/Albion/SR-Main/main.c b/games/Albion/SR-Main/main.c +index c9c3125..0d32bcb 100644 +--- a/games/Albion/SR-Main/main.c ++++ b/games/Albion/SR-Main/main.c +@@ -930,8 +930,6 @@ static void Game_Initialize2(void) + Init_Audio2(); + Init_Input2(); + +- SDL_EnableUNICODE(1); +- + Game_VideoAspectX = (360 << 16) / Picture_Width; + Game_VideoAspectY = (240 << 16) / Picture_Height; + diff --git a/pkgs/games/gog/albion/xdg-paths.patch b/pkgs/games/gog/albion/xdg-paths.patch new file mode 100644 index 00000000..13ba4a1c --- /dev/null +++ b/pkgs/games/gog/albion/xdg-paths.patch @@ -0,0 +1,259 @@ +diff --git a/games/Albion/SR-Main/virtualfs.c b/games/Albion/SR-Main/virtualfs.c +index 34e0544..7d3acec 100644 +--- a/games/Albion/SR-Main/virtualfs.c ++++ b/games/Albion/SR-Main/virtualfs.c +@@ -22,7 +22,9 @@ + * + */ + ++#define _GNU_SOURCE + #define _FILE_OFFSET_BITS 64 ++#include <fcntl.h> + #include <stdio.h> + #include <stdlib.h> + #include <malloc.h> +@@ -283,6 +285,177 @@ void vfs_visit_dir(file_entry *vdir) + vdir->dir_visited = 1; + } + ++#define CONCAT_ENV(path) \ ++ if (asprintf(&result, "%s/%s", env, path) == -1) { \ ++ perror("asprintf"); \ ++ exit(1); \ ++ } ++ ++#define DEFINE_XDG_GETTER(fun_name, envar, fallback) \ ++ static char *fun_name(void) { \ ++ const char *env; \ ++ static char *result = NULL; \ ++ if (result == NULL) { \ ++ if ((env = getenv(envar)) != NULL) { \ ++ CONCAT_ENV("albion"); \ ++ } else if ((env = getenv("HOME")) != NULL) { \ ++ CONCAT_ENV(fallback "/albion"); \ ++ } else { \ ++ fputs("Unable to determine " envar " or HOME.\n", stderr); \ ++ exit(1); \ ++ } \ ++ } \ ++ return result; \ ++ } ++ ++DEFINE_XDG_GETTER(getDataDir, "XDG_DATA_HOME", ".local/share"); ++DEFINE_XDG_GETTER(getConfigDir, "XDG_CONFIG_HOME", ".config"); ++ ++static int makeDirs(const char *path) ++{ ++ char *buf, *p; ++ ++ if (*path == '\0') ++ return 1; ++ ++ if ((buf = strdup(path)) == NULL) ++ return 1; ++ ++ for (p = buf + 1; *p != '\0'; p++) { ++ if (*p != '/') continue; ++ *p = '\0'; ++ mkdir(buf, 0777); ++ *p = '/'; ++ } ++ ++ mkdir(buf, 0777); ++ ++ free(buf); ++ return 0; ++} ++ ++typedef struct { ++ file_entry *dir; ++ const char *root; ++} unix_dir_cache_t; ++ ++unix_dir_cache_t *unixDirCache[100]; ++ ++static void setUnixDir(const char *root, file_entry **dir) ++{ ++ int i; ++ file_entry *newdir; ++ ++ if (dir == NULL) ++ return; ++ ++ for (i = 0; unixDirCache[i] != NULL; ++i) { ++ if (strcmp(unixDirCache[i]->root, root) == 0) { ++ *dir = unixDirCache[i]->dir; ++ return; ++ } ++ } ++ ++ if ((newdir = (file_entry *)malloc(sizeof(file_entry))) == NULL) ++ return; ++ ++ memset(newdir, 0, sizeof(file_entry)); ++ ++ newdir->dos_name[0] = 'X'; ++ newdir->dos_name[1] = ':'; ++ newdir->dos_name[2] = '\0'; ++ ++ newdir->real_name[0] = '.'; ++ newdir->real_name[1] = '\0'; ++ ++ newdir->dos_fullname = strdup(newdir->dos_name); ++ newdir->real_fullname = strdup(root); ++ ++ newdir->attributes = 1; ++ newdir->dir_visited = 0; ++ ++ newdir->parent = newdir; ++ newdir->next = NULL; ++ newdir->prev = NULL; ++ newdir->first_child = NULL; ++ *dir = newdir; ++ ++ unixDirCache[i] = (unix_dir_cache_t*)malloc(sizeof(unix_dir_cache_t)); ++ if (unixDirCache[i] != NULL) { ++ makeDirs(root); ++ unixDirCache[i]->root = strdup(root); ++ unixDirCache[i]->dir = newdir; ++ } ++} ++ ++static const char *manglePath(const char *xdg_path, const char *subdir, ++ const char *path, file_entry **dir) ++{ ++ char *buf; ++ ++ if (*path == '/' || *path == '\\') ++ path++; ++ ++ if (subdir == NULL) { ++ setUnixDir(xdg_path, dir); ++ return path; ++ } ++ ++ if (asprintf(&buf, "%s/%s", xdg_path, subdir) == -1) ++ return NULL; ++ ++ setUnixDir(buf, dir); ++ free(buf); ++ return path; ++} ++ ++#define MANGLE_PATH(xdgpath, subdir, off) \ ++ origdosname = manglePath(xdgpath, subdir, origdosname + off, &parse_dir) ++ ++static void maybeCreateSetupIni() ++{ ++ char *buf; ++ int fd_in, fd_out; ++ static int done = 0; ++ ++ if (done) return; ++ ++ if (asprintf(&buf, "%s/%s", getConfigDir(), "setup.ini") == -1) { ++ return; ++ } ++ ++ if (access(buf, F_OK) == 0) { ++ done = 1; ++ free(buf); ++ return; ++ } ++ ++ makeDirs(getConfigDir()); ++ ++ fd_out = open(buf, O_WRONLY | O_CREAT, 0666); ++ free(buf); ++ ++ if (fd_out == -1) ++ return; ++ ++ if ((fd_in = open("@SETUP_INI_PATH@", O_RDONLY)) == -1) { ++ close(fd_out); ++ return; ++ } ++ ++ buf = malloc(8192); ++ ++ while (1) { ++ ssize_t result = read(fd_in, buf, 8192); ++ if (result == -1 || result == 0) break; ++ if (write(fd_out, buf, result) != result) break; ++ } ++ ++ close(fd_in); ++ close(fd_out); ++ done = 1; ++} ++ + /* + return value: + 0 - dos path found (realdir = found entry) +@@ -292,9 +465,20 @@ return value: + int vfs_get_real_name(const char *origdosname, char *buf, file_entry **realdir) + { + char upperdosname[MAX_PATH], *dosname, *backslash; +- file_entry *parse_dir, *new_parse_dir; ++ file_entry *parse_dir = NULL, *new_parse_dir; + int ret; + ++ if (strncasecmp(origdosname, "xldlibs\\current", 15) == 0) { ++ MANGLE_PATH(getDataDir(), "chars", 15); ++ } else if (strncasecmp(origdosname, "saves", 5) == 0) { ++ MANGLE_PATH(getDataDir(), "saves", 5); ++ } else if (strncasecmp(origdosname, "setup.ini", 10) == 0) { ++ maybeCreateSetupIni(); ++ MANGLE_PATH(getConfigDir(), NULL, 0); ++ } else if (strncasecmp(origdosname, "setup.tmp", 10) == 0) { ++ MANGLE_PATH(getConfigDir(), NULL, 0); ++ } ++ + // convert dos name to uppercase + { + int i; +@@ -316,28 +500,30 @@ int vfs_get_real_name(const char *origdosname, char *buf, file_entry **realdir) + + + // find initial directory for parsing +- if (dosname[0] == '\\') +- { +- parse_dir = &Game_CDir; +- dosname++; +- } +- else if (dosname[0] == 'C' && dosname[1] == ':') +- { +- if (dosname[2] == '\\') ++ if (parse_dir == NULL) { ++ if (dosname[0] == '\\') + { + parse_dir = &Game_CDir; +- dosname+=3; ++ dosname++; ++ } ++ else if (dosname[0] == 'C' && dosname[1] == ':') ++ { ++ if (dosname[2] == '\\') ++ { ++ parse_dir = &Game_CDir; ++ dosname+=3; ++ } ++ else ++ { ++ parse_dir = Game_Current_Dir; ++ dosname+=2; ++ } + } + else + { + parse_dir = Game_Current_Dir; +- dosname+=2; + } + } +- else +- { +- parse_dir = Game_Current_Dir; +- } + + // find directory + for (backslash = strchr(dosname, '\\'); backslash != NULL; backslash = strchr(dosname, '\\')) diff --git a/pkgs/games/gog/default.nix b/pkgs/games/gog/default.nix index 111091c3..8d8379a3 100644 --- a/pkgs/games/gog/default.nix +++ b/pkgs/games/gog/default.nix @@ -10,6 +10,8 @@ let fetchGog = callPackage ./fetch-gog { inherit (config.gog) email password; }; + + albion = callPackage_i686 ./albion { inherit (pkgs) buildSandbox; }; }; in { options.gog = { |