Build standalone against JoeyLib.
This commit is contained in:
parent
5a9db28d63
commit
96c72ca4ba
12 changed files with 335 additions and 37 deletions
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Everything make writes: programs, disk images, the host tests.
|
||||||
|
build/
|
||||||
|
|
||||||
|
# The games the interpreter plays: Sierra's (or other authors') files,
|
||||||
|
# never committed. games/README.md says what goes there.
|
||||||
|
games/*
|
||||||
|
!games/README.md
|
||||||
|
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
# Editor / OS cruft
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
28
Makefile
Normal file
28
Makefile
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
# JoeyAGI, a Sierra AGI v2 interpreter built with JoeyLib: a JoeyLib
|
||||||
|
# checkout (JOEYLIB, beside this one by default) owns the toolchains, the
|
||||||
|
# library and every target's rules, and program.mk describes the
|
||||||
|
# interpreter to them.
|
||||||
|
#
|
||||||
|
# make every target whose toolchain is installed
|
||||||
|
# make <port> one target: iigs amiga atarist dos x68000 dvx
|
||||||
|
# make iigs-game-disk-agi the bootable IIgs volume with a game on it
|
||||||
|
# (games/kq3; AGI_GAME=NAME for games/NAME)
|
||||||
|
# make check build, then run the gates (scripts/verify.sh)
|
||||||
|
# make clean remove build/
|
||||||
|
# make help JoeyLib's project targets
|
||||||
|
#
|
||||||
|
# README.md covers setting up JoeyLib, the game files and running.
|
||||||
|
|
||||||
|
JOEYLIB ?= ../joeylib
|
||||||
|
include $(JOEYLIB)/make/project.mk
|
||||||
|
|
||||||
|
include $(JOEY_PROJECT)/program.mk
|
||||||
|
|
||||||
|
# The author DVX's resource list names.
|
||||||
|
DVX_AUTHOR := Scott Duensing
|
||||||
|
|
||||||
|
include $(JOEYLIB)/make/programs.mk
|
||||||
|
|
||||||
|
.PHONY: check
|
||||||
|
check: all
|
||||||
|
JOEYLIB="$(abspath $(JOEYLIB))" $(JOEY_PROJECT)/scripts/verify.sh
|
||||||
79
README.md
Normal file
79
README.md
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
# JoeyAGI
|
||||||
|
|
||||||
|
An interpreter for Sierra's Adventure Game Interpreter (AGI) v2 games --
|
||||||
|
King's Quest III and its contemporaries -- written from the public AGI
|
||||||
|
format descriptions on [JoeyLib](../joeylib), so it runs on every machine
|
||||||
|
JoeyLib targets: the Apple IIgs, Commodore Amiga, Atari ST, MS-DOS, Sharp
|
||||||
|
X68000 and DVX. It decodes the games' own resource files (LOGIC, PICTURE,
|
||||||
|
VIEW, SOUND, OBJECT, WORDS.TOK); it ships no game.
|
||||||
|
|
||||||
|
## Setting up
|
||||||
|
|
||||||
|
JoeyAGI builds with JoeyLib, which owns the cross compilers, the library
|
||||||
|
and every machine's build rules. Check JoeyLib out beside this repository
|
||||||
|
and install its toolchains (its README covers the installer):
|
||||||
|
|
||||||
|
```
|
||||||
|
games/
|
||||||
|
joeylib/ a JoeyLib checkout, set up with ./install.sh
|
||||||
|
joeyagi/ this repository
|
||||||
|
```
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ cd ../joeylib
|
||||||
|
$ ./install.sh install toolchains # the cross compilers
|
||||||
|
$ ./install.sh install emulators # to run it and for the gates
|
||||||
|
```
|
||||||
|
|
||||||
|
`JOEYLIB=PATH` on the make command line (or in the environment, for the
|
||||||
|
scripts) points at a checkout somewhere else.
|
||||||
|
|
||||||
|
## Games
|
||||||
|
|
||||||
|
The interpreter needs an AGI v2 game's files. Put each game in its own
|
||||||
|
folder under `games/` (`games/kq3/`, ...), which git ignores;
|
||||||
|
games/README.md lists the files and where legitimate copies come from.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ make # every machine whose toolchain is installed
|
||||||
|
$ make dos # one: iigs amiga atarist dos x68000 dvx
|
||||||
|
$ make iigs-game-disk-agi # the bootable IIgs volume, with games/kq3 on it
|
||||||
|
$ make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
The programs land in `build/<machine>/bin/`: `AGI` (IIgs), `Agi` (Amiga),
|
||||||
|
`AGI.PRG`, `AGI.EXE`, `AGI.X`, and on DVX `apps/joeylib/agi/`.
|
||||||
|
`make iigs-game-disk-agi` writes `build/iigs/bin/AGI.2mg`, a 2 MB bootable
|
||||||
|
volume holding the interpreter and the game (`AGI_GAME=NAME` puts
|
||||||
|
`games/NAME` on it instead). JoeyLib's library is built on demand in the
|
||||||
|
JoeyLib checkout's own `build/`.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
The interpreter reads the game from its `DATA` folder; JoeyLib's `joey-run`
|
||||||
|
copies a game there for the run:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ ../joeylib/joey-run --project . --port dos --data games/kq3 agi
|
||||||
|
$ ../joeylib/joey-run --ram 8M build/iigs/bin/AGI.2mg
|
||||||
|
```
|
||||||
|
|
||||||
|
The IIgs volume boots off a CFFA2 card in MAME and wants 8 MB of memory.
|
||||||
|
|
||||||
|
## The gates
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ make check # build, then every gate
|
||||||
|
$ scripts/verify.sh host # or name the ones to run
|
||||||
|
```
|
||||||
|
|
||||||
|
| Gate | What it proves |
|
||||||
|
|------|----------------|
|
||||||
|
| `host` | The resource loader, the PICTURE and VIEW decoders, the LOGIC VM and the VM pipeline, built for the host against JoeyLib's headers and run on every game in `games/` (`scripts/test-agi.sh`) |
|
||||||
|
| `disk` | `AGI.2mg` with King's Quest III boots on a IIgs, launches the interpreter and draws |
|
||||||
|
|
||||||
|
`scripts/verify.sh` exits 0 when every gate passed, 1 when one failed, and 3
|
||||||
|
when none failed but one was skipped (no game in `games/`, or the IIgs
|
||||||
|
toolchain or emulator missing).
|
||||||
49
games/README.md
Normal file
49
games/README.md
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
# AGI game data
|
||||||
|
|
||||||
|
Everything in this folder except this file is ignored by git. No game's
|
||||||
|
files are, or should ever be, committed to the repository.
|
||||||
|
|
||||||
|
Place each game in its own subdirectory:
|
||||||
|
|
||||||
|
```
|
||||||
|
games/
|
||||||
|
agidemo/ # Sierra's promotional AGIDEMO (freely redistributable)
|
||||||
|
kq3/ # Local copy extracted from your licensed King's Quest 3
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
`scripts/test-agi.sh` runs the host tests against every subdirectory that
|
||||||
|
holds a `LOGDIR`, and `make iigs-game-disk-agi` puts `kq3` (or
|
||||||
|
`AGI_GAME=NAME`) on the bootable IIgs volume. Everywhere else the
|
||||||
|
interpreter reads the game from its `DATA` folder; `joey-run --data
|
||||||
|
games/kq3` copies a game there for one run.
|
||||||
|
|
||||||
|
## Required files per game
|
||||||
|
|
||||||
|
For an AGI v2 game directory the loader needs:
|
||||||
|
|
||||||
|
- `LOGDIR` - logic script index
|
||||||
|
- `PICDIR` - picture (room background) index
|
||||||
|
- `VIEWDIR` - view (sprite/animation) index
|
||||||
|
- `SNDDIR` - sound index
|
||||||
|
- `VOL.0` - resource volume 0 (always present)
|
||||||
|
- `VOL.1`..`VOL.N` - additional resource volumes (game-dependent)
|
||||||
|
- `OBJECT` - inventory table
|
||||||
|
- `WORDS.TOK` - parser dictionary
|
||||||
|
|
||||||
|
File names are uppercase by AGI convention; the loader looks them up
|
||||||
|
literally so the directory should match.
|
||||||
|
|
||||||
|
## Sourcing AGI data
|
||||||
|
|
||||||
|
This repository never ships copyrighted Sierra game data. Two legitimate
|
||||||
|
sources for development and testing:
|
||||||
|
|
||||||
|
1. Sierra's freely-distributed `AGIDEMO` promotional disk -
|
||||||
|
redistributable since the late 1980s.
|
||||||
|
2. Fan-made AGI titles authored with AGI Studio - many are released
|
||||||
|
under explicit redistribution licenses.
|
||||||
|
|
||||||
|
To test against a commercial Sierra game you legally own, extract
|
||||||
|
the data files from your own copy and drop them in a new sibling
|
||||||
|
directory here. Do not commit them.
|
||||||
32
program.mk
Normal file
32
program.mk
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# The AGI interpreter, described for JoeyLib's make/programs.mk (which lists
|
||||||
|
# what each variable means). Included by the Makefile beside it, on JoeyLib's
|
||||||
|
# make/project.mk.
|
||||||
|
|
||||||
|
AGI_HOME := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||||
|
|
||||||
|
PROGRAMS += AGI
|
||||||
|
AGI_SRCS := $(addprefix $(AGI_HOME)/,agi.c agiRes.c agiPic.c agiView.c agiVm.c agiObj.c agiText.c)
|
||||||
|
AGI_TITLE := AGI
|
||||||
|
AGI_HELP := A Sierra AGI interpreter. The files of the game it plays go in its DATA folder.
|
||||||
|
|
||||||
|
# IIgs: large overflow segments. --segment-cap bounds the ENTRY bank (which
|
||||||
|
# also holds rodata + bss + heap); overflow banks carry text only, so capping
|
||||||
|
# them the same way wasted ~50K per bank. With this AGI links 5 bank-aligned
|
||||||
|
# segments instead of 19, which matters because it already needs -ramsize 4M.
|
||||||
|
# Verified by running KQ3 headless and diffing AGI's own joeylog.txt against
|
||||||
|
# the 19-segment build: identical apart from the embedded build timestamp.
|
||||||
|
# See JoeyLib's make/support/iigs/clang-build.sh for the measurements.
|
||||||
|
AGI_IIGS_OVERFLOW_CAP := 0xF000
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM),iigs)
|
||||||
|
# AGI's bootable IIgs volume needs a game's resources (games/kq3, King's
|
||||||
|
# Quest III, by default; AGI_GAME=NAME for games/NAME), which
|
||||||
|
# make-agi-iigs-disk.sh lays out, so it cannot use the generic one-program
|
||||||
|
# data disk. It also wants a bigger Memory Manager pool: run it with
|
||||||
|
# -ramsize 8M.
|
||||||
|
AGI_GAME ?= kq3
|
||||||
|
.PHONY: iigs-game-disk-agi
|
||||||
|
iigs-game-disk-agi: $(call programBin,AGI)
|
||||||
|
BINDIR="$(BINDIR)" JOEYLIB="$(REPO_DIR)" $(AGI_HOME)/scripts/make-agi-iigs-disk.sh $(BINDIR)/AGI-data.2mg $(AGI_GAME)
|
||||||
|
$(REPO_DIR)/scripts/make-iigs-game-disk.sh $(BINDIR)/AGI.2mg AGI AGI $(BINDIR)/AGI-data.2mg
|
||||||
|
endif
|
||||||
|
|
@ -10,19 +10,23 @@
|
||||||
# has no such cap, so the whole payload lands on one 2MB ProDOS volume.
|
# has no such cap, so the whole payload lands on one 2MB ProDOS volume.
|
||||||
#
|
#
|
||||||
# Usage: scripts/make-agi-iigs-disk.sh <output.2mg> [game-name]
|
# Usage: scripts/make-agi-iigs-disk.sh <output.2mg> [game-name]
|
||||||
# game-name : subdirectory under examples/agi/gamedata/ (default kq3)
|
# game-name : subdirectory under games/ (default kq3)
|
||||||
# Requires: ./install.sh install toolchain:iigs; built build/iigs/bin/AGI.
|
# Env: BINDIR the built AGI's folder (default build/iigs/bin)
|
||||||
|
# JOEYLIB the JoeyLib checkout (default ../joeylib)
|
||||||
|
# Requires: JoeyLib's ./install.sh install toolchain:iigs; build/iigs/bin/AGI
|
||||||
|
# built (make iigs).
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
source "$repo/scripts/lib/joeyEnv.sh"
|
JOEYLIB=${JOEYLIB:-$repo/../joeylib}
|
||||||
|
source "$JOEYLIB/scripts/lib/joeyEnv.sh"
|
||||||
joeyNeed LLVM816_ROOT toolchain:iigs
|
joeyNeed LLVM816_ROOT toolchain:iigs
|
||||||
joeyNeed CADIUS cadius
|
joeyNeed CADIUS cadius
|
||||||
BINDIR="${BINDIR:-$repo/build/iigs/bin}"
|
BINDIR="${BINDIR:-$repo/build/iigs/bin}"
|
||||||
|
|
||||||
out=${1:?usage: make-agi-iigs-disk.sh <output.2mg> [game]}
|
out=${1:?usage: make-agi-iigs-disk.sh <output.2mg> [game]}
|
||||||
game=${2:-kq3}
|
game=${2:-kq3}
|
||||||
gamedata=$repo/examples/agi/gamedata/$game
|
gamedata=$repo/games/$game
|
||||||
agiBin=$BINDIR/AGI
|
agiBin=$BINDIR/AGI
|
||||||
VOL=AGI
|
VOL=AGI
|
||||||
|
|
||||||
|
|
@ -31,7 +35,7 @@ VOL=AGI
|
||||||
# prefix to the volume it launched from, and ProDOS lookups are
|
# prefix to the volume it launched from, and ProDOS lookups are
|
||||||
# case-insensitive, so the uppercase names match the lowercase fopen paths.
|
# case-insensitive, so the uppercase names match the lowercase fopen paths.
|
||||||
[ -x "$CADIUS" ] || { echo "make-agi-iigs-disk.sh: cadius not found at $CADIUS" >&2; exit 2; }
|
[ -x "$CADIUS" ] || { echo "make-agi-iigs-disk.sh: cadius not found at $CADIUS" >&2; exit 2; }
|
||||||
[ -f "$agiBin" ] || { echo "make-agi-iigs-disk.sh: $agiBin not built (make -f make/iigs.mk $agiBin)" >&2; exit 1; }
|
[ -f "$agiBin" ] || { echo "make-agi-iigs-disk.sh: $agiBin not built (make iigs)" >&2; exit 1; }
|
||||||
[ -d "$gamedata" ] || { echo "make-agi-iigs-disk.sh: $gamedata is not an AGI v2 game directory" >&2; exit 1; }
|
[ -d "$gamedata" ] || { echo "make-agi-iigs-disk.sh: $gamedata is not an AGI v2 game directory" >&2; exit 1; }
|
||||||
[ -f "$gamedata/LOGDIR" ] || { echo "make-agi-iigs-disk.sh: $gamedata has no LOGDIR -- not AGI v2" >&2; exit 1; }
|
[ -f "$gamedata/LOGDIR" ] || { echo "make-agi-iigs-disk.sh: $gamedata has no LOGDIR -- not AGI v2" >&2; exit 1; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Host-side regression tests for the AGI port.
|
# Host-side regression tests for the AGI port.
|
||||||
#
|
#
|
||||||
# Compiles tests/agi/testAgiRes.c + examples/agi/agiRes.c with the
|
# Compiles the tests in tests/ with the interpreter sources they cover,
|
||||||
# host gcc and runs it against every game directory in
|
# using the host gcc and JoeyLib's headers, and runs them against every
|
||||||
# examples/agi/gamedata/. Each game is exercised in isolation; the
|
# game directory in games/. Each game is exercised in isolation; the
|
||||||
# script aggregates pass/fail counts and exits non-zero if any test
|
# script aggregates pass/fail counts and exits non-zero if any test
|
||||||
# fails.
|
# fails.
|
||||||
#
|
#
|
||||||
|
|
@ -15,13 +15,17 @@
|
||||||
# depend on capturing video / log output through DOSBox or MAME.
|
# depend on capturing video / log output through DOSBox or MAME.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# scripts/test-agi.sh # test every subdir of gamedata/
|
# scripts/test-agi.sh # test every subdir of games/
|
||||||
# scripts/test-agi.sh kq3 agidemo # test only the named subdirs
|
# scripts/test-agi.sh kq3 agidemo # test only the named subdirs
|
||||||
|
# Env:
|
||||||
|
# JOEYLIB the JoeyLib checkout (default ../joeylib)
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
gamedata=$repo/examples/agi/gamedata
|
JOEYLIB=${JOEYLIB:-$repo/../joeylib}
|
||||||
|
[[ -f $JOEYLIB/include/joey/joey.h ]] || { echo "test-agi: no JoeyLib checkout at $JOEYLIB (set JOEYLIB)" >&2; exit 2; }
|
||||||
|
gamedata=$repo/games
|
||||||
build=$repo/build/tests
|
build=$repo/build/tests
|
||||||
testRes=$build/testAgiRes
|
testRes=$build/testAgiRes
|
||||||
testPic=$build/testAgiPic
|
testPic=$build/testAgiPic
|
||||||
|
|
@ -40,7 +44,7 @@ mkdir -p "$build"
|
||||||
# the AGI parsers, never the JoeyLib HAL), but joey/platform.h #errors
|
# 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
|
# unless exactly one is defined. DOS is the closest fit for a Linux
|
||||||
# host (chunky, little-endian, x86 lineage).
|
# 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")
|
hostCflags=(-std=c99 -Wall -Wextra -Werror -O2 -DJOEYLIB_PLATFORM_DOS -I "$JOEYLIB/include" -I "$repo" -I "$JOEYLIB/src/core")
|
||||||
stubSrc=$build/hostStubs.c
|
stubSrc=$build/hostStubs.c
|
||||||
cat > "$stubSrc" <<'EOF'
|
cat > "$stubSrc" <<'EOF'
|
||||||
#include "joey/draw.h"
|
#include "joey/draw.h"
|
||||||
|
|
@ -85,45 +89,45 @@ EOF
|
||||||
|
|
||||||
echo "Building host tests..."
|
echo "Building host tests..."
|
||||||
gcc "${hostCflags[@]}" \
|
gcc "${hostCflags[@]}" \
|
||||||
"$repo/tests/agi/testAgiRes.c" \
|
"$repo/tests/testAgiRes.c" \
|
||||||
"$repo/examples/agi/agiRes.c" \
|
"$repo/agiRes.c" \
|
||||||
"$stubSrc" \
|
"$stubSrc" \
|
||||||
-o "$testRes"
|
-o "$testRes"
|
||||||
|
|
||||||
gcc "${hostCflags[@]}" \
|
gcc "${hostCflags[@]}" \
|
||||||
"$repo/tests/agi/testAgiPic.c" \
|
"$repo/tests/testAgiPic.c" \
|
||||||
"$repo/examples/agi/agiRes.c" \
|
"$repo/agiRes.c" \
|
||||||
"$repo/examples/agi/agiPic.c" \
|
"$repo/agiPic.c" \
|
||||||
"$stubSrc" \
|
"$stubSrc" \
|
||||||
-o "$testPic"
|
-o "$testPic"
|
||||||
|
|
||||||
gcc "${hostCflags[@]}" \
|
gcc "${hostCflags[@]}" \
|
||||||
"$repo/tests/agi/testAgiView.c" \
|
"$repo/tests/testAgiView.c" \
|
||||||
"$repo/examples/agi/agiRes.c" \
|
"$repo/agiRes.c" \
|
||||||
"$repo/examples/agi/agiPic.c" \
|
"$repo/agiPic.c" \
|
||||||
"$repo/examples/agi/agiView.c" \
|
"$repo/agiView.c" \
|
||||||
"$stubSrc" \
|
"$stubSrc" \
|
||||||
-o "$testView"
|
-o "$testView"
|
||||||
|
|
||||||
gcc "${hostCflags[@]}" \
|
gcc "${hostCflags[@]}" \
|
||||||
"$repo/tests/agi/testAgiVm.c" \
|
"$repo/tests/testAgiVm.c" \
|
||||||
"$repo/examples/agi/agiRes.c" \
|
"$repo/agiRes.c" \
|
||||||
"$repo/examples/agi/agiVm.c" \
|
"$repo/agiVm.c" \
|
||||||
"$repo/examples/agi/agiObj.c" \
|
"$repo/agiObj.c" \
|
||||||
"$stubSrc" \
|
"$stubSrc" \
|
||||||
-o "$testVm"
|
-o "$testVm"
|
||||||
|
|
||||||
gcc "${hostCflags[@]}" \
|
gcc "${hostCflags[@]}" \
|
||||||
"$repo/tests/agi/testAgiPipeline.c" \
|
"$repo/tests/testAgiPipeline.c" \
|
||||||
"$repo/examples/agi/agiRes.c" \
|
"$repo/agiRes.c" \
|
||||||
"$repo/examples/agi/agiVm.c" \
|
"$repo/agiVm.c" \
|
||||||
"$repo/examples/agi/agiObj.c" \
|
"$repo/agiObj.c" \
|
||||||
"$stubSrc" \
|
"$stubSrc" \
|
||||||
-o "$testPipeline"
|
-o "$testPipeline"
|
||||||
|
|
||||||
# Pick the game directories to exercise. With no args, every
|
# Pick the game directories to exercise. With no args, every
|
||||||
# subdirectory of examples/agi/gamedata that contains LOGDIR is a
|
# subdirectory of games/ that contains LOGDIR is a candidate (skips
|
||||||
# candidate (skips stray README files etc).
|
# stray README files etc).
|
||||||
if [[ $# -gt 0 ]]; then
|
if [[ $# -gt 0 ]]; then
|
||||||
games=("$@")
|
games=("$@")
|
||||||
else
|
else
|
||||||
|
|
@ -142,9 +146,10 @@ fi
|
||||||
if [[ ${#games[@]} -eq 0 ]]; then
|
if [[ ${#games[@]} -eq 0 ]]; then
|
||||||
echo
|
echo
|
||||||
echo "No AGI game directories found under $gamedata"
|
echo "No AGI game directories found under $gamedata"
|
||||||
echo "Drop an AGI v2 game in examples/agi/gamedata/<name>/ and rerun."
|
echo "Drop an AGI v2 game in games/<name>/ and rerun."
|
||||||
echo "See examples/agi/gamedata/README.md for the required files."
|
echo "See games/README.md for the required files."
|
||||||
exit 0
|
# Nothing was tested: not a pass (a gate runner reads 2 as skipped).
|
||||||
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
passed=0
|
passed=0
|
||||||
|
|
|
||||||
86
scripts/verify.sh
Executable file
86
scripts/verify.sh
Executable file
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# verify.sh - JoeyAGI's gates, run one after another, with a summary.
|
||||||
|
#
|
||||||
|
# host the resource loader, PIC and VIEW decoders, the LOGIC VM and the
|
||||||
|
# VM pipeline, built for the host and run against every game in
|
||||||
|
# games/ (scripts/test-agi.sh)
|
||||||
|
# disk the bootable IIgs volume with games/kq3 on it boots on a CFFA2
|
||||||
|
# card, launches the interpreter and draws (make
|
||||||
|
# iigs-game-disk-agi, then JoeyLib's verify-iigs-game-disk.sh with
|
||||||
|
# the 8 MB the interpreter wants)
|
||||||
|
#
|
||||||
|
# Usage: scripts/verify.sh [gate...] every gate when none is named
|
||||||
|
# Env: JOEYLIB the JoeyLib checkout (default ../joeylib)
|
||||||
|
# The disk gate checks what is built: run make first (make check does both).
|
||||||
|
#
|
||||||
|
# Exit codes:
|
||||||
|
# 0 every gate passed
|
||||||
|
# 1 a gate failed
|
||||||
|
# 3 none failed, but one was skipped for a missing prerequisite (an
|
||||||
|
# emulator, the IIgs toolchain, no game in games/) -- not 0, so a run
|
||||||
|
# that tested nothing cannot look green
|
||||||
|
# A gate exits 2 to say it was skipped.
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
|
JOEYLIB=$(cd "${JOEYLIB:-$repo/../joeylib}" && pwd) || { echo "verify: no JoeyLib checkout (set JOEYLIB)" >&2; exit 2; }
|
||||||
|
export JOEYLIB
|
||||||
|
diskGame=kq3
|
||||||
|
|
||||||
|
# name command...: every gate, in run order.
|
||||||
|
GATES=$(cat <<EOF
|
||||||
|
host scripts/test-agi.sh
|
||||||
|
disk [ -f games/$diskGame/LOGDIR ] || { echo "disk: no games/$diskGame to put on the volume" >&2; exit 2; }; make -s iigs-game-disk-agi AGI_GAME=$diskGame || exit 1; $JOEYLIB/scripts/verify-iigs-game-disk.sh build/iigs/bin/AGI.2mg 2 8M
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
names=$(echo "$GATES" | awk '{ print $1 }' | tr '\n' ' ')
|
||||||
|
for want in "$@"; do
|
||||||
|
case " $names " in
|
||||||
|
*" $want "*) ;;
|
||||||
|
*) echo "verify: unknown gate '$want' (choose from: $names)" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
selected=${*:-$names}
|
||||||
|
|
||||||
|
gateNames=()
|
||||||
|
gateVerdicts=()
|
||||||
|
gateSeconds=()
|
||||||
|
passed=0
|
||||||
|
failed=0
|
||||||
|
skipped=0
|
||||||
|
|
||||||
|
while read -r name cmd; do
|
||||||
|
case " $selected " in *" $name "*) ;; *) continue ;; esac
|
||||||
|
echo
|
||||||
|
echo "=== verify: $name ($cmd) ==="
|
||||||
|
start=$SECONDS
|
||||||
|
( cd "$repo" && bash -c "$cmd" ) < /dev/null
|
||||||
|
case $? in
|
||||||
|
0) verdict=PASS; passed=$((passed + 1)) ;;
|
||||||
|
2) verdict="SKIP (prerequisite missing)"; skipped=$((skipped + 1)) ;;
|
||||||
|
*) verdict=FAIL; failed=$((failed + 1)) ;;
|
||||||
|
esac
|
||||||
|
gateNames+=("$name")
|
||||||
|
gateVerdicts+=("$verdict")
|
||||||
|
gateSeconds+=("$((SECONDS - start))")
|
||||||
|
done <<< "$GATES"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "================ verify summary ================"
|
||||||
|
for i in "${!gateNames[@]}"; do
|
||||||
|
printf " %-10s %-28s %4ds\n" "${gateNames[$i]}" "${gateVerdicts[$i]}" "${gateSeconds[$i]}"
|
||||||
|
done
|
||||||
|
echo " ----"
|
||||||
|
printf " %d passed, %d failed, %d skipped\n" "$passed" "$failed" "$skipped"
|
||||||
|
|
||||||
|
if [ "$failed" -gt 0 ]; then
|
||||||
|
echo "verify: FAIL" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$skipped" -gt 0 ]; then
|
||||||
|
echo "verify: INCOMPLETE - some gates skipped (see above)" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
echo "verify: PASS (all $passed gates)"
|
||||||
|
exit 0
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Host-side test for examples/agi/agiPic.c.
|
// Host-side test for agiPic.c.
|
||||||
//
|
//
|
||||||
// Loads a single PIC resource from a game directory, decodes it, and
|
// Loads a single PIC resource from a game directory, decodes it, and
|
||||||
// writes two image files: a color PPM for the visual plane (palette
|
// writes two image files: a color PPM for the visual plane (palette
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Host-side regression test for examples/agi/agiRes.c.
|
// Host-side regression test for agiRes.c.
|
||||||
//
|
//
|
||||||
// The AGI resource loader is plain stdio C with no JoeyLib runtime
|
// The AGI resource loader is plain stdio C with no JoeyLib runtime
|
||||||
// dependencies, so we can compile and exercise it on the build host
|
// dependencies, so we can compile and exercise it on the build host
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Host-side test for examples/agi/agiView.c.
|
// Host-side test for agiView.c.
|
||||||
//
|
//
|
||||||
// Loads a single VIEW resource, parses it, dumps the loop/cel
|
// Loads a single VIEW resource, parses it, dumps the loop/cel
|
||||||
// structure, and writes cel 0 of every loop as a PPM image. The
|
// structure, and writes cel 0 of every loop as a PPM image. The
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Host-side test for examples/agi/agiVm.c (Phase 1 sub-A).
|
// Host-side test for agiVm.c (Phase 1 sub-A).
|
||||||
//
|
//
|
||||||
// Loads a LOGIC resource (default 0), runs the VM until it halts,
|
// Loads a LOGIC resource (default 0), runs the VM until it halts,
|
||||||
// and prints the halt reason plus any non-zero vars/flags. Since
|
// and prints the halt reason plus any non-zero vars/flags. Since
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue