84 lines
3 KiB
Bash
Executable file
84 lines
3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
|
|
# See LICENSE.md for license information.
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# check-modplayer.sh - Host gate for src/core/modPlayer.c, the module player
|
|
# every port that mixes .MOD in software plays through (DOS, the ST, the
|
|
# X68000, and the hosted ports). Builds tests/host/modPlayerHost.c, which
|
|
# includes the player, with the host cc and the address and undefined-
|
|
# behaviour sanitizers, and runs it: the Protracker behaviours the player
|
|
# keeps, where a song ends, the 8-bit and 16-bit outputs, and mangled
|
|
# modules played without reading outside the player's copy. When the
|
|
# Amiga's PTPlayer is installed, its period and vibrato tables are handed
|
|
# over too, and the player's must match them.
|
|
#
|
|
# Usage: scripts/check-modplayer.sh
|
|
# Exit: 0 PASS, 1 FAIL
|
|
set -uo pipefail
|
|
|
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
source "$repo/scripts/lib/joeyEnv.sh"
|
|
label=check-modplayer
|
|
cc=${CC:-cc}
|
|
|
|
work=$(mktemp -d -t joeylib-modplayer.XXXXXX)
|
|
trap 'rm -rf "$work"' EXIT
|
|
|
|
cd "$repo"
|
|
if ! "$cc" -O1 -g -fsanitize=address,undefined -fno-sanitize-recover=all -DJOEYLIB_PLATFORM_BLANK \
|
|
-Iinclude -Iinclude/joey -Isrc/core -Wall -Wextra -Werror \
|
|
tests/host/modPlayerHost.c -lm -o "$work/modPlayerHost"; then
|
|
echo "$label: FAIL - the harness did not build"
|
|
exit 1
|
|
fi
|
|
|
|
# PTPlayer's mt_PeriodTable, then its three vibrato tables, as numbers.
|
|
tables=()
|
|
asm="${AMIGA_PTPLAYER:-}/ptplayer.asm"
|
|
if [ -f "$asm" ]; then
|
|
awk -v out="$work/tables.txt" '
|
|
index($0, "mt_PeriodTable:") && !periodsDone {
|
|
inPeriods = 1
|
|
}
|
|
inPeriods && $0 == "" {
|
|
inPeriods = 0
|
|
periodsDone = 1
|
|
}
|
|
index($0, "mt_VibratoSineTable:") && !wavesDone {
|
|
inWaves = 1
|
|
}
|
|
index($0, "mt_VibratoRectTable:") {
|
|
afterRect = 1
|
|
}
|
|
inWaves && afterRect && index($0, "endc") {
|
|
inWaves = 0
|
|
wavesDone = 1
|
|
}
|
|
(inPeriods || inWaves) && match($0, /^[ \t]*dc\.[bw][ \t]+/) {
|
|
list = substr($0, RLENGTH + 1)
|
|
sub(/;.*/, "", list)
|
|
n = split(list, values, ",")
|
|
for (i = 1; i <= n; i++) {
|
|
if (inPeriods) {
|
|
periods = periods (periods == "" ? "" : " ") (values[i] + 0)
|
|
} else {
|
|
waves = waves (waves == "" ? "" : " ") (values[i] + 0)
|
|
}
|
|
}
|
|
}
|
|
END {
|
|
printf "periods %s\nvibrato %s\n", periods, waves > out
|
|
}' "$asm"
|
|
tables=("$work/tables.txt")
|
|
fi
|
|
|
|
output=$("$work/modPlayerHost" "${tables[@]}" 2>&1)
|
|
status=$?
|
|
echo "$output" | grep -v '^MODPLAYER'
|
|
counts=$(sed -n 's/^MODPLAYER //p' <<< "$output")
|
|
if [ "$status" -ne 0 ]; then
|
|
echo "$label: FAIL - ${counts:-harness error} checks pass"
|
|
exit 1
|
|
fi
|
|
echo "$label: PASS ($counts checks: Protracker's behaviours, song ends, both outputs, and mangled modules, under the sanitizers)"
|