127 lines
4 KiB
Bash
127 lines
4 KiB
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 joystick gates that run in DOSBox Staging (DOS, DVX,
|
|
# Win16): how a stick is moved and how JOY is photographed there. DOSBox's
|
|
# joysticktype 4axis puts four axes and four buttons on the game port with
|
|
# no host joystick, which a two-stick reader takes as sticks A (axes 0-1,
|
|
# buttons 0-1) and B (axes 2-3, buttons 2-3), as a Y cable gives them. A
|
|
# mapper file binds a host key to each line and xdotool holds the keys; the
|
|
# raw screenshot is on a key of its own (F11), so no Ctrl reaches the
|
|
# program. The mapper replaces every DOSBox binding: only these keys and
|
|
# Escape reach the machine. Source after joyGate.sh.
|
|
#
|
|
# dosboxJoyMapper FILE write the mapper file
|
|
# dosboxJoyTap NAME press and let go of a key of the table
|
|
# (escape, shot)
|
|
# joyPress / joyRelease joyGate.sh's: hold the controls' keys
|
|
# joyShot PNG joyGate.sh's: the raw screenshot as PNG
|
|
#
|
|
# The gate sets DOSBOX_JOY_DISPLAY and DOSBOX_JOY_WINDOW (DOSBox's X
|
|
# display and window) and DOSBOX_JOY_SHOTS (its capture_dir).
|
|
|
|
DOSBOX_JOY_DISPLAY=""
|
|
DOSBOX_JOY_WINDOW=""
|
|
DOSBOX_JOY_SHOTS=""
|
|
DOSBOX_JOY_SHOT_SECONDS=5 # the screenshot key until DOSBox has written the file
|
|
DOSBOX_JOY_TAP_SECONDS=0.3
|
|
|
|
# Control or name, its host key (xdotool's name), the key's SDL scancode and
|
|
# the DOSBox mapper event it drives.
|
|
DOSBOX_JOY_KEYS=(
|
|
"A-left j 13 jaxis_0_0-" "A-right l 15 jaxis_0_0+"
|
|
"A-up i 12 jaxis_0_1-" "A-down k 14 jaxis_0_1+"
|
|
"A-button0 a 4 jbutton_0_0" "A-button1 s 22 jbutton_0_1"
|
|
"B-left f 9 jaxis_0_2-" "B-right h 11 jaxis_0_2+"
|
|
"B-up t 23 jaxis_0_3-" "B-down g 10 jaxis_0_3+"
|
|
"B-button0 q 20 jbutton_0_2" "B-button1 w 26 jbutton_0_3"
|
|
"shot F11 68 hand_rawshot"
|
|
"escape Escape 41 key_esc"
|
|
)
|
|
|
|
|
|
# dosboxJoyKey NAME -- the host key for a control or name of the table.
|
|
dosboxJoyKey() {
|
|
local entry
|
|
local name
|
|
local key
|
|
for entry in "${DOSBOX_JOY_KEYS[@]}"; do
|
|
read -r name key _ <<< "$entry"
|
|
if [ "$name" = "$1" ]; then
|
|
printf '%s\n' "$key"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
|
|
dosboxJoyMapper() {
|
|
local entry
|
|
local key
|
|
local code
|
|
local event
|
|
for entry in "${DOSBOX_JOY_KEYS[@]}"; do
|
|
read -r _ key code event <<< "$entry"
|
|
printf '%s "key %s"\n' "$event" "$code"
|
|
done > "$1"
|
|
}
|
|
|
|
|
|
dosboxJoyTap() {
|
|
local key
|
|
key=$(dosboxJoyKey "$1") || return 1
|
|
DISPLAY="$DOSBOX_JOY_DISPLAY" xdotool keydown --window "$DOSBOX_JOY_WINDOW" "$key"
|
|
sleep "$DOSBOX_JOY_TAP_SECONDS"
|
|
# A key that ends the program (escape) can take DOSBox's window with it.
|
|
DISPLAY="$DOSBOX_JOY_DISPLAY" xdotool keyup --window "$DOSBOX_JOY_WINDOW" "$key" 2> /dev/null || true
|
|
}
|
|
|
|
|
|
# dosboxJoyHold keydown|keyup CONTROL...
|
|
dosboxJoyHold() {
|
|
local action="$1"
|
|
local control
|
|
local key
|
|
shift
|
|
for control in "$@"; do
|
|
key=$(dosboxJoyKey "$control") || { joyFail "no key for $control"; continue; }
|
|
DISPLAY="$DOSBOX_JOY_DISPLAY" xdotool "$action" --window "$DOSBOX_JOY_WINDOW" "$key"
|
|
done
|
|
}
|
|
|
|
|
|
joyPress() {
|
|
dosboxJoyHold keydown "$@"
|
|
}
|
|
|
|
|
|
joyRelease() {
|
|
dosboxJoyHold keyup "$@"
|
|
}
|
|
|
|
|
|
# DOSBox makes the file before it writes it: it is done when it has bytes
|
|
# and one more poll adds none.
|
|
joyShot() {
|
|
local before
|
|
local found
|
|
local size=""
|
|
local deadline
|
|
before=$(find "$DOSBOX_JOY_SHOTS" -name '*.png' | wc -l)
|
|
dosboxJoyTap shot
|
|
deadline=$((SECONDS + DOSBOX_JOY_SHOT_SECONDS))
|
|
while [ "$SECONDS" -lt "$deadline" ]; do
|
|
sleep 0.2
|
|
[ "$(find "$DOSBOX_JOY_SHOTS" -name '*.png' | wc -l)" -gt "$before" ] || continue
|
|
found=$(ls -t "$DOSBOX_JOY_SHOTS"/*.png | head -1)
|
|
[ -s "$found" ] || continue
|
|
if [ "$(stat -c %s "$found")" = "$size" ]; then
|
|
mv "$found" "$1"
|
|
return 0
|
|
fi
|
|
size=$(stat -c %s "$found")
|
|
done
|
|
return 1
|
|
}
|