115 lines
5 KiB
Bash
Executable file
115 lines
5 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
|
|
#
|
|
# verify-win16-joy.sh - Joystick gate for the Win16 port: both sticks,
|
|
# every direction, both buttons and every release, driven through DOSBox
|
|
# Staging's emulated game port, read by Windows through KPJOY.DRV (the
|
|
# joystick driver JoeyLib's Windows runs with, component kpjoy) and read
|
|
# back from what examples/joy draws; and no joystick at all when the game
|
|
# port is empty.
|
|
#
|
|
# The port (src/hosted/win16) reads the first two sticks through MMSYSTEM's
|
|
# joyGetPos, scaled by joyGetDevCaps's ranges. DOSBox Staging's joysticktype
|
|
# 4axis puts four axes and four buttons on the game port with no host
|
|
# joystick, which KPJOY reads as two sticks, A and B, as a Y cable gives
|
|
# them; it takes each axis's rest from its first readings and reports
|
|
# readings near the rest as the rest, so the dots sit exactly in the middle
|
|
# through the jitter interrupts give the counts. KPJOY counts reads of the
|
|
# port, so the emulated CPU runs at a fixed speed, as a real PC's does: at
|
|
# DOSBox's max cycles (how joey-run runs Windows) the speed follows this
|
|
# machine's load, and the counts with it. A mapper file binds host keys to
|
|
# DOSBox's joystick events (scripts/lib/dosboxJoy.sh) and xdotool holds
|
|
# them; the raw screenshot is on a key of its own, so no Ctrl reaches
|
|
# Windows. The mapper also leaves out any joystick plugged into this
|
|
# machine, so nothing else moves the sticks: they rest in the middle,
|
|
# buttons up.
|
|
#
|
|
# JOY (examples/joy) is Windows' shell, at one window pixel per stage pixel;
|
|
# tests/gate/joyScreen.c reads both sticks' whole state off each
|
|
# screenshot of the 800x600 screen (scripts/lib/joyGate.sh's steps). Escape
|
|
# then ends JOY, and with it Windows and DOSBox.
|
|
#
|
|
# Second run, joysticktype disabled: no game port, so JOY must show both
|
|
# sticks disconnected.
|
|
#
|
|
# Usage: scripts/verify-win16-joy.sh
|
|
# Env: JOY_SHOTS also keep the screenshots in this folder
|
|
# Requires: DOSBox Staging, Xvfb, xdotool, the win311 and
|
|
# kpjoy components; JOY.EXE (make win16).
|
|
set -uo pipefail
|
|
|
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
source "$repo/scripts/lib/joeyEnv.sh"
|
|
source "$repo/scripts/lib/joyGate.sh"
|
|
source "$repo/scripts/lib/dosboxJoy.sh"
|
|
source "$repo/scripts/lib/win16Gate.sh"
|
|
win16Need
|
|
|
|
JOY_LABEL=verify-win16-joy
|
|
JOY_SCALE=1
|
|
program=$(joeyExampleProgram joy win16)
|
|
[ -f "$program" ] || { echo "$JOY_LABEL: build JOY.EXE first (make win16)" >&2; exit 2; }
|
|
upSeconds=60 # Windows booting until JOY's screen is there
|
|
exitSeconds=20 # Escape until Windows and DOSBox have ended
|
|
fixedCycles=60000 # the emulated CPU's speed (DOSBox cycles per ms)
|
|
|
|
JOY_WORK=$(mktemp -d -t joeylib-win16-joy.XXXXXX)
|
|
cleanup() {
|
|
win16Stop
|
|
rm -rf "$JOY_WORK"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
|
|
# boot RUN JOYTYPE -- Windows staged in $JOY_WORK/RUN with JOY its shell,
|
|
# DOSBox's joysticktype JOYTYPE and the joystick mapper; waits for JOY's
|
|
# screen.
|
|
boot() {
|
|
local dir="$JOY_WORK/$1"
|
|
local waited
|
|
mkdir -p "$dir/program" "$dir/shots"
|
|
cp "$program" "$dir/program/JOY.EXE"
|
|
win16Stage "$dir" "$dir/program" JOY.EXE
|
|
dosboxJoyMapper "$dir/mapper.txt"
|
|
DOSBOX_JOY_SHOTS="$dir/shots"
|
|
WIN16_DOSBOX_ARGS=(--set "capture_dir=$dir/shots" --set "default_image_capture_formats=raw"
|
|
--set "joysticktype=$2" "${DOSBOX_JOY_SET_ARGS[@]}" --set "mapperfile=$dir/mapper.txt"
|
|
--set "cpu_cycles=$fixedCycles" --set "cpu_cycles_protected=$fixedCycles")
|
|
win16Start "$dir" JOEYLIB_SCALE=1 JOEYLIB_ASPECT=square
|
|
DOSBOX_JOY_DISPLAY="$WIN16_DISPLAY"
|
|
for ((waited = 0; waited < upSeconds; waited++)); do
|
|
joeyAlive "$WIN16_PID" || return 1
|
|
DOSBOX_JOY_WINDOW=$(win16Window) && break
|
|
sleep 1
|
|
done
|
|
[ -n "$DOSBOX_JOY_WINDOW" ] || return 1
|
|
DISPLAY="$DOSBOX_JOY_DISPLAY" xdotool windowactivate --sync "$DOSBOX_JOY_WINDOW" 2> /dev/null || true
|
|
for ((; waited < upSeconds; waited++)); do
|
|
joyShot "$dir/up.png" && "$(joeyTool joyScreen)" "$dir/up.png" --scale "$JOY_SCALE" > /dev/null 2>&1 && return 0
|
|
joeyAlive "$WIN16_PID" || return 1
|
|
sleep 1
|
|
done
|
|
return 1
|
|
}
|
|
|
|
|
|
# 1. Both sticks on the game port, moved through the mapper.
|
|
boot sticks 4axis || { echo "$JOY_LABEL: FAIL - Windows with JOY did not come up within ${upSeconds} s" >&2; exit 1; }
|
|
joyCheck "rest" "A=$JOY_REST B=$JOY_REST"
|
|
joyRunSteps "${JOY_STEPS_TWO_STICKS[@]}"
|
|
dosboxJoyTap escape
|
|
for ((waited = 0; waited < exitSeconds; waited++)); do
|
|
joeyAlive "$WIN16_PID" || break
|
|
sleep 1
|
|
done
|
|
joeyAlive "$WIN16_PID" && joyFail "Escape did not end JOY, and Windows with it, within ${exitSeconds} s"
|
|
win16Stop
|
|
|
|
# 2. No game port: no stick.
|
|
boot none disabled || { echo "$JOY_LABEL: FAIL - Windows with JOY and no game port did not come up within ${upSeconds} s" >&2; exit 1; }
|
|
joyCheck "no joystick" "A=$JOY_ABSENT B=$JOY_ABSENT"
|
|
win16Stop
|
|
|
|
joyResult "$JOY_LABEL" "both sticks through KPJOY.DRV, every direction, both buttons and every release; no stick without a game port"
|