169 lines
5.4 KiB
Bash
Executable file
169 lines
5.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Host-side regression tests for the AGI port.
|
|
#
|
|
# Compiles tests/agi/testAgiRes.c + examples/agi/agiRes.c with the
|
|
# host gcc and runs it against every game directory in
|
|
# examples/agi/gamedata/. Each game is exercised in isolation; the
|
|
# script aggregates pass/fail counts and exits non-zero if any test
|
|
# fails.
|
|
#
|
|
# Why a host build instead of running the emulator binaries: the AGI
|
|
# resource loader is plain stdio C with no platform dependencies, so
|
|
# the parsing logic is identical on every JoeyLib target. Validating
|
|
# it on the build host means each iteration takes a second instead
|
|
# of the 15-30s of an emulator boot, and reproducible failures don't
|
|
# depend on capturing video / log output through DOSBox or MAME.
|
|
#
|
|
# Usage:
|
|
# scripts/test-agi.sh # test every subdir of gamedata/
|
|
# scripts/test-agi.sh kq3 agidemo # test only the named subdirs
|
|
|
|
set -euo pipefail
|
|
|
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
gamedata=$repo/examples/agi/gamedata
|
|
build=$repo/build/tests
|
|
testRes=$build/testAgiRes
|
|
testPic=$build/testAgiPic
|
|
testView=$build/testAgiView
|
|
testVm=$build/testAgiVm
|
|
testPipeline=$build/testAgiPipeline
|
|
|
|
mkdir -p "$build"
|
|
|
|
# Shared host compile flags. agiPic.c calls jlDrawPixel in the blit
|
|
# step, which the host test never invokes; we stub it as an empty
|
|
# function via the link-line shim below so the host build can resolve
|
|
# the symbol without dragging in the JoeyLib runtime.
|
|
# Pick a JoeyLib platform for the host build. None of the platform-
|
|
# specific code paths are exercised by the host test (it only touches
|
|
# the AGI parsers, never the JoeyLib HAL), but joey/platform.h #errors
|
|
# unless exactly one is defined. DOS is the closest fit for a Linux
|
|
# host (chunky, little-endian, x86 lineage).
|
|
hostCflags=(-std=c99 -Wall -Wextra -Werror -O2 -DJOEYLIB_PLATFORM_DOS -I "$repo/include" -I "$repo/examples/agi" -I "$repo/src/core")
|
|
stubSrc=$build/hostStubs.c
|
|
cat > "$stubSrc" <<'EOF'
|
|
#include "joey/draw.h"
|
|
#include "joey/core.h"
|
|
#include "surfaceInternal.h"
|
|
#include <stdlib.h>
|
|
void jlDrawPixel(jlSurfaceT *s, int16_t x, int16_t y, uint8_t c) { (void)s; (void)x; (void)y; (void)c; }
|
|
void jlFillRect(jlSurfaceT *s, int16_t x, int16_t y, uint16_t w, uint16_t h, uint8_t c) { (void)s; (void)x; (void)y; (void)w; (void)h; (void)c; }
|
|
uint32_t jlRandom(void) { return (uint32_t)rand(); }
|
|
uint16_t jlRandomRange(uint16_t bound) { return (bound == 0u) ? 0u : (uint16_t)((unsigned)rand() % bound); }
|
|
void jlRandomSeed(uint32_t seed) { srand((unsigned)seed); }
|
|
void surfaceMarkDirtyRect(const jlSurfaceT *s, int16_t x, int16_t y, int16_t w, int16_t h) { (void)s; (void)x; (void)y; (void)w; (void)h; }
|
|
void surfaceMarkDirtyAll(const jlSurfaceT *s) { (void)s; }
|
|
EOF
|
|
|
|
echo "Building host tests..."
|
|
gcc "${hostCflags[@]}" \
|
|
"$repo/tests/agi/testAgiRes.c" \
|
|
"$repo/examples/agi/agiRes.c" \
|
|
-o "$testRes"
|
|
|
|
gcc "${hostCflags[@]}" \
|
|
"$repo/tests/agi/testAgiPic.c" \
|
|
"$repo/examples/agi/agiRes.c" \
|
|
"$repo/examples/agi/agiPic.c" \
|
|
"$stubSrc" \
|
|
-o "$testPic"
|
|
|
|
gcc "${hostCflags[@]}" \
|
|
"$repo/tests/agi/testAgiView.c" \
|
|
"$repo/examples/agi/agiRes.c" \
|
|
"$repo/examples/agi/agiPic.c" \
|
|
"$repo/examples/agi/agiView.c" \
|
|
"$stubSrc" \
|
|
-o "$testView"
|
|
|
|
gcc "${hostCflags[@]}" \
|
|
"$repo/tests/agi/testAgiVm.c" \
|
|
"$repo/examples/agi/agiRes.c" \
|
|
"$repo/examples/agi/agiVm.c" \
|
|
"$repo/examples/agi/agiObj.c" \
|
|
"$stubSrc" \
|
|
-o "$testVm"
|
|
|
|
gcc "${hostCflags[@]}" \
|
|
"$repo/tests/agi/testAgiPipeline.c" \
|
|
"$repo/examples/agi/agiRes.c" \
|
|
"$repo/examples/agi/agiVm.c" \
|
|
"$repo/examples/agi/agiObj.c" \
|
|
"$stubSrc" \
|
|
-o "$testPipeline"
|
|
|
|
# Pick the game directories to exercise. With no args, every
|
|
# subdirectory of examples/agi/gamedata that contains LOGDIR is a
|
|
# candidate (skips stray README files etc).
|
|
if [[ $# -gt 0 ]]; then
|
|
games=("$@")
|
|
else
|
|
games=()
|
|
if [[ -d $gamedata ]]; then
|
|
for dir in "$gamedata"/*/; do
|
|
[[ -d $dir ]] || continue
|
|
name=$(basename "$dir")
|
|
if [[ -f $dir/LOGDIR ]]; then
|
|
games+=("$name")
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
|
|
if [[ ${#games[@]} -eq 0 ]]; then
|
|
echo
|
|
echo "No AGI game directories found under $gamedata"
|
|
echo "Drop an AGI v2 game in examples/agi/gamedata/<name>/ and rerun."
|
|
echo "See examples/agi/gamedata/README.md for the required files."
|
|
exit 0
|
|
fi
|
|
|
|
passed=0
|
|
failed=0
|
|
echo
|
|
for game in "${games[@]}"; do
|
|
dir=$gamedata/$game
|
|
echo "===== $game ====="
|
|
if [[ ! -d $dir ]]; then
|
|
echo " FAIL: $dir does not exist"
|
|
failed=$((failed + 1))
|
|
continue
|
|
fi
|
|
|
|
gameOk=1
|
|
echo "--- resource loader ---"
|
|
if ! "$testRes" "$dir"; then
|
|
gameOk=0
|
|
fi
|
|
echo "--- PIC decoder ---"
|
|
if ! "$testPic" "$dir"; then
|
|
gameOk=0
|
|
fi
|
|
echo "--- VIEW decoder ---"
|
|
if ! "$testView" "$dir"; then
|
|
gameOk=0
|
|
fi
|
|
echo "--- LOGIC VM (logic.0) ---"
|
|
if ! "$testVm" "$dir"; then
|
|
gameOk=0
|
|
fi
|
|
echo "--- VM pipeline (callbacks + room transitions) ---"
|
|
if ! "$testPipeline" "$dir"; then
|
|
gameOk=0
|
|
fi
|
|
|
|
if [[ $gameOk -eq 1 ]]; then
|
|
passed=$((passed + 1))
|
|
else
|
|
failed=$((failed + 1))
|
|
fi
|
|
echo
|
|
done
|
|
|
|
total=$((passed + failed))
|
|
echo "===== summary: $passed/$total passed ====="
|
|
if [[ $failed -gt 0 ]]; then
|
|
exit 1
|
|
fi
|
|
exit 0
|