1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
{ stdenv, buildGame, fetchGog, writeText, SDL2, libudev }:
buildGame rec {
name = "freedom-planet-${version}";
version = "1.21.5";
src = fetchGog {
productId = 1207667013;
downloadName = "en3installer0";
sha256 = "1rsa2bswzvc4a8crpzhcw3vjan0f9avk7g1gyqibnyppib63i42w";
};
binDir = "bin${if stdenv.is64bit then "64" else "32"}";
buildInputs = [ SDL2 ];
runtimeDependencies = [ libudev ];
buildPhase = ''
cc -Werror -Wall -std=gnu11 -shared "$preloader" -o preload.so -fPIC \
-DDATA_DIR="\"$out/share/freedom-planet\""
patchelf \
--add-needed "$out/libexec/freedom-planet/libpreload.so" \
"$binDir/Chowdren"
'';
preloader = writeText "freedom-planet-preloader.c" ''
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char *mkDataPath(const char *path)
{
size_t pathlen;
char *buf;
pathlen = strlen(path);
buf = malloc(pathlen + sizeof(DATA_DIR));
if (buf == NULL) return NULL;
memcpy(buf, DATA_DIR, sizeof(DATA_DIR) - 1);
memcpy(buf + sizeof(DATA_DIR) - 1, path, pathlen + 1);
return buf;
}
static char *mkSavePath(const char *path)
{
char *env;
char *buf;
if ((env = getenv("XDG_DATA_HOME")) != NULL) {
if (asprintf(&buf, "%s/freedom-planet%s", env, path + 1) == -1)
return NULL;
} else if ((env = getenv("HOME")) != NULL) {
if (asprintf(&buf, "%s/.local/share/freedom-planet%s", env,
path + 1) == -1)
return NULL;
}
return buf;
}
static char *mkCfgPath(const char *path)
{
char *env;
char *buf;
if ((env = getenv("XDG_CONFIG_HOME")) != NULL) {
if (asprintf(&buf, "%s/freedom-planet%s", env, path + 1) == -1)
return NULL;
} else if ((env = getenv("HOME")) != NULL) {
if (asprintf(&buf, "%s/.config/freedom-planet%s", env, path + 1) == -1)
return NULL;
}
return buf;
}
FILE *fopen(const char *path, const char *mode) {
FILE *ret;
char *buf;
static FILE *(*_fopen) (const char *, const char *) = NULL;
if (_fopen == NULL) _fopen = dlsym(RTLD_NEXT, "fopen");
if (strncmp(path, "./Assets.dat", 13) == 0) {
buf = mkDataPath(path + 1);
} else if (strncmp(path, "./Data/", 7) == 0) {
buf = mkDataPath(path + 6);
} else if (strncmp(path, "./records.dat", 14) == 0 ||
strncmp(path, "./file", 6) == 0 ||
strncmp(path, "./save", 6) == 0) {
buf = mkSavePath(path);
} else if (strncmp(path, "./control_", 10) == 0) {
buf = mkCfgPath(path);
} else {
return _fopen(path, mode);
}
if (buf == NULL) return NULL;
ret = fopen(buf, mode);
free(buf);
return ret;
}
'';
installPhase = ''
install -m 0644 -vD Assets.dat "$out/share/freedom-planet/Assets.dat"
install -vD "$binDir/Chowdren" "$out/bin/freedom-planet"
install -vD preload.so "$out/libexec/freedom-planet/libpreload.so"
cp -rt "$out/share/freedom-planet" Data/BGM Data/font.bmp Data/voices
'';
sandbox.paths.required = [
"$XDG_DATA_HOME/freedom-planet" "$XDG_CONFIG_HOME/freedom-planet"
];
}
|