128 lines
4.4 KiB
Bash
128 lines
4.4 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 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 (scripts/lib/dosboxKeys.sh), so no
|
|
# Ctrl reaches the program. The mapper replaces every DOSBox binding: only
|
|
# these keys and Escape reach the machine. Source after joyGate.sh.
|
|
#
|
|
# DOSBOX_JOY_SETTINGS [joystick] settings every run needs
|
|
# ("name=value"); DOSBOX_JOY_SET_ARGS has them
|
|
# as DOSBox --set arguments
|
|
# dosboxJoyMapper FILE write the mapper file
|
|
# dosboxJoyTap NAME press and let go of a key of the table
|
|
# (escape)
|
|
# 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).
|
|
|
|
source "$JOEY_REPO/scripts/lib/dosboxKeys.sh"
|
|
|
|
DOSBOX_JOY_DISPLAY=""
|
|
DOSBOX_JOY_WINDOW=""
|
|
DOSBOX_JOY_SHOTS=""
|
|
DOSBOX_JOY_TAP_SECONDS=0.3
|
|
|
|
# DOSBox Staging 0.83's 4axis sticks wrap buttons at two when no host
|
|
# joystick is open: CStickBindGroup sets the wrap to its two buttons, and
|
|
# C4AxisBindGroup raises the count to four but copies it to the wrap only
|
|
# with buttonwrap on, so stick B's buttons would press stick A's. buttonwrap
|
|
# on wraps at four. A host pad DOSBox opened set the wrap to its own button
|
|
# count and hid this, and would add its own axes and buttons, so every host
|
|
# pad is hidden from DOSBox's SDL (an id no device has is the only one let
|
|
# through) and the runs are the same whatever is plugged in.
|
|
DOSBOX_JOY_SETTINGS=("buttonwrap=on")
|
|
DOSBOX_JOY_SET_ARGS=()
|
|
for setting in "${DOSBOX_JOY_SETTINGS[@]}"; do
|
|
DOSBOX_JOY_SET_ARGS+=(--set "$setting")
|
|
done
|
|
unset setting
|
|
export SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT=0x0000/0x0000
|
|
|
|
# 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"
|
|
"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 code
|
|
local event
|
|
local entries=()
|
|
for entry in "${DOSBOX_JOY_KEYS[@]}"; do
|
|
read -r _ _ code event <<< "$entry"
|
|
entries+=("$code $event")
|
|
done
|
|
dosboxKeysMapper "$1" "${entries[@]}"
|
|
}
|
|
|
|
|
|
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 "$@"
|
|
}
|
|
|
|
|
|
joyShot() {
|
|
dosboxShot "$DOSBOX_JOY_DISPLAY" "$DOSBOX_JOY_WINDOW" "$DOSBOX_JOY_SHOTS" "$1"
|
|
}
|