Skip to content

Commit 7c351ea

Browse files
committed
Cross-check Arcanum support against dbmaker and the demo archive
tests/arcanum.sh drives Troika's vendored dbmaker.exe under wine in both directions on a synthetic tree, then extracts the demo's real 13k-file archive with both tools and diffs the trees. The demo download is md5-pinned and the extracted archive is cached in CI.
1 parent f9eed4b commit 7c351ea

5 files changed

Lines changed: 116 additions & 1 deletion

File tree

‎.github/workflows/build.yml‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@ jobs:
5252
DEBIAN_FRONTEND: noninteractive
5353
run: |
5454
sudo apt-get update -qq
55-
sudo apt-get install -y --no-install-recommends gcc-mingw-w64 musl-tools
55+
sudo apt-get install -y --no-install-recommends gcc-mingw-w64 musl-tools p7zip-full
56+
57+
- name: Cache test fixtures
58+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
59+
with:
60+
path: |
61+
tests/rpu_v2.4.33.zip
62+
tests/ArcanumDemo.dat
63+
key: test-fixtures-rpu-v2.4.33-arcanum-demo-v1
5664

5765
- name: Build binaries
5866
run: ./build.sh

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
# Project-specific
77
*.dat
88
*.DAT
9+
/tmp/
910

1011
!/tests/
1112
/tests/*
1213
!/tests/*.sh
1314
!/tests/rpu.md5
1415
!/tests/dat2.exe
16+
!/tests/dbmaker.exe
1517

1618
# IDE
1719
.vscode/

‎test.sh‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ cargo build --release --target x86_64-unknown-linux-musl
99
cd tests
1010
./non-ascii.sh
1111
./rpu.sh
12+
./arcanum.sh
1213

1314
# Put Fallout 1 critter.dat into tests/f1 to run this
1415
if [ -f f1/critter.dat ]; then

‎tests/arcanum.sh‎

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/bin/bash
2+
3+
set -xeu -o pipefail
4+
5+
# Work inside tests directory
6+
cd "$(dirname "$0")"
7+
8+
# Load common variables and functions
9+
# shellcheck source=tests/common.sh
10+
source ./common.sh
11+
12+
# Cross-check the Arcanum format against Troika's own dbmaker.exe
13+
# (usage: dbmaker [option] output input; -r recurse, -u unpack, -cN level)
14+
dbmaker() {
15+
WINEDEBUG=-all wine dbmaker.exe "$@" 2>/dev/null
16+
}
17+
18+
SRC_DIR="arcanum_src"
19+
DAT3_DAT="arcanum_dat3.dat"
20+
DB_DAT="arcanum_dbmaker.dat"
21+
DB_OUT="arcanum_db_out"
22+
DAT3_OUT="arcanum_dat3_out"
23+
24+
# Build a small deterministic source tree: compressible files, a subdirectory,
25+
# and a file so small it stores uncompressed (zlib overhead exceeds its size)
26+
rm -rf "$SRC_DIR"
27+
mkdir -p "$SRC_DIR/data/sub"
28+
seq 1 2000 >"$SRC_DIR/data/numbers.txt"
29+
printf 'hi\n' >"$SRC_DIR/data/sub/tiny.txt"
30+
head -c 4096 /dev/zero >"$SRC_DIR/data/sub/zeros.bin"
31+
32+
# dat3 writes, dbmaker reads
33+
rm -f "$DAT3_DAT"
34+
(cd "$SRC_DIR" && $DAT3 a --format arcanum -c 9 "../$DAT3_DAT" data)
35+
rm -rf "$DB_OUT"
36+
mkdir "$DB_OUT"
37+
(cd "$DB_OUT" && dbmaker -u "../$DAT3_DAT")
38+
diff -r "$SRC_DIR" "$DB_OUT"
39+
40+
# dbmaker writes, dat3 auto-detects and reads
41+
rm -f "$DB_DAT"
42+
(cd "$SRC_DIR" && dbmaker -r -q "../$DB_DAT" data)
43+
$DAT3 l "$DB_DAT"
44+
rm -rf "$DAT3_OUT"
45+
$DAT3 x "$DB_DAT" -o "$DAT3_OUT"
46+
diff -r "$SRC_DIR" "$DAT3_OUT"
47+
48+
# dat3 modifies the dbmaker-written archive; dbmaker reads the result
49+
echo "added later" >added.txt
50+
$DAT3 a "$DB_DAT" -t data added.txt
51+
$DAT3 d "$DB_DAT" "data/sub/zeros.bin"
52+
rm -rf "$DB_OUT"
53+
mkdir "$DB_OUT"
54+
(cd "$DB_OUT" && dbmaker -u "../$DB_DAT")
55+
diff "$DB_OUT/data/added.txt" added.txt
56+
if [ -e "$DB_OUT/data/sub/zeros.bin" ]; then
57+
echo "Error: deleted file still present in archive"
58+
exit 1
59+
fi
60+
61+
# ── Real game data: the Arcanum demo's 30 MB archive (13k files) ──
62+
63+
# Only the extracted archive is cached; the demo installer is fetched and
64+
# unpacked (RAR -> CAB -> DAT) solely to produce it
65+
DEMO_DAT="ArcanumDemo.dat"
66+
if [ ! -f "$DEMO_DAT" ]; then
67+
DEMO_RAR="ArcanumDemo.rar"
68+
if [ ! -f "$DEMO_RAR" ]; then
69+
wget -nv -O "$DEMO_RAR" "https://archive.org/download/ArcanumDemo/ArcanumDemo.rar"
70+
fi
71+
echo "4a77a6cf6f801855cdfe0e7c61459a43 $DEMO_RAR" | md5sum -c
72+
7z e -y "$DEMO_RAR" Setup1.cab
73+
7z e -y Setup1.cab Arcanum.dat
74+
mv Arcanum.dat "$DEMO_DAT"
75+
rm -f Setup1.cab "$DEMO_RAR"
76+
fi
77+
echo "74e813d99a239c6ee04dd9fa807375a3 $DEMO_DAT" | md5sum -c
78+
79+
# Both tools extract the real archive; the trees must be identical
80+
$DAT3 l "$DEMO_DAT"
81+
rm -rf demo_dat3 demo_db
82+
$DAT3 x "$DEMO_DAT" -o demo_dat3
83+
mkdir demo_db
84+
(cd demo_db && dbmaker -u "../$DEMO_DAT")
85+
diff -r demo_dat3 demo_db
86+
87+
# dat3 modifies the real archive; dbmaker reads the result
88+
DEMO_MOD="demo_mod.dat"
89+
cp "$DEMO_DAT" "$DEMO_MOD"
90+
$DAT3 d "$DEMO_MOD" "WorldMap/WorldMap.mes"
91+
echo "demo test file" >demo_add.txt
92+
$DAT3 a "$DEMO_MOD" -t WorldMap demo_add.txt
93+
rm -rf demo_db
94+
mkdir demo_db
95+
(cd demo_db && dbmaker -u "../$DEMO_MOD")
96+
diff demo_db/WorldMap/demo_add.txt demo_add.txt
97+
if [ -e demo_db/WorldMap/WorldMap.mes ]; then
98+
echo "Error: deleted file still present in archive"
99+
exit 1
100+
fi
101+
102+
# Clean up (keep the extracted DAT for the CI cache)
103+
rm -rf "$SRC_DIR" "$DB_OUT" "$DAT3_OUT" "$DAT3_DAT" "$DB_DAT" added.txt \
104+
demo_dat3 demo_db "$DEMO_MOD" demo_add.txt

‎tests/dbmaker.exe‎

104 KB
Binary file not shown.

0 commit comments

Comments
 (0)