2023-11-10 00:08:15 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
2024-01-13 02:18:35 +00:00
|
|
|
. /etc/profile
|
|
|
|
|
2023-11-10 00:08:15 +00:00
|
|
|
# -- Config & Setup --
|
|
|
|
# Destination file
|
2024-01-13 06:42:58 +00:00
|
|
|
if [[ -z "$1" ]] && [[ -z "$2" ]]; then
|
|
|
|
echo "Usage: mapper.txt [gamecontrollerdb.txt] [controlfolder]"
|
2023-11-10 00:08:15 +00:00
|
|
|
exit -1
|
|
|
|
fi
|
|
|
|
|
|
|
|
CONTROLLER_DB="$1"
|
2024-01-13 06:42:58 +00:00
|
|
|
controlfolder="$2"
|
2024-01-13 02:18:35 +00:00
|
|
|
|
|
|
|
#Scrub the CONTROLLER_DB file
|
2024-01-13 06:42:58 +00:00
|
|
|
echo "" > ${CONTROLLER_DB}
|
2023-11-10 00:08:15 +00:00
|
|
|
|
|
|
|
# Where the emulationstation configuration file is
|
|
|
|
ES_CONFIG="${HOME}/.config/emulationstation/es_input.cfg"
|
|
|
|
|
2024-01-13 02:18:35 +00:00
|
|
|
#Set layout via Emulation Station
|
|
|
|
ACTIVE_GAME=""
|
|
|
|
GAME="${ACTIVE_GAME##*/}"
|
|
|
|
CONTROLLER_LAYOUT=$(get_setting port_controller_layout ports "${GAME}")
|
|
|
|
|
|
|
|
#Default to nintendo if no value assigned
|
|
|
|
if [ ! -n "${CONTROLLER_LAYOUT}" ]; then
|
|
|
|
CONTROLLER_LAYOUT="nintendo"
|
|
|
|
fi
|
|
|
|
|
2024-01-13 06:42:58 +00:00
|
|
|
scriptdir="controller_layout"
|
|
|
|
|
|
|
|
if [ ! -d "${controlfolder}/${scriptdir}" ]; then
|
|
|
|
mkdir -p "${controlfolder}/${scriptdir}"
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo -e "# Xbox Layout\nABUT=\"b\"\nBBUT=\"a\"\nXBUT=\"y\"\nYBUT=\"x\"" > "${controlfolder}/${scriptdir}/xbox_layout.txt"
|
|
|
|
echo -e "# Nintendo Layout\nABUT=\"a\"\nBBUT=\"b\"\nXBUT=\"x\"\nYBUT=\"y\"" > "${controlfolder}/${scriptdir}/nintendo_layout.txt"
|
2024-01-13 06:52:14 +00:00
|
|
|
if [[ ! -e "${controlfolder}/${scriptdir}/custom_layout.txt" ]]; then
|
2024-01-13 06:42:58 +00:00
|
|
|
echo -e "# Custom Layout\nABUT=\"a\"\nBBUT=\"b\"\nXBUT=\"x\"\nYBUT=\"y\"" > "${controlfolder}/${scriptdir}/custom_layout.txt"
|
2024-01-13 02:18:35 +00:00
|
|
|
fi
|
|
|
|
|
2024-01-13 06:42:58 +00:00
|
|
|
source "${controlfolder}/${scriptdir}/${CONTROLLER_LAYOUT}_layout.txt"
|
|
|
|
|
2023-11-10 00:08:15 +00:00
|
|
|
# -- Helper function --
|
|
|
|
# Map the actual button/hat/axis
|
|
|
|
function map {
|
|
|
|
INPUT_NAME=$1
|
|
|
|
TYPE=$2
|
|
|
|
ID=$3
|
|
|
|
VALUE=$4
|
|
|
|
|
|
|
|
map_x_result=""
|
|
|
|
case "${INPUT_NAME}" in
|
2024-01-13 02:18:35 +00:00
|
|
|
"a") TR_NAME="${ABUT}";;
|
|
|
|
"b") TR_NAME="${BBUT}";;
|
|
|
|
"x") TR_NAME="${XBUT}";;
|
|
|
|
"y") TR_NAME="${YBUT}";;
|
2023-11-10 00:08:15 +00:00
|
|
|
"hotkeyenable") TR_NAME="guide";;
|
|
|
|
"up") TR_NAME="dpup";;
|
|
|
|
"down") TR_NAME="dpdown";;
|
|
|
|
"left") TR_NAME="dpleft";;
|
|
|
|
"right") TR_NAME="dpright";;
|
|
|
|
"leftshoulder") TR_NAME="leftshoulder";;
|
|
|
|
"leftthumb") TR_NAME="leftstick";;
|
|
|
|
"lefttrigger") TR_NAME="lefttrigger";;
|
|
|
|
"rightshoulder") TR_NAME="rightshoulder";;
|
|
|
|
"rightthumb") TR_NAME="rightstick";;
|
|
|
|
"righttrigger") TR_NAME="righttrigger";;
|
|
|
|
"select") TR_NAME="back";;
|
|
|
|
"start") TR_NAME="start";;
|
|
|
|
"leftanalogup") TR_NAME="-lefty";;
|
|
|
|
"leftanalogleft") TR_NAME="-leftx";;
|
|
|
|
"leftanalogdown") TR_NAME="+lefty";;
|
|
|
|
"leftanalogright") TR_NAME="+leftx";;
|
|
|
|
"rightanalogup") TR_NAME="-righty";;
|
|
|
|
"rightanalogleft") TR_NAME="-rightx";;
|
|
|
|
"rightanalogdown") TR_NAME="+righty";;
|
|
|
|
"rightanalogright") TR_NAME="+rightx";;
|
|
|
|
*)
|
|
|
|
echo "Invalid mapping ${INPUT_NAME}."
|
|
|
|
return
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
case "${TYPE}" in
|
|
|
|
"axis")
|
|
|
|
if (( $VALUE < 0 )); then
|
|
|
|
map_x_result="${TR_NAME}:${map_x_result}-a${ID},"
|
|
|
|
else
|
|
|
|
# Most (save for a few misbehaved children...) triggers are [0, 1] instead of [-1, 1]
|
|
|
|
# Shitty workaround for an emulationstation issue
|
|
|
|
if [[ $INPUT_NAME =~ .*"trigger" ]]; then
|
|
|
|
map_x_result="${TR_NAME}:${map_x_result}a${ID},"
|
|
|
|
else
|
|
|
|
map_x_result="${TR_NAME}:${map_x_result}+a${ID},"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
"button")
|
|
|
|
map_x_result="${TR_NAME}:${map_x_result}b${ID},"
|
|
|
|
;;
|
|
|
|
"hat")
|
|
|
|
map_x_result="${TR_NAME}:${map_x_result}h${ID}.${VALUE},"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "Invalid entry ${TYPE}"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_map_suffix {
|
|
|
|
map_suffix="platform:Linux,"
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_map_prefix {
|
|
|
|
map_prefix="${GUID},${NAME},"
|
|
|
|
}
|
|
|
|
|
|
|
|
# query controllers mapped in emulationstation, ignore devices without a GUID
|
|
|
|
ES_QUERY="$(xmlstarlet sel -T -t -m "inputList/inputConfig[@deviceGUID!='']" -n -v "concat(@deviceName,';',@deviceGUID)" $ES_CONFIG)"
|
2024-01-13 06:42:58 +00:00
|
|
|
printf "# ${CONTROLLER_LAYOUT} layout\n" >> "${CONTROLLER_DB}"
|
2023-11-10 00:08:15 +00:00
|
|
|
|
|
|
|
echo "## ES Dev Mapper ##"
|
|
|
|
while IFS=";" read -r NAME GUID; do
|
|
|
|
echo "$NAME :: $GUID"
|
|
|
|
# Ignore keyboards
|
|
|
|
if [[ "${GUID}" == -1 ]]; then
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Query this specific GUID on the mappings
|
|
|
|
MAPPING_CFG=$(xmlstarlet sel -T -t -m "//inputConfig[@deviceGUID = '${GUID}']/input" -n -v "concat(@name,';',@type,';',@id,';',@value)" $ES_CONFIG)
|
|
|
|
|
|
|
|
MAPPING=""
|
|
|
|
while IFS=";" read -r -e INPUT_NAME TYPE ID VALUE; do
|
|
|
|
# Map the controller
|
|
|
|
map "${INPUT_NAME}" "${TYPE}" "${ID}" "${VALUE}"
|
2024-01-13 02:18:35 +00:00
|
|
|
|
2023-11-10 00:08:15 +00:00
|
|
|
# Only concatenate valid mappings
|
|
|
|
if [[ ! -z ${map_x_result} ]]; then
|
|
|
|
MAPPING="${MAPPING}${map_x_result}"
|
|
|
|
fi
|
|
|
|
done <<< ${MAPPING_CFG:1}
|
2024-01-13 02:18:35 +00:00
|
|
|
|
2023-11-10 00:08:15 +00:00
|
|
|
get_map_prefix
|
|
|
|
get_map_suffix
|
|
|
|
if [[ ! -z "${MAPPING}" ]]; then
|
|
|
|
echo "${map_prefix}${MAPPING}${map_suffix}" >> "${CONTROLLER_DB}"
|
|
|
|
else
|
|
|
|
echo "Failed to map anything."
|
|
|
|
fi
|
|
|
|
done <<< ${ES_QUERY:1}
|
2024-01-13 02:18:35 +00:00
|
|
|
|
|
|
|
#Reset file for next run
|
|
|
|
sed -i '/^ACTIVE_GAME=/c\ACTIVE_GAME=""' /storage/.config/PortMaster/mapper.txt
|