joeylib2/scripts/lib/dosboxKeys.sh

79 lines
2.8 KiB
Bash

# shellcheck shell=bash
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
#
# Shared by the gates that read DOSBox's raw screenshots (verify-dos-input.sh,
# verify-win16-input.sh, and the joystick gates through dosboxJoy.sh).
# DOSBox's own screenshot key, Ctrl+F5, hands the program a Ctrl press, so
# the screenshot goes on F11 in a mapper file instead; and a mapper file
# replaces every binding DOSBox has, so it binds each key the gate types or
# holds too.
#
# dosboxKeysMapper FILE ENTRY... write a mapper file: F11 as the raw
# screenshot, and each ENTRY ("SDL-scancode
# mapper-event"); DOSBOX_KEYS_TYPING has the keys the
# input gates type, DOSBOX_KEYS_NAMED the ones they hold
# dosboxShot DISPLAY WINDOW DIR OUT
# press F11 and move the raw screenshot DOSBox writes in
# DIR (its capture_dir) to OUT; 1 when none came
DOSBOX_SHOT_KEY=F11
DOSBOX_SHOT_SCANCODE=68
DOSBOX_SHOT_SECONDS=5 # the screenshot key until DOSBox has written the file
DOSBOX_SHOT_TAP_SECONDS=0.3
# The RetroNet string's keys: the digits, the period, and the colon (Shift
# and the semicolon).
DOSBOX_KEYS_TYPING=(
"30 key_1" "31 key_2" "32 key_3" "33 key_4" "34 key_5"
"35 key_6" "36 key_7" "37 key_8" "38 key_9" "39 key_0"
"55 key_period" "51 key_semicolon" "225 key_lshift"
)
# scripts/lib/keysGate.sh's keys, and the left Ctrl and Alt.
DOSBOX_KEYS_NAMED=(
"82 key_up" "96 key_kp_8" "90 key_kp_2" "92 key_kp_4" "94 key_kp_6"
"88 key_kp_enter" "224 key_lctrl" "228 key_rctrl" "226 key_lalt" "230 key_ralt"
)
dosboxKeysMapper() {
local file="$1"
local entry
local code
local event
shift
{
printf 'hand_rawshot "key %s"\n' "$DOSBOX_SHOT_SCANCODE"
for entry in "$@"; do
read -r code event <<< "$entry"
printf '%s "key %s"\n' "$event" "$code"
done
} > "$file"
}
# DOSBox makes the file before it writes it: it is done when it has bytes
# and one more poll adds none.
dosboxShot() {
local before
local found
local size=""
local deadline
before=$(find "$3" -name '*.png' | wc -l)
DISPLAY="$1" xdotool keydown --window "$2" "$DOSBOX_SHOT_KEY"
sleep "$DOSBOX_SHOT_TAP_SECONDS"
DISPLAY="$1" xdotool keyup --window "$2" "$DOSBOX_SHOT_KEY"
deadline=$((SECONDS + DOSBOX_SHOT_SECONDS))
while [ "$SECONDS" -lt "$deadline" ]; do
sleep 0.2
[ "$(find "$3" -name '*.png' | wc -l)" -gt "$before" ] || continue
found=$(ls -t "$3"/*.png | head -1)
[ -s "$found" ] || continue
if [ "$(stat -c %s "$found")" = "$size" ]; then
mv "$found" "$4"
return 0
fi
size=$(stat -c %s "$found")
done
return 1
}