mirror of
https://github.com/RetroDECK/RetroDECK.git
synced 2024-11-27 08:05:42 +00:00
Unused files cleanup
This commit is contained in:
parent
3554dcb0a2
commit
1a79017e54
|
@ -1,232 +0,0 @@
|
||||||
## ------------ A - 351ELEC configuration ------------ #
|
|
||||||
|
|
||||||
## Enable D-Pad to analogue at boot until we create a proper toggle
|
|
||||||
global.analogue=1
|
|
||||||
|
|
||||||
## Enable SSH at boot
|
|
||||||
ee_ssh.enabled=1
|
|
||||||
|
|
||||||
## Enable SAMBA at boot
|
|
||||||
ee_samba.enabled=1
|
|
||||||
|
|
||||||
## Enable Bluetooth at boot
|
|
||||||
ee_bluetooth.enabled=0
|
|
||||||
|
|
||||||
## Use maxperf, enable max settings for GPU and performance governer, this setting can be set globally, per platform or per game on the ES menu
|
|
||||||
global.maxperf=0
|
|
||||||
|
|
||||||
## Always show boot video
|
|
||||||
#ee_bootvideo.enabled=0
|
|
||||||
|
|
||||||
## Set video mode
|
|
||||||
ee_videomode=720p60hz
|
|
||||||
|
|
||||||
## What to start at boot Emulationstation or Retroarch
|
|
||||||
ee_boot=Emulationstation
|
|
||||||
|
|
||||||
## Enable splash screens
|
|
||||||
ee_splash.enabled=0
|
|
||||||
|
|
||||||
## set to 1 if you have long loading times after quitting a game, you will lose sound mixing in ES, this only affects S905/S912 devices as all others use alsa.
|
|
||||||
#ee_alsa.always=0
|
|
||||||
|
|
||||||
## Force splash screens to display for X seconds
|
|
||||||
#ee_splash.delay=0
|
|
||||||
|
|
||||||
## Some external HDDs take longer to mount than ES to load, if your external ROMS do not mount in time, increase this timer
|
|
||||||
#ee_load.delay=0
|
|
||||||
|
|
||||||
# Enable Advance mame auto gamepad configuration 1,0 (default 1)
|
|
||||||
advmame_auto_gamepad=0
|
|
||||||
|
|
||||||
## EmulationStation menu style
|
|
||||||
## default -> default all options menu
|
|
||||||
## none -> no menu except the game search menu
|
|
||||||
## bartop -> less menu, only needed for bartops
|
|
||||||
#system.es.menu=default
|
|
||||||
|
|
||||||
# ------------ B - Network ------------ #
|
|
||||||
## Set system hostname
|
|
||||||
system.hostname=351ELEC
|
|
||||||
## Activate wifi (0,1)
|
|
||||||
wifi.enabled=1
|
|
||||||
## Wifi SSID (string)
|
|
||||||
#wifi.ssid=
|
|
||||||
## Wifi KEY (string)
|
|
||||||
## after rebooting the "new key" is replace by a hidden value "enc:xxxxx"
|
|
||||||
## you can edit the "enc:xxxxx" value to replace by a clear value, it will be updated again at the following reboot
|
|
||||||
## Escape your special chars (# ; $) with a backslash : $ => \$
|
|
||||||
#wifi.key=
|
|
||||||
|
|
||||||
# secondary wifi (not configurable via the user interface)
|
|
||||||
#wifi2.ssid=new ssid
|
|
||||||
#wifi2.key=new key
|
|
||||||
|
|
||||||
# third wifi (not configurable via the user interface)
|
|
||||||
#wifi3.ssid=new ssid
|
|
||||||
#wifi3.key=new key
|
|
||||||
|
|
||||||
# ------------ C - Audio ------------ #
|
|
||||||
## Set the audio device (auto, hdmi, jack, speakers, headphones) mostly for OdroidGoAdvance
|
|
||||||
## Set system volume (0..100)
|
|
||||||
## Enable or disable system sounds in ES (0,1)
|
|
||||||
audio.bgmusic=1
|
|
||||||
|
|
||||||
# -------------- D - Controllers ----------------- #
|
|
||||||
# Enable support for standard bluetooth controllers
|
|
||||||
controllers.bluetooth.enabled=1
|
|
||||||
|
|
||||||
# ------------ F - Language and keyboard ------------ #
|
|
||||||
## Set the language of the system (fr_FR,en_US,en_GB,de_DE,pt_BR,es_ES,it_IT,eu_ES,tr_TR,zh_CN)
|
|
||||||
system.language=en_US
|
|
||||||
## Set you local time
|
|
||||||
## Select your timezone from : ls /usr/share/zoneinfo/ (string)
|
|
||||||
system.timezone=Europe/London
|
|
||||||
|
|
||||||
# ------------ G - UPDATES ------------ #
|
|
||||||
## Automatically check for updates at start (0,1)
|
|
||||||
updates.enabled=1
|
|
||||||
updates.type=release
|
|
||||||
|
|
||||||
# fan profile - controls fan speed (values: default/performance/quiet)
|
|
||||||
# Not used for DECK
|
|
||||||
# fan.profile=default
|
|
||||||
|
|
||||||
# ------------ H - HERE IT IS - GLOBAL EMULATOR CONFIGURATION ------------ #
|
|
||||||
## The global value will be used for all emulators, except if the value
|
|
||||||
## is redefined in the emulator
|
|
||||||
|
|
||||||
## Bezel on by default
|
|
||||||
global.bezel=default
|
|
||||||
|
|
||||||
## Retroarch menu driver, ozone (default), rgui or xmb
|
|
||||||
global.retroarch.menu_driver=ozone
|
|
||||||
|
|
||||||
## Shader set
|
|
||||||
## Automatically select shaders for all systems
|
|
||||||
## (none, retro, scanlines)
|
|
||||||
|
|
||||||
## Once enabled, your screen will be cropped, and you will have a pixel perfect image (0,1)
|
|
||||||
global.integerscale=1
|
|
||||||
|
|
||||||
## Set gpslp shader for all emulators (prefer shadersets above). Absolute path (string)
|
|
||||||
#global.shaders=
|
|
||||||
|
|
||||||
## Set ratio for all emulators (auto,4/3,16/9,16/10,custom)
|
|
||||||
global.ratio=4/3
|
|
||||||
|
|
||||||
## Set autosave/load savestate for all emulators (0,1,2,3)
|
|
||||||
global.autosave=2
|
|
||||||
|
|
||||||
## Set incremental savestates for all emulators (0,1)
|
|
||||||
global.incrementalsavestates=0
|
|
||||||
|
|
||||||
## Set runahead frames for all emulators (0,1,2,3,4,5,6)
|
|
||||||
global.runahead=0
|
|
||||||
|
|
||||||
## Set secondinstance for runahead for all emulators (0,1)
|
|
||||||
global.secondinstance=0
|
|
||||||
|
|
||||||
## Enable retroarchievements (0,1)
|
|
||||||
## Set your www.retroachievements.org username/password
|
|
||||||
## Escape your special chars (# ; $) with a backslash : $ => \$
|
|
||||||
global.retroachievements=1
|
|
||||||
global.retroachievements.hardcore=0
|
|
||||||
global.retroachievements.leaderboards=disabled
|
|
||||||
global.retroachievements.challengeindicators=0
|
|
||||||
global.retroachievements.richpresence=0
|
|
||||||
global.retroachievements.testunofficial=0
|
|
||||||
global.retroachievements.soundenable=0
|
|
||||||
global.retroachievements.verbose=0
|
|
||||||
global.retroachievements.screenshot=1
|
|
||||||
global.retroachievements.username=
|
|
||||||
global.retroachievements.password=
|
|
||||||
|
|
||||||
## Enable RetroArch AI game translation service
|
|
||||||
#global.ai_service_enabled=0
|
|
||||||
#global.ai_service_url=
|
|
||||||
#global.ai_target_lang=
|
|
||||||
|
|
||||||
## Configurations generated by Emulationstation
|
|
||||||
audio.display_titles=1
|
|
||||||
audio.persystem=0
|
|
||||||
global.netplay=0
|
|
||||||
global.netplay.port=55435
|
|
||||||
global.netplay.relay=none
|
|
||||||
audio.device=headphone
|
|
||||||
audio.volume=75
|
|
||||||
brightness.level=50
|
|
||||||
system.brightness=50
|
|
||||||
|
|
||||||
## Device Overclock
|
|
||||||
overclock=0
|
|
||||||
|
|
||||||
# ------------ I - EMULATORS CHOICES ----------- #
|
|
||||||
## You can override the global configuration here
|
|
||||||
## Here is the snes example
|
|
||||||
#snes.shaders=mysnesshader.gplsp
|
|
||||||
|
|
||||||
3do.maxperf=1
|
|
||||||
3do.rewind=0
|
|
||||||
arcade.maxperf=1
|
|
||||||
arcade.autosave=0
|
|
||||||
atari2600.ratio=squarepixel
|
|
||||||
atarilynx.ratio=squarepixel
|
|
||||||
atarilynx.shaderset=handheld/lcd3x.glslp
|
|
||||||
atomiswave.maxperf=1
|
|
||||||
dreamcast.maxperf=1
|
|
||||||
fbn.ratio=squarepixel
|
|
||||||
gamegear.bezel.overlay.grid=1
|
|
||||||
gamegear.bezel.overlay.shadow=1
|
|
||||||
gamegear.ratio=squarepixel
|
|
||||||
gb.bezel.overlay.grid=1
|
|
||||||
gb.bezel.overlay.shadow=1
|
|
||||||
gb.ratio=squarepixel
|
|
||||||
gba.ratio=squarepixel
|
|
||||||
gba.shaderset=handheld/lcd3x.glslp
|
|
||||||
gbah.ratio=squarepixel
|
|
||||||
gbah.shaderset=handheld/lcd3x.glslp
|
|
||||||
gbc.bezel.overlay.grid=1
|
|
||||||
gbc.bezel.overlay.shadow=1
|
|
||||||
gbc.ratio=squarepixel
|
|
||||||
gbch.bezel.overlay.grid=1
|
|
||||||
gbch.bezel.overlay.shadow=1
|
|
||||||
gbch.ratio=squarepixel
|
|
||||||
gbh.bezel.overlay.grid=1
|
|
||||||
gbh.bezel.overlay.shadow=1
|
|
||||||
gbh.ratio=squarepixel
|
|
||||||
ggh.bezel.overlay.grid=1
|
|
||||||
ggh.bezel.overlay.shadow=1
|
|
||||||
ggh.ratio=squarepixel
|
|
||||||
j2me.maxperf=1
|
|
||||||
megadrive.ratio=squarepixel
|
|
||||||
mame.autosave=0
|
|
||||||
mame.maxperf=1
|
|
||||||
n64.maxperf=1
|
|
||||||
nds.maxperf=1
|
|
||||||
naomi.maxperf=1
|
|
||||||
ngp.ratio=squarepixel
|
|
||||||
ngp.shaderset=handheld/lcd3x.glslp
|
|
||||||
ngpc.ratio=squarepixel
|
|
||||||
ngpc.shaderset=handheld/lcd3x.glslp
|
|
||||||
pc.maxperf=1
|
|
||||||
pcfx.maxperf=1
|
|
||||||
pokemini.ratio=3/2
|
|
||||||
psp.maxperf=1
|
|
||||||
psp.ratio=squarepixel
|
|
||||||
pspminis.maxperf=1
|
|
||||||
pspminis.ratio=squarepixel
|
|
||||||
psx.integerscaleoverscale=1
|
|
||||||
saturn.ratio=squarepixel
|
|
||||||
segacd.ratio=squarepixel
|
|
||||||
supervision.bezel.overlay.grid=1
|
|
||||||
supervision.bezel.overlay.shadow=1
|
|
||||||
supervision.ratio=squarepixel
|
|
||||||
uzebox.integerscale=1
|
|
||||||
vectrex.ratio=3/4
|
|
||||||
virtualboy.maxperf=1
|
|
||||||
virtualboy.ratio=squarepixel
|
|
||||||
wonderswan.ratio=squarepixel
|
|
||||||
wonderswan.shaderset=handheld/lcd3x.glslp
|
|
||||||
wonderswancolor.ratio=squarepixel
|
|
||||||
wonderswancolor.shaderset=handheld/lcd3x.glslp
|
|
|
@ -1 +0,0 @@
|
||||||
/home/steamos/retrodeck/retroarch.cfg
|
|
|
@ -1,236 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
# Copyright (C) 2020-present Batocera
|
|
||||||
# Copyright (C) 2020-present Fewtarius
|
|
||||||
|
|
||||||
#
|
|
||||||
# Download and install packages supported binary packages
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# 351elec-es-package 'list' or 'install <package>'
|
|
||||||
#
|
|
||||||
# If you don't provide a <package>, the list of packages will be downloaded and sent back to you.
|
|
||||||
#
|
|
||||||
|
|
||||||
ARCH="$(cat /storage/.config/.OS_ARCH)"
|
|
||||||
if [ "${ARCH}" == "RG351P" ]; then
|
|
||||||
DEVICE="RG351P"
|
|
||||||
elif [ "${ARCH}" == "RG351V" ]; then
|
|
||||||
DEVICE="RG351V"
|
|
||||||
elif [ "${ARCH}" == "RG351MP" ]; then
|
|
||||||
DEVICE="RG351MP"
|
|
||||||
elif [ "${ARCH}" == "RG552" ]; then
|
|
||||||
DEVICE="RG552"
|
|
||||||
fi
|
|
||||||
DISTRO="351ELEC"
|
|
||||||
CONFIGDIR="/storage/.config/packages"
|
|
||||||
PACKAGELIST="https://raw.githubusercontent.com/351ELEC/351ELEC-metadata/main/${ARCH}/packages.cfg"
|
|
||||||
LOCALPACKAGELIST="/storage/.config/packages.cfg"
|
|
||||||
|
|
||||||
# Community Package List Schema
|
|
||||||
#
|
|
||||||
# {PACKAGE NAME}|{PACKAGE URL}|{SHA256SUM}
|
|
||||||
#
|
|
||||||
# Half_Life|https://github.com/blah/half-life-1231.zip|d06489dcf04c602ddacc6f80b2809e6d25fd6298c461966e666e19d3188e04be
|
|
||||||
#
|
|
||||||
# packages.cfg must be a plain text pipe delimited file.
|
|
||||||
|
|
||||||
# Community Package Schema
|
|
||||||
#
|
|
||||||
# URL: https://github.com/blah/half-life-1231.zip
|
|
||||||
# Content:
|
|
||||||
# half-life/ <- must match "package" name ^
|
|
||||||
# install.sh <- must be named install.sh/uninstall.sh and be in the package root.
|
|
||||||
# uninstall.sh
|
|
||||||
# Relevant files/directories included in install.sh/uninstall.sh
|
|
||||||
# Minimum:
|
|
||||||
# system-half-life.png
|
|
||||||
# system-half-life-thumb.png
|
|
||||||
#
|
|
||||||
# The package blob may be hosted elsewhere, as long as install.sh is able to download it.
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
# Prepare the system for installation
|
|
||||||
if [ ! -d "${CONFIGDIR}" ]
|
|
||||||
then
|
|
||||||
mkdir -p "${CONFIGDIR}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
function usage() {
|
|
||||||
echo "$0 - downloads and installs packages supported packages in ${DISTRO}"
|
|
||||||
echo " "
|
|
||||||
echo "It accepts two modes: 'list' and 'install <package>'"
|
|
||||||
echo "- 'list' for the list of packages available online, and if they are"
|
|
||||||
echo " [A]vailable to install, [I]nstalled or [?]unknown."
|
|
||||||
echo "- 'install <package>' to install the package, from its package name."
|
|
||||||
echo "- 'remove <package>' to delete an installed package."
|
|
||||||
echo " "
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
function check_url() {
|
|
||||||
[[ "$1" =~ ^(https?|ftp)://.*$ ]] && echo "[A]" || echo "[?]"
|
|
||||||
}
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
function git_name() {
|
|
||||||
echo "$1" | sed "s,.*/\(.*\),\1,"
|
|
||||||
}
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
function repo_name() {
|
|
||||||
echo "$1" | sed "s,.*github.com/\([A-Za-z0-9_-]*\)/.*,\1,"
|
|
||||||
}
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
function list_packages() {
|
|
||||||
fn=$(date +"%s")
|
|
||||||
tmp="/tmp/packages_${fn}"
|
|
||||||
echo "* ${DISTRO} packages *"
|
|
||||||
if [ -f ${LOCALPACKAGELIST} ]; then
|
|
||||||
cp -f "${LOCALPACKAGELIST}" "${tmp}"
|
|
||||||
else
|
|
||||||
curl -H 'Cache-Control: no-cache' -sfL "${PACKAGELIST}" -o "${tmp}" || exit 1
|
|
||||||
sed -i 's/\r$//' "${tmp}"
|
|
||||||
fi
|
|
||||||
while IFS=$'|' read name url shasum; do
|
|
||||||
[ x"${name}" == "x" ] && continue
|
|
||||||
ia=$(check_url "${url}")
|
|
||||||
[ -d "${CONFIGDIR}"/"${name}" ] && ia="[I]"
|
|
||||||
echo "${ia} ${name} - ${url}"
|
|
||||||
done < "${tmp}"
|
|
||||||
[[ -e "${tmp}" ]] && rm "${tmp}"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
function getPer() {
|
|
||||||
TARFILE="$1"
|
|
||||||
TARVAL="$2"
|
|
||||||
while true; do
|
|
||||||
CURVAL=$(stat "$TARFILE" | grep -E '^[ ]*Size:' | sed -e s+'^[ ]*Size: \([0-9][0-9]*\) .*$'+'\1'+)
|
|
||||||
CURVAL=$((CURVAL / 1024 / 1024))
|
|
||||||
PER=$((${CURVAL} * 100 / ${TARVAL}))
|
|
||||||
echo "${PER}% - ${package} - [${TARVAL}MB]"
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
function install_package() {
|
|
||||||
package="$1"
|
|
||||||
success_installed=0
|
|
||||||
fn=$(date +"%s")
|
|
||||||
tmp="/tmp/packages_${fn}"
|
|
||||||
if [ -f ${LOCALPACKAGELIST} ]; then
|
|
||||||
cp -f "${LOCALPACKAGELIST}" "${tmp}"
|
|
||||||
else
|
|
||||||
curl -H 'Cache-Control: no-cache' -sfL "${PACKAGELIST}" -o "${tmp}" || exit 1
|
|
||||||
sed -i 's/\r$//' "${tmp}"
|
|
||||||
fi
|
|
||||||
while IFS=$'|' read name url shasum; do
|
|
||||||
[ x"${name}" != x"${package}" ] && continue
|
|
||||||
ia=$(check_url "${url}")
|
|
||||||
if [ x"${ia}" != x"[A]" ]; then
|
|
||||||
echo "Error - invalid package URL ${url}"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
cd ${CONFIGDIR}
|
|
||||||
filename=$(echo ${url} | sed "s#^.*/##")
|
|
||||||
curl -H 'Cache-Control: no-cache' -sfL "${url}" -o "${filename}" || exit 1
|
|
||||||
if [ -f "${filename}" ]; then
|
|
||||||
echo "Verifying package checksum"
|
|
||||||
dldsum=$(sha256sum ${filename} | awk '{print $1}')
|
|
||||||
if [ ! "${shasum}" == "${dldsum}" ]
|
|
||||||
then
|
|
||||||
echo "Error - Checksum does not match."
|
|
||||||
success_installed=0
|
|
||||||
else
|
|
||||||
echo "Unzipping ${filename} package files >>> 99%"
|
|
||||||
if [ -d "${CONFIGDIR}/${filename}" ]
|
|
||||||
then
|
|
||||||
rm -rf "${CONFIGDIR}/${filename}"
|
|
||||||
fi
|
|
||||||
unzip "${filename}" >/dev/null 2>&1
|
|
||||||
rm "${filename}"
|
|
||||||
echo "Installing ${filename} package"
|
|
||||||
sh ./${package}/install.sh
|
|
||||||
if [ $? == 0 ]
|
|
||||||
then
|
|
||||||
success_installed=1
|
|
||||||
else
|
|
||||||
echo "Error - Installation failed."
|
|
||||||
success_installed=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Error - ${package} zip file could not be downloaded from ${url}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done < "${tmp}"
|
|
||||||
[[ -e "${tmp}" ]] && rm "${tmp}"
|
|
||||||
if [ "${success_installed}" == 1 ]; then
|
|
||||||
echo "${package} is now installed >>> 100%"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "Error - ${package} could not be installed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#
|
|
||||||
function remove_package() {
|
|
||||||
package="$1"
|
|
||||||
success_removed=0
|
|
||||||
filename=${package}
|
|
||||||
if [ -d "${CONFIGDIR}/${package}" ]; then
|
|
||||||
sh ${CONFIGDIR}/${package}/uninstall.sh
|
|
||||||
if [ $? == 0 ]
|
|
||||||
then
|
|
||||||
rm -rf "${CONFIGDIR}"/"${filename}" && success_removed=1
|
|
||||||
else
|
|
||||||
echo "Unable to uninstall ${package}"
|
|
||||||
success_removed=0
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "${package} doesn't appear to be in ${CONFIGDIR}/${filename}"
|
|
||||||
fi
|
|
||||||
if [ "${success_removed}" == 1 ]; then
|
|
||||||
TERMINAL=0 && echo "${package} uninstalled >>>100"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "Error - ${package} could not be removed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
#### Main loop
|
|
||||||
#
|
|
||||||
command="$1"
|
|
||||||
package="$2"
|
|
||||||
|
|
||||||
if ! [ -d "${CONFIGDIR}" ]; then
|
|
||||||
echo "Error - package directory ${CONFIGDIR} is not valid."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ x"${command}" == "xlist" ]; then
|
|
||||||
list_packages
|
|
||||||
elif [ x"${command}" == "xinstall" ]; then
|
|
||||||
[ x"${package}" != "x" ] && install_package ${package} || usage
|
|
||||||
elif [ x"${command}" == "xremove" ]; then
|
|
||||||
[ x"${package}" != "x" ] && remove_package ${package} || usage
|
|
||||||
else
|
|
||||||
usage
|
|
||||||
fi
|
|
|
@ -1,373 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ ! "$1" ];then
|
|
||||||
echo -e "usage : batocera-config [command] [args]\nWith command in\n\toverscan [enable|disable]\n\tlsaudio\n\tgetaudio\n\taudio [hdmi|jack|auto|custom|x,y]\n\tcanupdate\n\tupdate\n\twifi [enable|disable] ssid key\n\tstorage [current|list|INTERNAL|ANYEXTERNAL|RAM|DEV UUID]\n\tsetRootPassword [password]\n\tgetRootPassword\n\ttz [|tz]"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
configFile="/storage/.config/distribution/configs/config.txt"
|
|
||||||
storageFile="/storage/.config/distribution/configs/batocera-boot.conf"
|
|
||||||
command="$1"
|
|
||||||
mode="$2"
|
|
||||||
extra1="$3"
|
|
||||||
extra2="$4"
|
|
||||||
extra3="$5"
|
|
||||||
extra4="$6"
|
|
||||||
arch=$(cat /storage/.config/.OS_ARCH)
|
|
||||||
|
|
||||||
updateurl="https://127.0.0.1"
|
|
||||||
|
|
||||||
preBootConfig() {
|
|
||||||
mount -o remount,rw /boot
|
|
||||||
}
|
|
||||||
|
|
||||||
postBootConfig() {
|
|
||||||
mount -o remount,ro /boot
|
|
||||||
}
|
|
||||||
|
|
||||||
bato_config_set_value () {
|
|
||||||
key=$1
|
|
||||||
value=$2
|
|
||||||
[ -z "$value" ] && value=0
|
|
||||||
cat "$configFile" | grep "$key"
|
|
||||||
valPresent=$?
|
|
||||||
if [ "$valPresent" != "0" ];then
|
|
||||||
echo "$key=$value" >> "$configFile"
|
|
||||||
else
|
|
||||||
sed -i "s/#\?$key=.*/$key=$value/g" "$configFile"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
#log=/userdata/system/logs/batocera.log
|
|
||||||
#systemsetting="python /usr/lib/python2.7/site-packages/configgen/settings/batoceraSettings.py"
|
|
||||||
|
|
||||||
log=/tmp/logs/systemsettings.log
|
|
||||||
systemsetting="/usr/bin/batocera-settings"
|
|
||||||
|
|
||||||
|
|
||||||
echo "----config ----" >> $log
|
|
||||||
|
|
||||||
if [ "$command" == "getRootPassword" ]; then
|
|
||||||
# security disabled, force the default one without changing boot configuration
|
|
||||||
securityenabled="`$systemsetting -command load -key system.security.enabled`"
|
|
||||||
if [ "$securityenabled" != "1" ];then
|
|
||||||
echo "linux"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
ENCPASSWD=$(grep -E '^[ \t]*rootshadowpassword[ \t]*=' "${storageFile}" | sed -e s+'^[ \t]*rootshadowpassword[ \t]*='++)
|
|
||||||
if test -z "${ENCPASSWD}"
|
|
||||||
then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if ! batocera-encode decode "${ENCPASSWD}"
|
|
||||||
then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "setRootPassword" ]; then
|
|
||||||
PASSWD=${2}
|
|
||||||
|
|
||||||
# security disabled, don't change
|
|
||||||
securityenabled="`$systemsetting -command load -key system.security.enabled`"
|
|
||||||
if [ "$securityenabled" != "1" ];then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if no password if provided, generate one
|
|
||||||
if test -z "${PASSWD}"
|
|
||||||
then
|
|
||||||
PASSWD=$(tr -cd _A-Z-a-z-0-9 < /dev/urandom | fold -w8 | head -n1)
|
|
||||||
fi
|
|
||||||
PASSWDENC=$(batocera-encode encode "${PASSWD}")
|
|
||||||
|
|
||||||
preBootConfig
|
|
||||||
if grep -qE '^[ \t]*rootshadowpassword[ \t]*=' "${storageFile}"
|
|
||||||
then
|
|
||||||
# update it
|
|
||||||
if ! sed -i -e s@'^[ \t]*rootshadowpassword[ \t]*=.*$'@"rootshadowpassword=${PASSWDENC}"@ "${storageFile}"
|
|
||||||
then
|
|
||||||
postBootConfig
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
postBootConfig
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
# create it
|
|
||||||
if ! echo "rootshadowpassword=${PASSWDENC}" >> "${storageFile}"
|
|
||||||
then
|
|
||||||
postBootConfig
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
postBootConfig
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "overscan" ]; then
|
|
||||||
if [ "$mode" == "set" ];then
|
|
||||||
# set will set overscan values abd also enable this mode
|
|
||||||
if [ -z "$extra1" ] || [ -z "$extra2" ] || [ -z "$extra3" ] || [ -z "$extra4" ]; then
|
|
||||||
echo "$0 $command $mode needs 4 arguments:"
|
|
||||||
echo "$0 $command $mode overscan_left overscan_right overscan_top overscan_bottom"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
preBootConfig
|
|
||||||
[ -f "$configFile" ] || touch "$configFile"
|
|
||||||
|
|
||||||
echo "setting overscan values $extra1 $extra2 $extra3 $extra4 " >> $log
|
|
||||||
bato_config_set_value disable_overscan 0
|
|
||||||
bato_config_set_value overscan_scale 1
|
|
||||||
bato_config_set_value overscan_left "$extra1"
|
|
||||||
bato_config_set_value overscan_right "$extra2"
|
|
||||||
bato_config_set_value overscan_top "$extra3"
|
|
||||||
bato_config_set_value overscan_bottom "$extra4"
|
|
||||||
|
|
||||||
postBootConfig
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
fi
|
|
||||||
if [ -f "$configFile" ];then
|
|
||||||
preBootConfig
|
|
||||||
if [ "$mode" == "enable" ];then
|
|
||||||
echo "enabling overscan" >> $log
|
|
||||||
bato_config_set_value disable_overscan 0
|
|
||||||
bato_config_set_value overscan_scale 1
|
|
||||||
elif [ "$mode" == "disable" ];then
|
|
||||||
echo "disabling overscan" >> $log
|
|
||||||
bato_config_set_value disable_overscan 1
|
|
||||||
bato_config_set_value overscan_scale 0
|
|
||||||
else
|
|
||||||
postBootConfig
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
postBootConfig
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "lsoutputs" ]
|
|
||||||
then
|
|
||||||
echo "auto"
|
|
||||||
batocera-resolution listOutputs
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "lsaudio" ];then
|
|
||||||
if [[ "${arch}" =~ "rpi" ]]
|
|
||||||
then
|
|
||||||
echo "hdmi"
|
|
||||||
echo "jack"
|
|
||||||
echo "auto"
|
|
||||||
elif [[ "${arch}" =~ "x86" ]];then
|
|
||||||
echo "auto"
|
|
||||||
echo "custom"
|
|
||||||
LANG=C aplay -l | grep -E '^card [0-9]*:' | sed -e s+'^card \([0-9]*\): \([^,]*\), device \([0-9]*\): [^\[]* \[\([^]]*\)].*$'+'\1,\3 \4 \2'+
|
|
||||||
else
|
|
||||||
echo "auto"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "getaudio" ];then
|
|
||||||
$systemsetting -command load -key audio.device
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "audio" ];then
|
|
||||||
# this code is specific to the rpi
|
|
||||||
# don't set it on other boards
|
|
||||||
# find a more generic way would be nice
|
|
||||||
if [[ "${arch}" =~ "rpi" ]]
|
|
||||||
then
|
|
||||||
# this is specific to the rpi
|
|
||||||
cmdVal="0"
|
|
||||||
if [ "$mode" == "hdmi" ];then
|
|
||||||
cmdVal="2"
|
|
||||||
elif [ "$mode" == "jack" ];then
|
|
||||||
cmdVal="1"
|
|
||||||
fi
|
|
||||||
echo "setting audio output mode : $mode" >> $log
|
|
||||||
amixer cset numid=3 $cmdVal || exit 1
|
|
||||||
elif [[ "${arch}" =~ "x86" ]]
|
|
||||||
then
|
|
||||||
# auto: no .asoundrc file
|
|
||||||
# custom: don't touch the .asoundrc file
|
|
||||||
# any other, create the .asoundrd file
|
|
||||||
if [ "$mode" == "auto" ];then
|
|
||||||
rm -rf /userdata/system/.asoundrc || exit 1
|
|
||||||
elif [ "$mode" != "custom" ];then
|
|
||||||
if echo "${mode}" | grep -qE '^[0-9]*,[0-9]* '
|
|
||||||
then
|
|
||||||
cardnb=$(echo "${mode}" | sed -e s+'^\([0-9]*\),.*$'+'\1'+)
|
|
||||||
devicenb=$(echo "${mode}" | sed -e s+'^[0-9]*,\([0-9]*\) .*$'+'\1'+)
|
|
||||||
cat > /userdata/system/.asoundrc <<EOF
|
|
||||||
pcm.!default { type plug slave { pcm "hw:${cardnb},${devicenb}" } }
|
|
||||||
ctl.!default { type hw card ${cardnb} }
|
|
||||||
EOF
|
|
||||||
aplay "/usr/share/sounds/Mallet.wav"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
elif [[ "${arch}" =~ RG351 ]]
|
|
||||||
then
|
|
||||||
case "${mode}" in
|
|
||||||
"auto"|"speakers")
|
|
||||||
amixer cset name='Playback Path' SPK
|
|
||||||
;;
|
|
||||||
"headphone")
|
|
||||||
amixer cset name='Playback Path' HP
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "volume" ];then
|
|
||||||
if [ "$mode" != "" ];then
|
|
||||||
echo "setting audio volume : $mode" >> $log
|
|
||||||
|
|
||||||
# on my pc, the master is turned off at boot
|
|
||||||
# i don't know what are the rules to set here.
|
|
||||||
amixer set Master unmute || exit 1
|
|
||||||
amixer set Master -- ${mode}% || exit 1
|
|
||||||
|
|
||||||
# maximize the sound to be sure it's not 0, allow errors
|
|
||||||
amixer set PCM -- 100% #|| exit 1
|
|
||||||
amixer set Headphone -- 100% #|| exit 1
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
exit 12
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "gpiocontrollers" ];then
|
|
||||||
command="module"
|
|
||||||
mode="load"
|
|
||||||
extra1="mk_arcade_joystick_rpi"
|
|
||||||
extra2="map=1,2"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "module" ];then
|
|
||||||
modulename="$extra1"
|
|
||||||
map="$extra2"
|
|
||||||
# remove in all cases
|
|
||||||
rmmod /lib/modules/`uname -r`/extra/${modulename}.ko >> $log
|
|
||||||
|
|
||||||
if [ "$mode" == "load" ];then
|
|
||||||
echo "loading module $modulename args = $map" >> $log
|
|
||||||
insmod /lib/modules/`uname -r`/extra/${modulename}.ko $map >> $log
|
|
||||||
[ "$?" ] || exit 1
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "canupdate" ];then
|
|
||||||
available=$(updatecheck canupdate)
|
|
||||||
echo "$available"
|
|
||||||
if [[ "$available" != "no" ]]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
exit 12
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "update" ];then
|
|
||||||
351elec-upgrade
|
|
||||||
exit $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$command" == "wifi" ]]; then
|
|
||||||
ssid="$3"
|
|
||||||
psk="$4"
|
|
||||||
|
|
||||||
if [[ "$mode" == "enable" ]]; then
|
|
||||||
echo "configure wifi" >> $log
|
|
||||||
mkdir -p "/storage/.cache/connman" || exit 1
|
|
||||||
cat > "/storage/.cache/connman/wifi.config" <<EOF
|
|
||||||
[global]
|
|
||||||
Name=351elec
|
|
||||||
|
|
||||||
[service_351elec_default]
|
|
||||||
Type=wifi
|
|
||||||
Name=${ssid}
|
|
||||||
EOF
|
|
||||||
if test "${psk}" != ""
|
|
||||||
then
|
|
||||||
echo "Passphrase=${psk}" >> "/storage/.cache/connman/wifi.config"
|
|
||||||
fi
|
|
||||||
# Power up the WIFI device
|
|
||||||
if [ "$(cat /sys/firmware/devicetree/base/model)" == "Anbernic RG552" ]; then
|
|
||||||
echo 1 > /sys/class/gpio/gpio113/value
|
|
||||||
else
|
|
||||||
echo 1 > /sys/class/gpio/gpio5/value
|
|
||||||
fi
|
|
||||||
sleep 3
|
|
||||||
connmanctl enable wifi || exit 1
|
|
||||||
connmanctl scan wifi || exit 1
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
if [[ "$mode" =~ "start" ]]; then
|
|
||||||
if [[ "$mode" != "forcestart" ]]; then
|
|
||||||
settingsWlan="`$systemsetting -command load -key wifi.enabled`"
|
|
||||||
if [ "$settingsWlan" != "1" ];then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
# Power up the WIFI device
|
|
||||||
if [ "$(cat /sys/firmware/devicetree/base/model)" == "Anbernic RG552" ]; then
|
|
||||||
echo 1 > /sys/class/gpio/gpio113/value
|
|
||||||
else
|
|
||||||
echo 1 > /sys/class/gpio/gpio5/value
|
|
||||||
fi
|
|
||||||
sleep 3
|
|
||||||
connmanctl enable wifi || exit 1
|
|
||||||
connmanctl scan wifi || exit 1
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
if [[ "$mode" == "disable" ]]; then
|
|
||||||
connmanctl disable wifi
|
|
||||||
# Power down the WIFI device
|
|
||||||
if [ "$(cat /sys/firmware/devicetree/base/model)" == "Anbernic RG552" ]; then
|
|
||||||
echo 0 > /sys/class/gpio/gpio113/value
|
|
||||||
else
|
|
||||||
echo 0 > /sys/class/gpio/gpio5/value
|
|
||||||
fi
|
|
||||||
exit $?
|
|
||||||
fi
|
|
||||||
if [[ "$mode" == "list" ]]; then
|
|
||||||
WAVAILABLE=$(connmanctl services | cut -b 5- | sed -e s+'^\([^ ]*\).*$'+'\1'+ | grep -vE '^Wired$|^<hidden>$')
|
|
||||||
if test -n "${ssid}"
|
|
||||||
then
|
|
||||||
echo "${WAVAILABLE}" | grep -qE '^'"${ssid}"'$' || echo "${ssid}"
|
|
||||||
fi
|
|
||||||
echo "${WAVAILABLE}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$command" == "storage" ]]; then
|
|
||||||
exit 0;
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$command" == "forgetBT" ]]; then
|
|
||||||
killall -9 hcitool
|
|
||||||
systemctl stop bluetooth
|
|
||||||
rm -rf /storage/.cache/bluetooth/*
|
|
||||||
systemctl start bluetooth
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$command" == "tz" ];then
|
|
||||||
if test "$mode" == ""
|
|
||||||
then
|
|
||||||
cat /storage/.config/distribution/configs/tz
|
|
||||||
else
|
|
||||||
if test -f "/usr/share/zoneinfo/${mode}"
|
|
||||||
then
|
|
||||||
echo "TIMEZONE=${mode}" > /storage/.cache/timezone
|
|
||||||
systemctl restart tz-data.service
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
exit $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 10
|
|
|
@ -1,84 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# If we are on Steam Deck
|
|
||||||
arch=$(cat /storage/.config/.OS_ARCH)
|
|
||||||
if [ $arch == "DECK" ];then
|
|
||||||
INSTALL_DIR="~/retrodeck"
|
|
||||||
|
|
||||||
systemsetting=$INSTALL_DIR+"/usr/bin/batocera-settings"
|
|
||||||
syslang=$($systemsetting -command load -key system.language)
|
|
||||||
IMGSTYLE=$($systemsetting -command load -key scrapper.style)
|
|
||||||
|
|
||||||
if test $# = 1
|
|
||||||
then
|
|
||||||
DOSYS=$1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# supported languages : en, fr, es, de, pt
|
|
||||||
case "${syslang}" in
|
|
||||||
fr_FR)
|
|
||||||
sslang=fr,en
|
|
||||||
;;
|
|
||||||
es_ES)
|
|
||||||
sslang=es,en
|
|
||||||
;;
|
|
||||||
de_DE)
|
|
||||||
sslang=de,en
|
|
||||||
;;
|
|
||||||
pt_PT)
|
|
||||||
sslang=pt,en
|
|
||||||
;;
|
|
||||||
pt_BR)
|
|
||||||
sslang=pt,en
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
sslang=en
|
|
||||||
esac
|
|
||||||
|
|
||||||
if test -z "${IMGSTYLE}"
|
|
||||||
then
|
|
||||||
IMGSTYLE="b,f,a,l,3b,s"
|
|
||||||
fi
|
|
||||||
|
|
||||||
do_scrap() {
|
|
||||||
LRDIR=$1
|
|
||||||
NF=$(ls "${LRDIR}" | grep -vE '\.txt$|\.xml$' | wc -l)
|
|
||||||
if test "${NF}" -gt 0
|
|
||||||
then
|
|
||||||
BASEDIR=$(basename "${LRDIR}")
|
|
||||||
echo "GAME: system ${BASEDIR}"
|
|
||||||
EXTRAOPT=
|
|
||||||
|
|
||||||
for x in "mame" "fba" "fba_libretro" "neogeo"
|
|
||||||
do
|
|
||||||
test "${LRDIR}" = $INSTALL_DIR+"/storage/roms/${x}" && EXTRAOPT="-mame"
|
|
||||||
done
|
|
||||||
|
|
||||||
(cd "${LRDIR}" && sselph-scraper -console_src ss,gdb,ovgdb -lang "${sslang}" -console_img "${IMGSTYLE}" -download_videos -workers 5 ${EXTRAOPT}) 2>&1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# find system to scrape
|
|
||||||
(if test -n "${DOSYS}"
|
|
||||||
then
|
|
||||||
test -d $INSTALL_DIR+"/storage/roms/${DOSYS}" && echo $INSTALL_DIR+"/storage/roms/${DOSYS}"
|
|
||||||
else
|
|
||||||
find /storage/roms -maxdepth 1 -mindepth 1 -type d
|
|
||||||
fi) |
|
|
||||||
while read RDIR1
|
|
||||||
do
|
|
||||||
# read the 2 next dir
|
|
||||||
read RDIR2
|
|
||||||
read RDIR3
|
|
||||||
read RDIR4
|
|
||||||
|
|
||||||
do_scrap "${RDIR1}" &
|
|
||||||
test -n "${RDIR2}" && do_scrap "${RDIR2}" &
|
|
||||||
test -n "${RDIR3}" && do_scrap "${RDIR3}" &
|
|
||||||
test -n "${RDIR4}" && do_scrap "${RDIR4}" &
|
|
||||||
wait
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
||||||
# synchronize to not make the usb/sdcard slowing down once finnished
|
|
||||||
sync
|
|
|
@ -1,272 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# batocera-settings can mimic batoceraSettings.py
|
|
||||||
# goal: abolish this python script, it's useless for the sake of the load feature only
|
|
||||||
# get a more user friendly environment for setting, getting and saving keys
|
|
||||||
#
|
|
||||||
# Usage of BASE COMMAND:
|
|
||||||
# longform: <filename> --command <cmd> --key <key> --value <value>
|
|
||||||
#
|
|
||||||
# shortform: <file> <cmd> <key> <value>
|
|
||||||
#
|
|
||||||
# --command load write enable disable status
|
|
||||||
# --key any key in emuelec.conf (kodi.enabled...)
|
|
||||||
# --value any alphanumerical string
|
|
||||||
# use quotation marks to avoid globbing use slashes escape special characters
|
|
||||||
|
|
||||||
# This script reads only 1st occurrence if string and writes only to this first hit
|
|
||||||
#
|
|
||||||
# This script uses #-Character to comment values
|
|
||||||
#
|
|
||||||
# If there is a boolean value (0,1) then then enable and disable command will set the corresponding
|
|
||||||
# boolean value.
|
|
||||||
|
|
||||||
# Examples:
|
|
||||||
# 'batocera-settings --command load --key wifi.enabled' will print out 0 or 1
|
|
||||||
# 'batocera-settings --command write --key wifi.ssid -value "This is my NET"' will set 'wlan.ssid=This is my NET'
|
|
||||||
# 'batocera-settings enable wifi.ssid' will remove # from configfile (activate)
|
|
||||||
# 'batocera-settings disable wifi.enabled' will set key wifi.enabled=0
|
|
||||||
# 'botocera-settings /myown/config.file --command status --key my.key' will output status of own config.file and my.key
|
|
||||||
|
|
||||||
# by cyperghost - 2019/12/30
|
|
||||||
|
|
||||||
##### INITS #####
|
|
||||||
# If we are on Steam Deck
|
|
||||||
arch=$(cat /storage/.config/.OS_ARCH)
|
|
||||||
if [ $arch == "DECK" ];then
|
|
||||||
INSTALL_DIR="~/retrodeck"
|
|
||||||
|
|
||||||
BATOCERA_CONFIGFILE=$INSTALL_DIR+"/storage/.config/distribution/configs/distribution.conf"
|
|
||||||
COMMENT_CHAR_SEARCH="[#|;]"
|
|
||||||
COMMENT_CHAR="#"
|
|
||||||
##### INITS #####
|
|
||||||
|
|
||||||
##### Function Calls #####
|
|
||||||
|
|
||||||
function get_config() {
|
|
||||||
#Will search for key.value and #key.value for only one occurrence
|
|
||||||
#If the character is the COMMENT CHAR then set value to it
|
|
||||||
#Otherwise strip till the equal-char to obtain value
|
|
||||||
local val
|
|
||||||
local ret
|
|
||||||
val="$(grep -E -m1 "^\s*$1\s*=" $BATOCERA_CONFIGFILE)"
|
|
||||||
ret=$?
|
|
||||||
if [[ $ret -eq 1 ]]; then
|
|
||||||
val="$(grep -E -m1 "^$COMMENT_CHAR_SEARCH\s*$1\s*=" $BATOCERA_CONFIGFILE)"
|
|
||||||
ret=$?
|
|
||||||
[[ $ret -eq 0 ]] && val=$COMMENT_CHAR
|
|
||||||
else
|
|
||||||
#Maybe here some finetuning to catch key.value = ENTRY without blanks
|
|
||||||
val="${val#*=}"
|
|
||||||
fi
|
|
||||||
echo "$val"
|
|
||||||
return $ret
|
|
||||||
}
|
|
||||||
|
|
||||||
function set_config() {
|
|
||||||
#Will search for first key.name at beginning of line and write value to it
|
|
||||||
sed -i "1,/^\(\s*$1\s*=\).*/s//\1$2/" "$BATOCERA_CONFIGFILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
function uncomment_config() {
|
|
||||||
#Will search for first Comment Char at beginning of line and remove it
|
|
||||||
sed -i "1,/^$COMMENT_CHAR_SEARCH\(\s*$1\)/s//\1/" "$BATOCERA_CONFIGFILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
function comment_config() {
|
|
||||||
#Will search for first key.name at beginning of line and add a comment char to it
|
|
||||||
sed -i "1,/^\(\s*$1\)/s//$COMMENT_CHAR\1/" "$BATOCERA_CONFIGFILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
function check_argument() {
|
|
||||||
# This method does not accept arguments starting with '-'.
|
|
||||||
if [[ -z "$2" || "$2" =~ ^- ]]; then
|
|
||||||
echo >&2
|
|
||||||
echo "ERROR: '$1' is missing an argument." >&2
|
|
||||||
echo >&2
|
|
||||||
echo "Just type '$0' to see usage page." >&2
|
|
||||||
echo >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function dash_style() {
|
|
||||||
#This function is needed to "simulate" the python script with single dash
|
|
||||||
#commands. It will also accept the more common posix double dashes
|
|
||||||
#Accept dashes and double dashes and build new array ii with parameter set
|
|
||||||
#The else-branch can be used for the shortform
|
|
||||||
|
|
||||||
for i in --command --key --value; do
|
|
||||||
if [[ -z "$1" ]]; then
|
|
||||||
continue
|
|
||||||
elif [[ "$i" =~ ^-{0,1}"${1,,}" ]]; then
|
|
||||||
check_argument $1 $2
|
|
||||||
[[ $? -eq 0 ]] || exit 1
|
|
||||||
ii+=("$2")
|
|
||||||
shift 2
|
|
||||||
else
|
|
||||||
ii+=("$1")
|
|
||||||
shift 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function usage() {
|
|
||||||
val=" Usage of BASE COMMAND:
|
|
||||||
|
|
||||||
<file> --command <cmd> --key <key> --value <value>
|
|
||||||
|
|
||||||
shortform: <file> <cmd> <key> <value>
|
|
||||||
|
|
||||||
--command load write enable disable status
|
|
||||||
--key any key in emuelec.conf (kodi.enabled...)
|
|
||||||
--value any alphanumerical string
|
|
||||||
use quotation marks to avoid globbing
|
|
||||||
|
|
||||||
For write command --value <value> must be provided
|
|
||||||
|
|
||||||
exit codes: exit 0 = value is available, proper exit
|
|
||||||
exit 1 = general error
|
|
||||||
exit 2 = file error
|
|
||||||
exit 10 = value found, but empty
|
|
||||||
exit 11 = value found, but not activated
|
|
||||||
exit 12 = value not found
|
|
||||||
|
|
||||||
If you don't set a filename then default is '~/storage/.config/distribution.conf'"
|
|
||||||
|
|
||||||
echo "$val"
|
|
||||||
|
|
||||||
}
|
|
||||||
##### Function Calls #####
|
|
||||||
|
|
||||||
##### MAIN FUNCTION #####
|
|
||||||
function main() {
|
|
||||||
|
|
||||||
#Filename parsed?
|
|
||||||
if [[ -f "$1" ]]; then
|
|
||||||
BATOCERA_CONFIGFILE="$1"
|
|
||||||
shift
|
|
||||||
else
|
|
||||||
[[ -f "$BATOCERA_CONFIGFILE" ]] || { echo "not found: $BATOCERA_CONFIGFILE" >&2; exit 2; }
|
|
||||||
fi
|
|
||||||
|
|
||||||
#How much arguments are parsed, up to 6 then it is the long format
|
|
||||||
#up to 3 then it is the short format
|
|
||||||
if [[ ${#@} -eq 0 || ${#@} -gt 6 ]]; then
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
dash_style "$@"
|
|
||||||
command="${ii[0]}"
|
|
||||||
keyvalue="${ii[1]}"
|
|
||||||
newvalue="${ii[2]}"
|
|
||||||
unset ii
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ -z $keyvalue ]] && { echo "error: Please provide a proper keyvalue" >&2; exit 1; }
|
|
||||||
|
|
||||||
# value processing, switch case
|
|
||||||
case "${command,,}" in
|
|
||||||
|
|
||||||
"read"|"get"|"load")
|
|
||||||
val="$(get_config $keyvalue)"
|
|
||||||
ret=$?
|
|
||||||
[[ "$val" == "$COMMENT_CHAR" ]] && exit 11
|
|
||||||
[[ -z "$val" && $ret -eq 0 ]] && exit 10
|
|
||||||
[[ -z "$val" && $ret -eq 1 ]] && exit 12
|
|
||||||
[[ -n "$val" ]] && echo "$val" && exit 0
|
|
||||||
;;
|
|
||||||
|
|
||||||
"stat"|"status")
|
|
||||||
val="$(get_config $keyvalue)"
|
|
||||||
ret=$?
|
|
||||||
[[ -f "$BATOCERA_CONFIGFILE" ]] && echo "ok: found '$BATOCERA_CONFIGFILE'" >&2 || echo "error: not found '$BATOCERA_CONFIGFILE'" >&2
|
|
||||||
[[ -w "$BATOCERA_CONFIGFILE" ]] && echo "ok: r/w file '$BATOCERA_CONFIGFILE'" >&2 || echo "error: r/o file '$BATOCERA_CONFIGFILE'" >&2
|
|
||||||
[[ -z "$val" && $ret -eq 1 ]] && echo "error: '$keyvalue' not found!" >&2
|
|
||||||
[[ -z "$val" && $ret -eq 0 ]] && echo "error: '$keyvalue' is empty - use 'comment' command to retrieve" >&2
|
|
||||||
[[ "$val" == "$COMMENT_CHAR" ]] && echo "error: '$keyvalue' is commented $COMMENT_CHAR!" >&2 && val=
|
|
||||||
[[ -n "$val" ]] && echo "ok: '$keyvalue' $val"
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
|
|
||||||
"set"|"write"|"save")
|
|
||||||
#Is file write protected?
|
|
||||||
[[ -w "$BATOCERA_CONFIGFILE" ]] || { echo "r/o file: $BATOCERA_CONFIGFILE" >&2; exit 2; }
|
|
||||||
#We can comment line above to erase keys, it's much saver to check if a value is setted
|
|
||||||
[[ -z "$newvalue" ]] && echo "error: '$keyvalue' needs value to be setted" >&2 && exit 1
|
|
||||||
|
|
||||||
val="$(get_config $keyvalue)"
|
|
||||||
ret=$?
|
|
||||||
if [[ "$val" == "$COMMENT_CHAR" ]]; then
|
|
||||||
echo "$keyvalue: hashed out!" >&2
|
|
||||||
uncomment_config "$keyvalue"
|
|
||||||
set_config "$keyvalue" "$newvalue"
|
|
||||||
echo "$keyvalue: set from '$val' to '$newvalue'" >&2
|
|
||||||
exit 0
|
|
||||||
elif [[ -z "$val" && $ret -eq 1 ]]; then
|
|
||||||
echo "$keyvalue: not found!" >&2
|
|
||||||
exit 12
|
|
||||||
elif [[ "$val" != "$newvalue" ]]; then
|
|
||||||
set_config "$keyvalue" "$newvalue"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
"uncomment"|"enable"|"activate")
|
|
||||||
val="$(get_config $keyvalue)"
|
|
||||||
ret=$?
|
|
||||||
# Boolean
|
|
||||||
if [[ "$val" == "$COMMENT_CHAR" ]]; then
|
|
||||||
uncomment_config "$keyvalue"
|
|
||||||
echo "$keyvalue: removed '$COMMENT_CHAR', key is active" >&2
|
|
||||||
elif [[ "$val" == "0" ]]; then
|
|
||||||
set_config "$keyvalue" "1"
|
|
||||||
echo "$keyvalue: boolean set '1'" >&2
|
|
||||||
elif [[ -z "$val" && $ret -eq 1 ]]; then
|
|
||||||
echo "$keyvalue: not found!" && exit 2
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
"comment"|"disable"|"remark")
|
|
||||||
val="$(get_config $keyvalue)"
|
|
||||||
ret=$?
|
|
||||||
# Boolean
|
|
||||||
[[ "$val" == "$COMMENT_CHAR" || "$val" == "0" ]] && exit 0
|
|
||||||
if [[ -z "$val" && $ret -eq 1 ]]; then
|
|
||||||
echo "$keyvalue: not found!" >&2 && exit 12
|
|
||||||
elif [[ "$val" == "1" ]]; then
|
|
||||||
set_config "$keyvalue" "0"
|
|
||||||
echo "$keyvalue: boolean set to '0'" >&2
|
|
||||||
else
|
|
||||||
comment_config "$keyvalue"
|
|
||||||
echo "$keyvalue: added '$COMMENT_CHAR', key is not active" >&2
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "ERROR: invalid command '$command'" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
##### MAIN FUNCTION #####
|
|
||||||
|
|
||||||
##### MAIN CALL #####
|
|
||||||
|
|
||||||
# Prepare arrays from fob python script
|
|
||||||
# Keyword for python call is mimic_python
|
|
||||||
# Attention the unset is needed to eliminate first argument (python basefile)
|
|
||||||
|
|
||||||
if [[ "${#@}" -eq 1 && "$1" =~ "mimic_python" ]]; then
|
|
||||||
#batoceraSettings.py fob
|
|
||||||
readarray -t arr <<< "$1"
|
|
||||||
unset arr[0]
|
|
||||||
else
|
|
||||||
#regular call by shell
|
|
||||||
arr=("$@")
|
|
||||||
fi
|
|
||||||
|
|
||||||
main "${arr[@]}"
|
|
||||||
|
|
||||||
##### MAIN CALL #####
|
|
|
@ -1,407 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
import os
|
|
||||||
import shlex
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from pathlib import Path
|
|
||||||
from time import perf_counter
|
|
||||||
from typing import TYPE_CHECKING, Optional
|
|
||||||
|
|
||||||
from setsettings import set_settings
|
|
||||||
|
|
||||||
# If we are on Steam Deck we want a prefix
|
|
||||||
|
|
||||||
# TODO: INSTALL_DIR + '/storage/.config/.OS_ARCH' was not working, dunno why, I'll check later
|
|
||||||
# DEVICE = "DECK" #for the moment this will do
|
|
||||||
|
|
||||||
INSTALL_DIR = os.path.expanduser('~/retrodeck')
|
|
||||||
with open(INSTALL_DIR + r'/storage/.config/.OS_ARCH', 'r') as file:
|
|
||||||
DEVICE = file.read().rstrip()
|
|
||||||
|
|
||||||
#if DEVICE == "DECK" :
|
|
||||||
#
|
|
||||||
#else:
|
|
||||||
# INSTALL_DIR = ""
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
#These except Union are deprecated in 3.9 and should be replaced with collections.abc / builtin list type, but we have 3.8 for now
|
|
||||||
from typing import List, Mapping, MutableMapping, Sequence, Union
|
|
||||||
|
|
||||||
LOGS_DIR = Path('/tmp/logs')
|
|
||||||
RA_TEMP_CONF = INSTALL_DIR + '/storage/.config/retroarch/retroarch.cfg'
|
|
||||||
RA_APPEND_CONF = '/tmp/raappend.cfg'
|
|
||||||
log_path = LOGS_DIR / 'exec.log'
|
|
||||||
|
|
||||||
def call_profile_func(function_name: str, *args: str) -> str:
|
|
||||||
# if we are on Steam Deck
|
|
||||||
if DEVICE == "DECK" :
|
|
||||||
proc = subprocess.run(f'. {INSTALL_DIR}/export_func.sh', shell=True, stdout=subprocess.PIPE, check=True, text=True)
|
|
||||||
else:
|
|
||||||
#We are going to want to call some stuff from /etc/profile, they are defined in ../profile.d/99-distribution.conf
|
|
||||||
#But on Steam Deck this is not needed as these stuff is called by another script as profile.d is just for embedded distros
|
|
||||||
proc = subprocess.run(f'. /etc/profile && {shlex.quote(function_name)} {shlex.join(args)}', shell=True, stdout=subprocess.PIPE, check=True, text=True)
|
|
||||||
return proc.stdout.strip('\n')
|
|
||||||
|
|
||||||
def get_es_setting(setting_type: str, setting_name: str) -> str:
|
|
||||||
#from es_settings.cfg (XML)
|
|
||||||
return call_profile_func('get_es_setting', setting_type, setting_name)
|
|
||||||
|
|
||||||
log_level = get_es_setting('string', 'LogLevel') #If set to default, would equal empty string
|
|
||||||
|
|
||||||
def jslisten_set(*exe_names: str):
|
|
||||||
#exe_names are passed as one argument, intended for killall to use them later
|
|
||||||
if DEVICE != "DECK" :
|
|
||||||
call_profile_func('jslisten', 'set', shlex.join(exe_names))
|
|
||||||
|
|
||||||
def jslisten_stop():
|
|
||||||
#call_profile_func('jslisten', 'stop')
|
|
||||||
if DEVICE != "DECK" :
|
|
||||||
subprocess.check_call(['systemctl', 'stop', 'jslisten'])
|
|
||||||
|
|
||||||
def get_elec_setting(setting_name, platform=None, rom=None):
|
|
||||||
#From distribution.conf
|
|
||||||
#Potentially this can be reimplemented in Python if that turns out to be a good idea
|
|
||||||
return call_profile_func('get_ee_setting', setting_name, platform, rom)
|
|
||||||
|
|
||||||
def set_elec_setting(setting_name, value):
|
|
||||||
call_profile_func('set_ee_setting', setting_name, value)
|
|
||||||
|
|
||||||
def check_bios(platform, core, emulator, game, log_path_):
|
|
||||||
call_profile_func('ee_check_bios', platform, core, emulator, game, log_path_)
|
|
||||||
|
|
||||||
def log(text):
|
|
||||||
with log_path.open('at', encoding='utf-8') as log_file:
|
|
||||||
print(text, file=log_file)
|
|
||||||
|
|
||||||
def cleanup_and_quit(return_code):
|
|
||||||
if log_level == 'debug':
|
|
||||||
log(f'Cleaning up and exiting with return code {return_code}')
|
|
||||||
|
|
||||||
if DEVICE != "DECK" :
|
|
||||||
jslisten_stop()
|
|
||||||
clear_screen()
|
|
||||||
call_profile_func('normperf')
|
|
||||||
call_profile_func('set_audio', 'default')
|
|
||||||
sys.exit(return_code)
|
|
||||||
|
|
||||||
def clear_screen():
|
|
||||||
if DEVICE != "DECK" :
|
|
||||||
if log_level == 'debug':
|
|
||||||
log('Clearing screen')
|
|
||||||
with open('/dev/console', 'wb') as console:
|
|
||||||
subprocess.run('clear', stdout=console, check=True)
|
|
||||||
|
|
||||||
def list_archive(path: Path) -> 'List[str]':
|
|
||||||
#7z path needs to be given explicitly, otherwise it won't find 7z.so
|
|
||||||
sevenzip_proc = subprocess.run(['/usr/bin/7z', 'l', '-slt', path], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False)
|
|
||||||
if sevenzip_proc.returncode != 0:
|
|
||||||
raise OSError(sevenzip_proc.stderr.strip())
|
|
||||||
#Ignore the first Path = line which is the archive itself
|
|
||||||
return [line[len('Path = '):] for line in sevenzip_proc.stdout.splitlines() if line.startswith('Path = ')][1:]
|
|
||||||
|
|
||||||
def extract_archive(path: Path) -> Path:
|
|
||||||
#Assume there is only one file, otherwise things get weird
|
|
||||||
inner_filename = list_archive(path)[0]
|
|
||||||
#Since save files etc may be placed in the ROM folder, we should extract there so everything still works transparently, which also helps with overrides and such
|
|
||||||
subprocess.check_call(['/usr/bin/7z', 'e', f'-o{str(path.parent)}', path, inner_filename], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
||||||
return path.parent.joinpath(inner_filename)
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class StandaloneEmulator():
|
|
||||||
jskill_name: str
|
|
||||||
args: 'Sequence[str]'
|
|
||||||
should_extract: bool = False
|
|
||||||
|
|
||||||
standalone_emulators: 'MutableMapping[str, StandaloneEmulator]' = {
|
|
||||||
'AMIBERRY': StandaloneEmulator('amiberry', [INSTALL_DIR + '/usr/bin/amiberry.start', '<path>']),
|
|
||||||
'AdvanceMame': StandaloneEmulator('advmame', [INSTALL_DIR + '/usr/bin/advmame.sh', '<path>']),
|
|
||||||
'HATARISA': StandaloneEmulator('hatari', [INSTALL_DIR + '/usr/bin/hatari.start', '<path>']),
|
|
||||||
'hypseus_singe': StandaloneEmulator('hypseus', [INSTALL_DIR + '/usr/bin/hypseus.sh', '<path>']),
|
|
||||||
'OPENBOR': StandaloneEmulator('openbor', [INSTALL_DIR + '/usr/bin/openbor.sh', '<path>']),
|
|
||||||
'PPSSPPSDL': StandaloneEmulator('PPSSPPSDL', [INSTALL_DIR + '/usr/bin/ppsspp.sh', '<path>']),
|
|
||||||
'SCUMMVMSA': StandaloneEmulator('scummvm', [INSTALL_DIR + '/usr/bin/scummvm.start', 'sa', '<path>']),
|
|
||||||
'drastic': StandaloneEmulator('drastic', [INSTALL_DIR + '/usr/bin/drastic.sh', '<path>']),
|
|
||||||
'ecwolf': StandaloneEmulator('ecwolf', [INSTALL_DIR + '/usr/bin/ecwolf.sh', '<path>']),
|
|
||||||
'gzdoom': StandaloneEmulator('gzdoom', [INSTALL_DIR + '/usr/bin/gzdoom.sh', '<path>']),
|
|
||||||
'lzdoom': StandaloneEmulator('lzdoom', [INSTALL_DIR + '/usr/bin/lzdoom.sh', '<path>']),
|
|
||||||
'mpv': StandaloneEmulator('mpv', [INSTALL_DIR + '/usr/bin/mpv_video.sh', '<path>']),
|
|
||||||
'pico8': StandaloneEmulator('pico8_dyn', [INSTALL_DIR + '/usr/bin/pico-8.sh', '<path>']),
|
|
||||||
'piemu': StandaloneEmulator('piemu', [INSTALL_DIR + '/usr/bin/bash', '-l', '/usr/bin/piemu.sh', '<path>']),
|
|
||||||
'raze': StandaloneEmulator('raze', [INSTALL_DIR + '/usr/bin/raze.sh', '<path>']),
|
|
||||||
'solarus': StandaloneEmulator('solarus-run', [INSTALL_DIR + '/usr/bin/solarus.sh', '<path>']),
|
|
||||||
'yuzu': StandaloneEmulator('yuzu', [INSTALL_DIR + '/emulators/yuzu.sh', '<path>']),
|
|
||||||
'ryujinx': StandaloneEmulator('ryujinx', [INSTALL_DIR + '/emulators/ryujinx.sh', '<path>']),
|
|
||||||
}
|
|
||||||
|
|
||||||
def _load_customized_standalone_emulators():
|
|
||||||
try:
|
|
||||||
with open(INSTALL_DIR + '/storage/.config/standalone_emulators', 'rt', encoding='utf-8') as f:
|
|
||||||
for line in f:
|
|
||||||
if ': ' not in line or line.startswith('#'):
|
|
||||||
continue
|
|
||||||
name, rest = line.rstrip().split(': ', 1)
|
|
||||||
args = rest.split(' ')
|
|
||||||
kill_name = name
|
|
||||||
should_extract = False
|
|
||||||
#If name of exe to kill was not listed, assume it is the same as the emulator name
|
|
||||||
if not args[0].startswith('/'):
|
|
||||||
kill_name = args[0]
|
|
||||||
args = args[1:]
|
|
||||||
if args[-1] == 'should_extract':
|
|
||||||
args = args[:-1]
|
|
||||||
should_extract = True
|
|
||||||
standalone_emulators[name] = StandaloneEmulator(kill_name, args, should_extract)
|
|
||||||
except (FileNotFoundError, ValueError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
_load_customized_standalone_emulators()
|
|
||||||
|
|
||||||
class EmuRunner():
|
|
||||||
def __init__(self, rom: Optional[Path], platform: Optional[str], emulator: Optional[str], core: Optional[str], args: 'Mapping[str, str]') -> None:
|
|
||||||
self.rom = rom
|
|
||||||
self.platform = platform
|
|
||||||
self.emulator = emulator
|
|
||||||
self.core = core
|
|
||||||
self.args = args
|
|
||||||
self.temp_files: 'List[Path]' = [] #Files that we extracted from archives, etc. to clean up later
|
|
||||||
self.environment = os.environ.copy()
|
|
||||||
|
|
||||||
def download_things_if_needed(self) -> None:
|
|
||||||
if self.core == 'freej2me':
|
|
||||||
#freej2me needs the JDK to be downloaded on the first run
|
|
||||||
subprocess.run(INSTALL_DIR + '/usr/bin/freej2me.sh', check=True)
|
|
||||||
self.environment['JAVA_HOME']=INSTALL_DIR + '/storage/jdk'
|
|
||||||
self.environment['PATH'] = INSTALL_DIR + '/storage/jdk/bin:' + os.environ['PATH']
|
|
||||||
elif self.core == 'easyrpg':
|
|
||||||
# easyrpg needs runtime files to be downloaded on the first run
|
|
||||||
subprocess.run(INSTALL_DIR + '/usr/bin/easyrpg.sh', check=True)
|
|
||||||
|
|
||||||
def toggle_max_performance(self) -> None:
|
|
||||||
if get_elec_setting('maxperf', self.platform, self.rom.name if self.rom else None) == '1':
|
|
||||||
if log_level == 'debug':
|
|
||||||
log('Enabling max performance as requested')
|
|
||||||
call_profile_func('maxperf')
|
|
||||||
else:
|
|
||||||
call_profile_func('normperf')
|
|
||||||
|
|
||||||
def set_settings(self) -> str:
|
|
||||||
rom_name = str(self.rom) if self.rom else ''
|
|
||||||
core = self.core if self.core else ''
|
|
||||||
platform = self.platform if self.platform else ''
|
|
||||||
return set_settings(rom_name, core, platform, controllers=self.args.get('controllers', ''), autosave=self.args.get('autosave', ''), snapshot=self.args.get('state_slot', ''))
|
|
||||||
|
|
||||||
def get_standalone_emulator_command(self) -> 'Sequence[Union[str, Path]]':
|
|
||||||
if not self.emulator:
|
|
||||||
raise ValueError('runemu.py was called improperly, tried to launch a standard emulator with no emulator')
|
|
||||||
if log_level != 'minimal':
|
|
||||||
log('Running a standalone emulator:')
|
|
||||||
log(f'platform: {self.platform}')
|
|
||||||
log(f'emulator: {self.emulator}')
|
|
||||||
#Core is not actually relevant (other than Mupen64Plus which is in another function)
|
|
||||||
|
|
||||||
emu = standalone_emulators[self.emulator]
|
|
||||||
path = self.rom
|
|
||||||
if self.rom and emu.should_extract and self.rom.suffix in {'.zip', '.7z', '.gz', '.bz2'}:
|
|
||||||
path = extract_archive(self.rom)
|
|
||||||
self.temp_files.append(path)
|
|
||||||
|
|
||||||
command = [arg for arg in (path if arg == '<path>' else arg for arg in emu.args) if arg]
|
|
||||||
|
|
||||||
jslisten_set(emu.jskill_name)
|
|
||||||
return command
|
|
||||||
|
|
||||||
def get_retroarch_command(self, shader_arg: str) -> 'Sequence[Union[str, Path]]':
|
|
||||||
if log_level != 'minimal':
|
|
||||||
log('Running a libretro core via RetroArch')
|
|
||||||
log(f'platform: {self.platform}')
|
|
||||||
log(f'core: {self.core}')
|
|
||||||
retroarch_binary = 'retroarch'
|
|
||||||
#if self.core in {'pcsx_rearmed', 'parallel_n64'}:
|
|
||||||
# retroarch_binary = 'retroarch32'
|
|
||||||
# self.environment['LD_LIBRARY_PATH'] = '/usr/lib32'
|
|
||||||
|
|
||||||
rom_path: 'Optional[Union[str, Path]]' = self.rom
|
|
||||||
|
|
||||||
if self.rom:
|
|
||||||
if self.platform == 'doom' and self.rom.suffix == '.doom':
|
|
||||||
subprocess.run(['dos2unix', self.rom], check=True) #Hmmmmm but do we need that
|
|
||||||
with self.rom.open('rt', encoding='utf-8') as doomfile:
|
|
||||||
for line in doomfile:
|
|
||||||
key, _, value = line.partition('=')
|
|
||||||
if key == 'IWAD':
|
|
||||||
rom_path = value
|
|
||||||
break
|
|
||||||
if self.core == 'scummvm' and self.rom.suffix == '.scummvm':
|
|
||||||
#ScummVM libretro core actually only works with .scummvm files that just have the game ID with no path specified, which isn't how they are generated by the scummvm scanner script
|
|
||||||
#But if you give it any other path to a file, it will autodetect a game inside that file's parent directory, even if the file doesn't actually exist
|
|
||||||
#This would otherwise be what /usr/bin/scummvm.start tries to do when its first arg is "libretro", by cd'ing into that game directory
|
|
||||||
path = Path(self.rom.read_text(encoding='utf-8').split('"')[1])
|
|
||||||
rom_path = path / 'game'
|
|
||||||
|
|
||||||
jslisten_set(retroarch_binary)
|
|
||||||
command: 'List[Union[str, Path]]' = [os.path.join('/usr/bin/', retroarch_binary), '-L', Path('/tmp/cores/', f'{self.core}_libretro.so')]
|
|
||||||
|
|
||||||
if log_level != 'minimal':
|
|
||||||
command.append('--verbose')
|
|
||||||
|
|
||||||
if 'host' in self.args or 'connect' in self.args:
|
|
||||||
netplay_nick = get_elec_setting('netplay.nickname')
|
|
||||||
if not netplay_nick:
|
|
||||||
netplay_nick = '351ELEC'
|
|
||||||
if 'connect' in self.args:
|
|
||||||
set_elec_setting('netplay.client.port', self.args['port'])
|
|
||||||
set_elec_setting('netplay.client.ip', self.args['connect']) #We should now have parsed that properly so it's just a hostname/IP address, no --port argument
|
|
||||||
command += ['--connect', self.args['connect'] + '|' + self.args['port']]
|
|
||||||
if 'host' in self.args:
|
|
||||||
command += ['--host', self.args['host']]
|
|
||||||
|
|
||||||
command += ['--nick', netplay_nick]
|
|
||||||
|
|
||||||
if self.core == 'fbneo' and self.platform == 'neocd':
|
|
||||||
command += ['--subsystem', self.platform]
|
|
||||||
if shader_arg:
|
|
||||||
#Returned from setsettings, this is of the form "--shader-set /tmp/shaders/blahblahblah", apparently actually needed even if video_shader is set in RA_APPEND_CONF
|
|
||||||
command += shlex.split(shader_arg)
|
|
||||||
command += ['--config', RA_TEMP_CONF, '--appendconfig', RA_APPEND_CONF]
|
|
||||||
if rom_path:
|
|
||||||
command.append(rom_path)
|
|
||||||
|
|
||||||
return command
|
|
||||||
|
|
||||||
def get_retrorun_command(self) -> 'Sequence[Union[str, Path]]':
|
|
||||||
if not self.rom:
|
|
||||||
raise ValueError('runemu.py was called improperly, tried to launch retrorun with no game')
|
|
||||||
if not self.platform:
|
|
||||||
raise ValueError('runemu.py was called improperly, tried to launch retrorun with no platform')
|
|
||||||
if not self.core:
|
|
||||||
raise ValueError('runemu.py was called improperly, tried to launch retrorun with no platform')
|
|
||||||
|
|
||||||
core_path = Path('/tmp/cores/', f'{self.core}_libretro.so')
|
|
||||||
if log_level != 'minimal':
|
|
||||||
log('Running a libretro core via retrorun')
|
|
||||||
log(f'platform: {self.platform}')
|
|
||||||
log(f'core: {self.core}')
|
|
||||||
jslisten_set('retrorun', 'retrorun32')
|
|
||||||
|
|
||||||
path = self.rom
|
|
||||||
if self.rom.suffix in {'.zip', '.7z', '.gz', '.bz2'} and self.platform not in {'arcade', 'naomi', 'atomiswave', 'fbneo', 'mame'}:
|
|
||||||
path = extract_archive(self.rom)
|
|
||||||
self.temp_files.append(path)
|
|
||||||
|
|
||||||
return [INSTALL_DIR + '/usr/bin/retrorun.sh', core_path, path, self.platform]
|
|
||||||
|
|
||||||
def get_mupen64plus_standalone_command(self) -> 'Sequence[Union[str, Path]]':
|
|
||||||
if not self.rom:
|
|
||||||
raise ValueError('runemu.py was called improperly, tried to launch Mupen64Plus standalone with no video plugin')
|
|
||||||
if not self.core:
|
|
||||||
raise ValueError('runemu.py was called improperly, tried to launch Mupen64Plus standalone with no video plugin')
|
|
||||||
if log_level != 'minimal':
|
|
||||||
log(f'Running Mupen64Plus standalone with {self.core} video plugin')
|
|
||||||
jslisten_set('mupen64plus')
|
|
||||||
path = self.rom
|
|
||||||
if self.rom.suffix in {'.zip', '.7z', '.gz', '.bz2'}:
|
|
||||||
path = extract_archive(self.rom)
|
|
||||||
self.temp_files.append(path)
|
|
||||||
|
|
||||||
return [INSTALL_DIR + '/usr/bin/m64p.sh', self.core, path]
|
|
||||||
|
|
||||||
def get_command(self, shader_arg: str='') -> 'Sequence[Union[str, Path]]':
|
|
||||||
is_libretro_port = self.core and not self.emulator
|
|
||||||
#If true this was called from the inside of a port .sh that runs a libretro port (e.g. 2048, tyrQuake, etc), it makes no sense otherwise
|
|
||||||
|
|
||||||
if self.rom and (self.rom.suffix == '.sh' or self.platform == 'tools'):
|
|
||||||
#If the ROM is a shell script then just execute it (tools, ports, Pico-8 splore, ScummVM scanner, etc)
|
|
||||||
return ['/usr/bin/bash', '-l', self.rom]
|
|
||||||
elif self.emulator == 'retroarch' or is_libretro_port:
|
|
||||||
return self.get_retroarch_command(shader_arg)
|
|
||||||
elif self.emulator == 'retrorun':
|
|
||||||
return self.get_retrorun_command()
|
|
||||||
elif self.emulator == 'mupen64plussa':
|
|
||||||
return self.get_mupen64plus_standalone_command()
|
|
||||||
else:
|
|
||||||
return self.get_standalone_emulator_command()
|
|
||||||
|
|
||||||
def run(self, command: 'Sequence[Union[str, Path]]') -> None:
|
|
||||||
clear_screen()
|
|
||||||
if log_level != 'minimal':
|
|
||||||
log(f'Executing game: {self.rom}')
|
|
||||||
log(f'Executing {command}')
|
|
||||||
with log_path.open('at', encoding='utf-8') as log_file:
|
|
||||||
subprocess.run(command, stdout=log_file, stderr=subprocess.STDOUT, check=True, text=True, env=self.environment)
|
|
||||||
|
|
||||||
def cleanup_temp_files(self) -> None:
|
|
||||||
for temp_file in self.temp_files:
|
|
||||||
temp_file.unlink(missing_ok=True)
|
|
||||||
|
|
||||||
def main():
|
|
||||||
time_started = perf_counter()
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
args: dict[str, str] = {}
|
|
||||||
while i < len(sys.argv)-1:
|
|
||||||
if sys.argv[i].startswith('--'):
|
|
||||||
args[sys.argv[i][2:]] = sys.argv[i + 1]
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
if sys.argv[i].startswith('-'):
|
|
||||||
args[sys.argv[i][1:]] = sys.argv[i + 1]
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
rom = Path(args['rom']) if 'rom' in args else None
|
|
||||||
platform = args.get('platform')
|
|
||||||
core = args.get('core')
|
|
||||||
emulator = args.get('emulator')
|
|
||||||
|
|
||||||
log_path.unlink(missing_ok=True)
|
|
||||||
LOGS_DIR.mkdir(parents=True, exist_ok=True)
|
|
||||||
log_path.touch()
|
|
||||||
|
|
||||||
log(f'Emulation run log: Started at {datetime.datetime.now()}')
|
|
||||||
log(f'Args: {args}')
|
|
||||||
|
|
||||||
runner = EmuRunner(rom, platform, emulator, core, args)
|
|
||||||
|
|
||||||
runner.download_things_if_needed()
|
|
||||||
runner.toggle_max_performance()
|
|
||||||
|
|
||||||
#Disable netplay by default
|
|
||||||
set_elec_setting('netplay.client.ip', 'disable')
|
|
||||||
set_elec_setting('netplay.client.port', 'disable')
|
|
||||||
|
|
||||||
jslisten_stop()
|
|
||||||
|
|
||||||
shader_arg = runner.set_settings()
|
|
||||||
command = runner.get_command(shader_arg)
|
|
||||||
if log_level != 'minimal':
|
|
||||||
log(f'Took {perf_counter() - time_started} seconds to start up')
|
|
||||||
clear_screen()
|
|
||||||
|
|
||||||
try:
|
|
||||||
runner.run(command)
|
|
||||||
exit_code = 0
|
|
||||||
except subprocess.CalledProcessError as cpe:
|
|
||||||
log(f'Process exited improperly with return code {cpe.returncode}')
|
|
||||||
exit_code = 1
|
|
||||||
requires_bios = {'atari5200', 'atari800', 'atari7800', 'atarilynx', 'colecovision', 'amiga', 'amigacd32', 'o2em', 'intellivision', 'pcengine', 'pcenginecd', 'pcfx', 'fds', 'segacd', 'saturn', 'dreamcast', 'naomi', 'atomiswave', 'x68000', 'neogeo', 'neogeocd', 'msx', 'msx2', 'sc-3000', 'pcsx2'}
|
|
||||||
if platform in requires_bios:
|
|
||||||
if platform == 'msx2':
|
|
||||||
platform_to_check = 'msx2'
|
|
||||||
elif platform == 'pcenginecd':
|
|
||||||
platform_to_check = 'pcengine'
|
|
||||||
elif platform == 'amigacd32':
|
|
||||||
platform_to_check = 'amiga'
|
|
||||||
else:
|
|
||||||
platform_to_check = platform
|
|
||||||
check_bios(platform_to_check, core, emulator, rom, log_path)
|
|
||||||
finally:
|
|
||||||
runner.cleanup_temp_files()
|
|
||||||
cleanup_and_quit(exit_code)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,700 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
#
|
|
||||||
# setsettings.py:
|
|
||||||
# Copyright (C) 2021-present konsumschaf
|
|
||||||
# Copyright (C) 2021-present konsumlamm
|
|
||||||
#
|
|
||||||
# based on setsettings.sh:
|
|
||||||
# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert)
|
|
||||||
# Copyright (C) 2020-present Fewtarius
|
|
||||||
|
|
||||||
|
|
||||||
# Convert ES settings from distribution.conf to RetroArch configuration in raappend.conf.
|
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
|
||||||
from configparser import ConfigParser
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from glob import iglob
|
|
||||||
import os
|
|
||||||
import random
|
|
||||||
import re
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
# If we are on Steam Deck we want a prefix
|
|
||||||
DEVICE = "DECK"
|
|
||||||
# TODO: put a real check on the .OS_ARCH file, or maybe not as we are obviously running on Deck
|
|
||||||
INSTALL_DIR = os.path.expanduser("~/retrodeck")
|
|
||||||
|
|
||||||
# if DEVICE == "DECK" :
|
|
||||||
#
|
|
||||||
#else:
|
|
||||||
# INSTALL_DIR = ""
|
|
||||||
|
|
||||||
# Files and Folder
|
|
||||||
ra_conf = INSTALL_DIR + "/storage/.config/retroarch/retroarch.cfg"
|
|
||||||
ra_source_conf = INSTALL_DIR + "/usr/config/retroarch/retroarch.cfg"
|
|
||||||
ra_core_conf = INSTALL_DIR + "/storage/.config/retroarch/retroarch-core-options.cfg"
|
|
||||||
ra_append_conf = "/tmp/raappend.cfg"
|
|
||||||
os_arch_conf = INSTALL_DIR + "/storage/.config/.OS_ARCH"
|
|
||||||
snapshots = INSTALL_DIR + "/storage/roms/savestates"
|
|
||||||
|
|
||||||
# Logging
|
|
||||||
class Logger:
|
|
||||||
dir = "/tmp/logs"
|
|
||||||
file = "exec.log"
|
|
||||||
script_basename = os.path.basename(__file__)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
if not os.path.isdir(self.dir):
|
|
||||||
os.makedirs(self.dir)
|
|
||||||
self.file_handle = open(f'{self.dir}/{self.file}',"a+")
|
|
||||||
|
|
||||||
def log(self, text: str) -> None:
|
|
||||||
self.file_handle.write(f'{self.script_basename}: {text}\n')
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
self.file_handle.close()
|
|
||||||
|
|
||||||
|
|
||||||
# No Sections in distribution.conf, we have to fake our own
|
|
||||||
class MyConfigParser(ConfigParser):
|
|
||||||
def read(self, filename: str) -> None:
|
|
||||||
text = open(filename, encoding="utf_8").read()
|
|
||||||
self.read_string("[351elec]\n" + text, filename)
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Config:
|
|
||||||
rom_name: str
|
|
||||||
platform: str
|
|
||||||
|
|
||||||
distribution_conf = INSTALL_DIR + "/storage/.config/distribution/configs/distribution.conf"
|
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
# Read the distribution.conf to a dictionary
|
|
||||||
config_parser = MyConfigParser(strict=False)
|
|
||||||
config_parser.read(self.distribution_conf)
|
|
||||||
self.config = config_parser['351elec']
|
|
||||||
|
|
||||||
def get_setting(self, setting: str) -> str:
|
|
||||||
"""Get the settings from distribution.conf"""
|
|
||||||
|
|
||||||
pat_rom = f'{self.platform}["{self.rom_name}"].{setting}'
|
|
||||||
pat_platform = f'{self.platform}.{setting}'
|
|
||||||
pat_global = f'global.{setting}'
|
|
||||||
|
|
||||||
if pat_rom in self.config:
|
|
||||||
value = self.config[pat_rom]
|
|
||||||
elif pat_platform in self.config:
|
|
||||||
value = self.config[pat_platform]
|
|
||||||
elif pat_global in self.config:
|
|
||||||
value = self.config[pat_global]
|
|
||||||
else:
|
|
||||||
value = ""
|
|
||||||
|
|
||||||
if value == "0":
|
|
||||||
value = ""
|
|
||||||
return value
|
|
||||||
|
|
||||||
def get_bool_string(self, setting: str) -> str:
|
|
||||||
"""For readability a function that returns "true" and "false" directly."""
|
|
||||||
|
|
||||||
if self.get_setting(setting):
|
|
||||||
return "true"
|
|
||||||
else:
|
|
||||||
return "false"
|
|
||||||
|
|
||||||
# Delete lines from a config file
|
|
||||||
def delete_lines(file_path: str, lines: tuple) -> None:
|
|
||||||
with open(file_path, "r") as input:
|
|
||||||
tmp_file = f'/tmp/{os.path.basename(file_path)}.tmp'
|
|
||||||
with open(tmp_file, "w") as output:
|
|
||||||
for line in input:
|
|
||||||
write_this_line = True
|
|
||||||
for item in lines:
|
|
||||||
if line.strip().startswith(item):
|
|
||||||
write_this_line = False
|
|
||||||
break
|
|
||||||
if write_this_line:
|
|
||||||
output.write(line)
|
|
||||||
# replace file with original name
|
|
||||||
shutil.move(tmp_file, file_path)
|
|
||||||
|
|
||||||
# Append dictionary to the end of a file
|
|
||||||
def write_file(file_path: str, dictionary: dict, separator: str = ' = ', quote_sign: str = '"') -> None:
|
|
||||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
||||||
with open(file_path, "a") as file:
|
|
||||||
for (key, value) in dictionary.items():
|
|
||||||
file.write(f'{key}{separator}{quote_sign}{value}{quote_sign}\n')
|
|
||||||
|
|
||||||
# Generate the config out of the distribution.conf
|
|
||||||
def set_settings(rom_name: str, core: str, platform: str, controllers: str, autosave: str, snapshot: str) -> str:
|
|
||||||
logger = Logger()
|
|
||||||
shader_path = ''
|
|
||||||
|
|
||||||
#
|
|
||||||
# Do some checks and clean up first
|
|
||||||
#
|
|
||||||
|
|
||||||
# Log current call:
|
|
||||||
logger.log(f'ROM: {rom_name}')
|
|
||||||
logger.log(f'Platform: {platform}')
|
|
||||||
logger.log(f'Core: {core}')
|
|
||||||
logger.log(f'Controllers: {controllers}')
|
|
||||||
logger.log(f'Autosave: {autosave}')
|
|
||||||
logger.log(f'Snapshot: {snapshot}')
|
|
||||||
|
|
||||||
# We only need the ROM, but we get the fullpath
|
|
||||||
rom_name = os.path.basename(rom_name)
|
|
||||||
# Delete any existing raappend.cfg first
|
|
||||||
if os.path.isfile(ra_append_conf):
|
|
||||||
os.remove(ra_append_conf)
|
|
||||||
# Restore retroarch.cfg if it is missing or empty
|
|
||||||
if not os.path.isfile(ra_conf) or os.stat(ra_conf).st_size == 0:
|
|
||||||
shutil.copy(ra_source_conf,ra_conf)
|
|
||||||
|
|
||||||
# Get the Device Name
|
|
||||||
with open(os_arch_conf, encoding="utf-8") as f:
|
|
||||||
device_name = f.readline().strip()
|
|
||||||
logger.log(f'Device: {device_name}')
|
|
||||||
|
|
||||||
# Is the CORE 32 or 64bit?
|
|
||||||
if core in {'pcsx_rearmed', 'parallel_n64'}:
|
|
||||||
bits='32bit'
|
|
||||||
else:
|
|
||||||
bits='64bit'
|
|
||||||
logger.log(f'core is {bits}')
|
|
||||||
|
|
||||||
# Dictionary for the raappend.cfg
|
|
||||||
ra_append_dict = {}
|
|
||||||
|
|
||||||
# Create config from distribution.conf
|
|
||||||
config = Config(rom_name, platform)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Global configuration directly in retroarch.cfg
|
|
||||||
#
|
|
||||||
|
|
||||||
# RA menu rgui, ozone, glui or xmb (fallback if everthing else fails)
|
|
||||||
# if empty (auto in ES) do nothing to enable configuration in RA
|
|
||||||
if menu_driver := config.get_setting('retroarch.menu_driver'):
|
|
||||||
ra_dict = {}
|
|
||||||
# delete setting only if we set new ones
|
|
||||||
# therefore configuring in RA is still possible
|
|
||||||
delete_lines(ra_conf, ('menu_driver', 'menu_linear_filter'))
|
|
||||||
if menu_driver == 'rgui':
|
|
||||||
ra_dict['menu_driver'] = 'rgui'
|
|
||||||
ra_dict['menu_linear_filter'] = 'true'
|
|
||||||
elif menu_driver == 'ozone':
|
|
||||||
ra_dict['menu_driver'] = 'ozone'
|
|
||||||
elif menu_driver == 'glui':
|
|
||||||
ra_dict['menu_driver'] = 'glui'
|
|
||||||
else:
|
|
||||||
# play it save and set xmb if nothing else matches
|
|
||||||
ra_dict['menu_driver'] = 'xmb'
|
|
||||||
write_file(ra_conf, ra_dict)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Convert the settings from distribution.conf to raappend.cfg
|
|
||||||
#
|
|
||||||
|
|
||||||
# FPS
|
|
||||||
ra_append_dict['fps_show'] = config.get_bool_string("showFPS")
|
|
||||||
|
|
||||||
# Retroachievements / Cheevos
|
|
||||||
retro_achievements = {
|
|
||||||
'arcade', 'atari2600', 'atari7800', 'atarilynx', 'colecovision',
|
|
||||||
'famicom', 'fbn', 'fds', 'gamegear', 'gb', 'gba', 'gbah', 'gbc', 'gbch',
|
|
||||||
'gbh', 'genesis', 'genh', 'ggh', 'intellivision', 'mastersystem',
|
|
||||||
'megacd', 'megadrive', 'megadrive-japan', 'msx', 'msx2', 'n64',
|
|
||||||
'neogeo', 'neogeocd', 'nes', 'nesh', 'ngp', 'ngpc', 'odyssey2',
|
|
||||||
'pcengine', 'pcenginecd', 'pcfx', 'pokemini', 'psp', 'psx', 'sega32x',
|
|
||||||
'segacd', 'sfc', 'sg-1000', 'snes', 'snesh', 'snesmsu1', 'supergrafx',
|
|
||||||
'supervision', 'tg16', 'tg16cd', 'vectrex', 'virtualboy', 'wonderswan',
|
|
||||||
'wonderswancolor',
|
|
||||||
}
|
|
||||||
if platform in retro_achievements:
|
|
||||||
if config.get_setting("retroachievements"):
|
|
||||||
ra_append_dict['cheevos_enable'] = "true"
|
|
||||||
ra_append_dict['cheevos_username'] = config.get_setting("retroachievements.username")
|
|
||||||
ra_append_dict['cheevos_password'] = config.get_setting("retroachievements.password")
|
|
||||||
ra_append_dict['cheevos_hardcore_mode_enable'] = config.get_bool_string("retroachievements.hardcore")
|
|
||||||
value = config.get_setting("retroachievements.leaderboards")
|
|
||||||
if value == "enabled":
|
|
||||||
ra_append_dict['cheevos_leaderboards_enable'] = "true"
|
|
||||||
elif value == "trackers only":
|
|
||||||
ra_append_dict['cheevos_leaderboards_enable'] = "trackers"
|
|
||||||
elif value == "notifications only":
|
|
||||||
ra_append_dict['cheevos_leaderboards_enable'] = "notifications"
|
|
||||||
else:
|
|
||||||
ra_append_dict['cheevos_leaderboards_enable'] = "false"
|
|
||||||
ra_append_dict['cheevos_verbose_enable'] = config.get_bool_string("retroachievements.verbose")
|
|
||||||
ra_append_dict['cheevos_auto_screenshot'] = config.get_bool_string("retroachievements.screenshot")
|
|
||||||
ra_append_dict['cheevos_richpresence_enable'] = config.get_bool_string("retroachievements.richpresence")
|
|
||||||
ra_append_dict['cheevos_challenge_indicators'] = config.get_bool_string("retroachievements.challengeindicators")
|
|
||||||
ra_append_dict['cheevos_test_unofficial'] = config.get_bool_string("retroachievements.testunofficial")
|
|
||||||
ra_append_dict['cheevos_badges_enable'] = config.get_bool_string("retroachievements.badges")
|
|
||||||
ra_append_dict['cheevos_start_active'] = config.get_bool_string("retroachievements.active")
|
|
||||||
ra_append_dict['cheevos_unlock_sound_enable'] = config.get_bool_string("retroachievements.soundenable")
|
|
||||||
else:
|
|
||||||
ra_append_dict['cheevos_enable'] = "false"
|
|
||||||
ra_append_dict['cheevos_username'] = ""
|
|
||||||
ra_append_dict['cheevos_password'] = ""
|
|
||||||
ra_append_dict['cheevos_hardcore_mode_enable'] = "false"
|
|
||||||
ra_append_dict['cheevos_leaderboards_enable'] = "false"
|
|
||||||
ra_append_dict['cheevos_verbose_enable'] = "false"
|
|
||||||
ra_append_dict['cheevos_test_unofficial'] = "false"
|
|
||||||
ra_append_dict['cheevos_unlock_sound_enable'] = "false"
|
|
||||||
ra_append_dict['cheevos_auto_screenshot'] = "false"
|
|
||||||
ra_append_dict['cheevos_badges_enable'] = "false"
|
|
||||||
ra_append_dict['cheevos_start_active'] = "false"
|
|
||||||
ra_append_dict['cheevos_richpresence_enable'] = "false"
|
|
||||||
ra_append_dict['cheevos_challenge_indicators'] = "false"
|
|
||||||
|
|
||||||
# Netplay
|
|
||||||
if config.get_setting("netplay"):
|
|
||||||
ra_append_dict['netplay'] = "true"
|
|
||||||
# Not needed any more?
|
|
||||||
## Disable Cheevos Hardcore Mode to allow savestates
|
|
||||||
#if 'cheevos_hardcore_mode_enable' in ra_append_dict:
|
|
||||||
# ra_append_dict['cheevos_hardcore_mode_enable'] = "false"
|
|
||||||
# Host or Client
|
|
||||||
value = config.get_setting('netplay.mode')
|
|
||||||
if value == 'host':
|
|
||||||
ra_append_dict['netplay_mode'] = "false"
|
|
||||||
ra_append_dict['netplay_client_swap_input'] = "false"
|
|
||||||
ra_append_dict['netplay_ip_port'] = config.get_setting('netplay.port')
|
|
||||||
elif value == 'client':
|
|
||||||
ra_append_dict['netplay_mode'] = "true"
|
|
||||||
ra_append_dict['netplay_ip_address'] = config.get_setting('netplay.client.ip')
|
|
||||||
ra_append_dict['netplay_ip_port'] = config.get_setting('netplay.client.port')
|
|
||||||
ra_append_dict['netplay_client_swap_input'] = "true"
|
|
||||||
# Relay
|
|
||||||
if value := config.get_setting('netplay.relay'):
|
|
||||||
ra_append_dict['netplay_use_mitm_server'] = "true"
|
|
||||||
ra_append_dict['netplay_mitm_server'] = value
|
|
||||||
else:
|
|
||||||
ra_append_dict['netplay_use_mitm_server'] = "false"
|
|
||||||
ra_append_dict['netplay_delay_frames'] = config.get_setting('netplay.frames')
|
|
||||||
ra_append_dict['netplay_nickname'] = config.get_setting('netplay.nickname')
|
|
||||||
# spectator mode
|
|
||||||
ra_append_dict['netplay_spectator_mode_enable'] = config.get_bool_string("netplay.spectator")
|
|
||||||
ra_append_dict['netplay_public_announce'] = config.get_bool_string("netplay_public_announce")
|
|
||||||
else:
|
|
||||||
ra_append_dict['netplay'] = "false"
|
|
||||||
|
|
||||||
# AI Translation Service
|
|
||||||
if config.get_setting('ai_service_enabled'):
|
|
||||||
ra_append_dict['ai_service_enable'] = "true"
|
|
||||||
LangCodes = {
|
|
||||||
"false": "0", "En": "1", "Fr": "3", "Pt": "49", "De": "5",
|
|
||||||
"El": "30", "Es": "2", "Cs": "8", "Da": "9", "Hr": "11", "Hu": "35",
|
|
||||||
"It": "4", "Ja": "6", "Ko": "12", "Nl": "7", "Nn": "46", "Po": "48",
|
|
||||||
"Ro": "50", "Ru": "51", "Sv": "10", "Tr": "59", "Zh": "13",
|
|
||||||
}
|
|
||||||
ai_lang = config.get_setting('ai_target_lang')
|
|
||||||
if ai_lang in LangCodes:
|
|
||||||
ra_append_dict['ai_service_target_lang'] = f'{LangCodes[ai_lang]}'
|
|
||||||
else:
|
|
||||||
# use English as default
|
|
||||||
ra_append_dict['ai_service_target_lang'] = "1"
|
|
||||||
if ai_url := config.get_setting('ai_service_url'):
|
|
||||||
ra_append_dict['ai_service_url'] = f'{ai_url}&mode=Fast&output=png&target_lang={ai_lang}'
|
|
||||||
else:
|
|
||||||
ra_append_dict['ai_service_url'] = f'http://ztranslate.net/service?api_key=BATOCERA&mode=Fast&output=png&target_lang={ai_lang}'
|
|
||||||
else:
|
|
||||||
ra_append_dict['ai_service_enable'] = "false"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Global/System/Game specific settings
|
|
||||||
#
|
|
||||||
|
|
||||||
# Ratio
|
|
||||||
# default to 22 (core provided) if case anything goes wrong
|
|
||||||
ra_append_dict['aspect_ratio_index'] = "22"
|
|
||||||
if ratio := config.get_setting('ratio'):
|
|
||||||
index_rations = {
|
|
||||||
'4/3': '0', '16/9': '1', '16/10': '2', '16/15': '3', '21/9': '4',
|
|
||||||
'1/1': '5', '2/1': '6', '3/2': '7', '3/4': '8', '4/1': '9',
|
|
||||||
'9/16': '10', '5/4': '11', '6/5': '12', '7/9': '13', '8/3': '14',
|
|
||||||
'8/7': '15', '19/12': '16', '19/14': '17', '30/17': '18',
|
|
||||||
'32/9': '19', 'config': '20', 'squarepixel': '21', 'core': '22',
|
|
||||||
'custom': '23', 'full' : '24',
|
|
||||||
}
|
|
||||||
if ratio in index_rations:
|
|
||||||
ra_append_dict['aspect_ratio_index'] = index_rations[ratio]
|
|
||||||
|
|
||||||
# Bilinear filtering
|
|
||||||
ra_append_dict['video_smooth'] = config.get_bool_string("smooth")
|
|
||||||
|
|
||||||
# Video Integer Scale
|
|
||||||
ra_append_dict['video_scale_integer'] = config.get_bool_string("integerscale")
|
|
||||||
|
|
||||||
# Video Integer Scale Overscale
|
|
||||||
ra_append_dict['video_scale_integer_overscale'] = config.get_bool_string("integerscaleoverscale")
|
|
||||||
|
|
||||||
# RGA Scaling / CTX Scaling
|
|
||||||
ra_append_dict['video_ctx_scaling'] = config.get_bool_string("rgascale")
|
|
||||||
|
|
||||||
# Shaderset
|
|
||||||
if shaderset := config.get_setting('shaderset'):
|
|
||||||
ra_append_dict['video_shader_enable'] = "true"
|
|
||||||
ra_append_dict['video_shader'] = shaderset
|
|
||||||
# We need to print the shader folder for runemu.sh to use it
|
|
||||||
shader_path = f'--set-shader /tmp/shaders/{shaderset}'
|
|
||||||
else:
|
|
||||||
ra_append_dict['video_shader_enable'] = "false"
|
|
||||||
ra_append_dict['video_shader'] = ""
|
|
||||||
|
|
||||||
# Filters
|
|
||||||
# Set correct path for video- and audio-filters depending on 32/64bit
|
|
||||||
ra_append_dict['audio_filter_dir'] = f'/usr/share/retroarch/filters/{bits}/audio'
|
|
||||||
ra_append_dict['video_filter_dir'] = f'/usr/share/retroarch/filters/{bits}/video'
|
|
||||||
# Filterset
|
|
||||||
if filterset := config.get_setting('filterset'):
|
|
||||||
# Filter do not work with RGA/CTX enabled
|
|
||||||
ra_append_dict['video_ctx_scaling'] = "false"
|
|
||||||
ra_append_dict['video_filter'] = f'/usr/share/retroarch/filters/{bits}/video/{filterset}'
|
|
||||||
else:
|
|
||||||
ra_append_dict['video_filter'] = ""
|
|
||||||
|
|
||||||
# Rewind
|
|
||||||
no_rewind = {'sega32x', 'psx', 'zxspectrum', 'odyssey2', 'mame', 'n64', 'dreamcast', 'atomiswave', 'naomi', 'neogeocd', 'saturn', 'psp', 'pspminis'}
|
|
||||||
if config.get_setting('rewind') and platform not in no_rewind:
|
|
||||||
ra_append_dict['rewind_enable'] = "true"
|
|
||||||
else:
|
|
||||||
ra_append_dict['rewind_enable'] = "false"
|
|
||||||
|
|
||||||
# Saves
|
|
||||||
# Incrementalsavestates
|
|
||||||
if config.get_setting('incrementalsavestates'):
|
|
||||||
ra_append_dict['savestate_auto_index'] = "true"
|
|
||||||
ra_append_dict['savestate_max_keep'] = "0"
|
|
||||||
else:
|
|
||||||
ra_append_dict['savestate_auto_index'] = "false"
|
|
||||||
ra_append_dict['savestate_max_keep'] = "50"
|
|
||||||
# Autosave
|
|
||||||
if config.get_setting('autosave'):
|
|
||||||
ra_append_dict['savestate_auto_save'] = "true"
|
|
||||||
ra_append_dict['savestate_auto_load'] = "true"
|
|
||||||
else:
|
|
||||||
ra_append_dict['savestate_auto_save'] = "false"
|
|
||||||
ra_append_dict['savestate_auto_load'] = "false"
|
|
||||||
# Snapshots
|
|
||||||
ra_append_dict['savestate_directory'] = f'{snapshots}/{platform}'
|
|
||||||
if snapshot:
|
|
||||||
if autosave == "1":
|
|
||||||
ra_append_dict['savestate_auto_load'] = "true"
|
|
||||||
ra_append_dict['savestate_auto_save'] = "true"
|
|
||||||
else:
|
|
||||||
ra_append_dict['savestate_auto_load'] = "false"
|
|
||||||
ra_append_dict['savestate_auto_save'] = "false"
|
|
||||||
ra_append_dict['state_slot'] = f'{snapshot}'
|
|
||||||
|
|
||||||
# Runahead
|
|
||||||
# Runahead 1st Instance
|
|
||||||
no_run_ahead = {'psp', 'sega32x', 'n64', 'dreamcast', 'atomiswave', 'naomi', 'neogeocd', 'saturn'}
|
|
||||||
if (runahead := config.get_setting('runahead')) and platform not in no_run_ahead:
|
|
||||||
ra_append_dict['run_ahead_enabled'] = "true"
|
|
||||||
ra_append_dict['run_ahead_frames'] = runahead
|
|
||||||
else:
|
|
||||||
ra_append_dict['run_ahead_enabled'] = "false"
|
|
||||||
ra_append_dict['run_ahead_frames'] = "1"
|
|
||||||
# Runahead 2nd Instance
|
|
||||||
if config.get_setting('secondinstance') and platform not in no_run_ahead:
|
|
||||||
ra_append_dict['run_ahead_secondary_instance'] = "true"
|
|
||||||
else:
|
|
||||||
ra_append_dict['run_ahead_secondary_instance'] = "false"
|
|
||||||
|
|
||||||
# Auto Frame Relay
|
|
||||||
ra_append_dict['video_frame_delay_auto'] = config.get_bool_string("video_frame_delay_auto")
|
|
||||||
|
|
||||||
# maxperf / CPU Governor
|
|
||||||
if config.get_setting('maxperf'):
|
|
||||||
ra_append_dict['cpu_scaling_mode'] = '2'
|
|
||||||
else:
|
|
||||||
ra_append_dict['cpu_scaling_mode'] = '4'
|
|
||||||
|
|
||||||
#
|
|
||||||
# Settings for special cores
|
|
||||||
#
|
|
||||||
|
|
||||||
## atari800 core needs other settings when emulation atari5200
|
|
||||||
if core == 'atari800':
|
|
||||||
logger.log('Atari 800 section')
|
|
||||||
retrocore_dict = {}
|
|
||||||
atari800_dict = {}
|
|
||||||
atari_dict = {}
|
|
||||||
atari_conf = INSTALL_DIR + '/storage/.config/distribution/configs/atari800.cfg'
|
|
||||||
atari800_conf = INSTALL_DIR + '/storage/.config/retroarch/config/Atari800/Atari800.opt'
|
|
||||||
delete_lines(ra_core_conf, ('atari800_system =',))
|
|
||||||
delete_lines(atari_conf, ('RAM_SIZE', 'STEREO_POKEY', 'BUILTIN_BASIC'))
|
|
||||||
if os.path.isfile(atari800_conf):
|
|
||||||
delete_lines(atari800_conf, ('atari800_system',))
|
|
||||||
if platform == 'atari5200':
|
|
||||||
retrocore_dict['atari800_system'] = '5200'
|
|
||||||
atari800_dict['atari800_system'] = '5200'
|
|
||||||
atari_dict['RAM_SIZE'] = '16'
|
|
||||||
atari_dict['STEREO_POKEY'] = '0'
|
|
||||||
atari_dict['BUILTIN_BASIC'] = '0'
|
|
||||||
else:
|
|
||||||
retrocore_dict['atari800_system'] = '800XL (64K)'
|
|
||||||
atari800_dict['atari800_system'] = '800XL (64K)'
|
|
||||||
atari_dict['RAM_SIZE'] = '64'
|
|
||||||
atari_dict['STEREO_POKEY'] = '1'
|
|
||||||
atari_dict['BUILTIN_BASIC'] = '1'
|
|
||||||
write_file(ra_core_conf, retrocore_dict)
|
|
||||||
# The format of the atari800.cfg is different
|
|
||||||
# ('key=value' instead of 'key = "value"')
|
|
||||||
write_file(atari_conf, atari_dict, separator='=', quote_sign='')
|
|
||||||
write_file(atari800_conf, atari800_dict)
|
|
||||||
|
|
||||||
# Gambatte
|
|
||||||
if core == 'gambatte':
|
|
||||||
logger.log('Gambatte section')
|
|
||||||
gambatte_dict = {}
|
|
||||||
gambatte_conf = INSTALL_DIR + "/storage/.config/retroarch/config/Gambatte/Gambatte.opt"
|
|
||||||
|
|
||||||
if os.path.isfile(gambatte_conf):
|
|
||||||
delete_lines(gambatte_conf, ('gambatte_gb_colorization', 'gambatte_gb_internal_palette'))
|
|
||||||
else:
|
|
||||||
gambatte_dict['gambatte_gbc_color_correction'] = 'disabled'
|
|
||||||
|
|
||||||
colorization = config.get_setting('renderer.colorization')
|
|
||||||
logger.log(f'gambatte colorization: {colorization}')
|
|
||||||
if not colorization or colorization == 'auto':
|
|
||||||
gambatte_dict['gambatte_gb_colorization'] = 'disabled'
|
|
||||||
elif colorization == 'Best Guess':
|
|
||||||
gambatte_dict['gambatte_gb_colorization'] = 'auto'
|
|
||||||
elif colorization == 'GBC' or colorization == 'SGB':
|
|
||||||
gambatte_dict['gambatte_gb_colorization'] = colorization
|
|
||||||
else:
|
|
||||||
gambatte_dict['gambatte_gb_colorization'] = 'internal'
|
|
||||||
gambatte_dict['gambatte_gb_internal_palette'] = colorization
|
|
||||||
|
|
||||||
write_file(gambatte_conf, gambatte_dict)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Controllers
|
|
||||||
#
|
|
||||||
# We set up the controller index
|
|
||||||
if controllers:
|
|
||||||
for player in range(1,6):
|
|
||||||
logger.log(f'Controller section {player}')
|
|
||||||
if pindex := re.search(fr'p{player}index\s+([0-9]+)', controllers):
|
|
||||||
ra_append_dict['input_player{player}_joypad_index'] = pindex.group(1)
|
|
||||||
# Setting controller type for different cores
|
|
||||||
if platform == "atari5200":
|
|
||||||
ra_append_dict['input_libretro_device_p{player}'] = '513'
|
|
||||||
|
|
||||||
#
|
|
||||||
# Bezels / Decorations
|
|
||||||
#
|
|
||||||
# List of possible Bezel Folders
|
|
||||||
bezel_dir = ('/tmp/overlays/bezels', INSTALL_DIR + '/storage/roms/bezels')
|
|
||||||
# Define the resolutions of the different systems (0:x 1:y 2:width 3:height) as seen in Scaling -> Aspect Ration -> Custom
|
|
||||||
# Devices (width x hight)
|
|
||||||
# RG351P/M = 480x320
|
|
||||||
# RG351V/MP = 640x480
|
|
||||||
# RG552 = 1920x1152
|
|
||||||
# DECK = 1280x800
|
|
||||||
# Consoles (width x hight)
|
|
||||||
# GB/GBC/GG = 160x144
|
|
||||||
# supervision = 160x160
|
|
||||||
# Pokemini = 96x64
|
|
||||||
# ngp/ngpc = 160x152
|
|
||||||
# wonderswan/wonderswancolor = 224×144
|
|
||||||
if device_name == "RG351P":
|
|
||||||
system_viewport = {
|
|
||||||
'standard': (1, 1, 479, 319), # max-1
|
|
||||||
'gb': (80, 16, 320, 288), # x2
|
|
||||||
'gbh': (80, 16, 320, 288), # x2
|
|
||||||
'gbc': (80, 16, 320, 288), # x2
|
|
||||||
'gbch': (80, 16, 320, 288), # x2
|
|
||||||
'supervision': (80, 0, 320, 320), # x2
|
|
||||||
'gamegear': (80, 16, 320, 288), # x2
|
|
||||||
'ggh': (80, 16, 320, 288), # x2
|
|
||||||
'pokemini': (96, 64, 288, 192), # x3
|
|
||||||
'ngp': (80, 8, 320, 304), # x2
|
|
||||||
'ngpc': (80, 8, 320, 304), # x2
|
|
||||||
'wonderswan': (16, 16, 448, 288), # x2
|
|
||||||
'wonderswancolor': (16, 16, 448, 288), # x2
|
|
||||||
}
|
|
||||||
elif device_name == "RG351V" or device_name == "RG351MP":
|
|
||||||
system_viewport = {
|
|
||||||
'standard': (1, 1, 639, 479), # max-1
|
|
||||||
'gb': (80, 24, 480, 432), # x3
|
|
||||||
'gbh': (80, 24, 480, 432), # x3
|
|
||||||
'gbc': (80, 24, 480, 432), # x3
|
|
||||||
'gbch': (80, 24, 480, 432), # x3
|
|
||||||
'supervision': (80, 0, 480, 480), # x3
|
|
||||||
'gamegear': (80, 24, 480, 432), # x3
|
|
||||||
'ggh': (80, 24, 480, 432), # x3
|
|
||||||
'pokemini': (128, 112, 384, 256), # x4
|
|
||||||
'ngp': (80, 12, 480, 456), # x3
|
|
||||||
'ngpc': (80, 12, 480, 456), # x3
|
|
||||||
'wonderswan': (96, 96, 448, 288), # x2
|
|
||||||
'wonderswancolor': (96, 96, 448, 288), # x2
|
|
||||||
}
|
|
||||||
elif device_name == "RG552":
|
|
||||||
system_viewport = {
|
|
||||||
'standard': (1, 1, 1919, 1151), # max-1
|
|
||||||
'gb': (320, 0, 1280, 1152), # x8
|
|
||||||
'gbh': (320, 0, 1280, 1152), # x8
|
|
||||||
'gbc': (320, 0, 1280, 1152), # x8
|
|
||||||
'gbch': (320, 0, 1280, 1152), # x8
|
|
||||||
'supervision': (400, 16, 1120, 1120), # x7
|
|
||||||
'gamegear': (320, 0, 1280, 1152), # x8
|
|
||||||
'ggh': (320, 0, 1280, 1152), # x8
|
|
||||||
'pokemini': (384, 192, 1152, 768), # x12
|
|
||||||
'ngp': (400, 44, 1120, 1064), # x7
|
|
||||||
'ngpc': (400, 44, 1120, 1064), # x7
|
|
||||||
'wonderswan': (64, 0, 1792, 1152), # x8
|
|
||||||
'wonderswancolor': (64, 0, 1792, 1152), # x8
|
|
||||||
}
|
|
||||||
elif device_name == "DECK":
|
|
||||||
#just copied from 552, I have to edit this
|
|
||||||
system_viewport = {
|
|
||||||
'standard': (1, 1, 1279, 799), # max-1
|
|
||||||
'gb': (320, 0, 1280, 1152), # x8
|
|
||||||
'gbh': (320, 0, 1280, 1152), # x8
|
|
||||||
'gbc': (320, 0, 1280, 1152), # x8
|
|
||||||
'gbch': (320, 0, 1280, 1152), # x8
|
|
||||||
'supervision': (400, 16, 1120, 1120), # x7
|
|
||||||
'gamegear': (320, 0, 1280, 1152), # x8
|
|
||||||
'ggh': (320, 0, 1280, 1152), # x8
|
|
||||||
'pokemini': (384, 192, 1152, 768), # x12
|
|
||||||
'ngp': (400, 44, 1120, 1064), # x7
|
|
||||||
'ngpc': (400, 44, 1120, 1064), # x7
|
|
||||||
'wonderswan': (64, 0, 1792, 1152), # x8
|
|
||||||
'wonderswancolor': (64, 0, 1792, 1152), # x8
|
|
||||||
}
|
|
||||||
|
|
||||||
bezel_cfg = None
|
|
||||||
|
|
||||||
if (bezel := config.get_setting('bezel')) and platform in system_viewport:
|
|
||||||
logger.log(f'bezel: {bezel} platform: {platform} rom: {rom_name}')
|
|
||||||
tmp_bezel = "/tmp/351elec-bezel.cfg"
|
|
||||||
game_cfg = ''
|
|
||||||
# set path
|
|
||||||
path = ''
|
|
||||||
for searchpath in bezel_dir:
|
|
||||||
if os.path.isdir(f'{searchpath}/{bezel}'):
|
|
||||||
path = f'{searchpath}/{bezel}'
|
|
||||||
|
|
||||||
bezel_system = config.get_setting('bezel.system.override')
|
|
||||||
if not bezel_system or bezel_system == "AUTO":
|
|
||||||
bezel_system = platform
|
|
||||||
|
|
||||||
bezel_system_png = f'{path}/systems/{bezel_system}.png'
|
|
||||||
logger.log(f'Bezel system png: {bezel_system_png}')
|
|
||||||
|
|
||||||
game_bezel_override = config.get_setting('bezel.game.override')
|
|
||||||
logger.log(f'Game bezel override: {game_bezel_override}')
|
|
||||||
if not game_bezel_override or game_bezel_override == "AUTO":
|
|
||||||
logger.log('No game specific override found. Looking for games')
|
|
||||||
# is there a $ROMNAME.cfg?
|
|
||||||
# exactly the same / just the name / default
|
|
||||||
# Random bezels have to match $ROMNAME./d+.cfg
|
|
||||||
romdir = f'{path}/systems/{bezel_system}/games'
|
|
||||||
full_name = os.path.splitext(rom_name)[0]
|
|
||||||
short_name = full_name.split(' (')[0]
|
|
||||||
if os.path.isdir(romdir):
|
|
||||||
with os.scandir(romdir) as it:
|
|
||||||
full_list = [entry.name for entry in it if entry.is_file() and entry.name.endswith('.cfg')]
|
|
||||||
for romname in (full_name, short_name , 'default'):
|
|
||||||
logger.log(f'Looking at: {romdir}/{romname}')
|
|
||||||
file_list = [file for file in full_list if re.fullmatch(fr'{re.escape(romname)}\.[0-9]+\.cfg', file)]
|
|
||||||
if len(file_list) > 0:
|
|
||||||
game_cfg = f'{romdir}/{random.choice(file_list)}'
|
|
||||||
logger.log(f'Using random config: {game_cfg}')
|
|
||||||
break
|
|
||||||
elif os.path.isfile(f'{romdir}/{romname}.cfg'):
|
|
||||||
game_cfg = f'{romdir}/{romname}.cfg'
|
|
||||||
logger.log(f'Using ROM config: {game_cfg}')
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
game_cfg = f'{path}/systems/{bezel_system}/games/{game_bezel_override}.cfg'
|
|
||||||
|
|
||||||
if os.path.isfile(game_cfg):
|
|
||||||
logger.log(f'game config file exists: {game_cfg}')
|
|
||||||
with open(game_cfg) as f:
|
|
||||||
contents = f.read().strip()
|
|
||||||
bezel_system_png = f'{path}/systems/{bezel_system}/games/{contents}'
|
|
||||||
logger.log(f'bezel png: {bezel_system_png}')
|
|
||||||
if os.path.isfile(bezel_system_png):
|
|
||||||
tmp_bezel_dict = {}
|
|
||||||
tmp_bezel_dict['overlays'] = '1'
|
|
||||||
tmp_bezel_dict['overlay0_full_screen'] = 'true'
|
|
||||||
tmp_bezel_dict['overlay0_normalized'] = 'true'
|
|
||||||
tmp_bezel_dict['overlay0_overlay'] = bezel_system_png
|
|
||||||
overlays_dir = f'{path}/systems/{bezel_system}/overlays/'
|
|
||||||
count = 0
|
|
||||||
if os.path.isdir(overlays_dir):
|
|
||||||
for overlay_png in iglob(f'{overlays_dir}/*.png'):
|
|
||||||
overlay_name = os.path.splitext(os.path.basename(overlay_png))[0]
|
|
||||||
overlay_setting = config.get_setting(f'bezel.overlay.{overlay_name}')
|
|
||||||
if not overlay_setting:
|
|
||||||
continue
|
|
||||||
logger.log(f'Adding overlay. name: {overlay_name} overlay setting: {overlay_setting}')
|
|
||||||
tmp_bezel_dict[f'overlay0_desc{count}_overlay'] = overlay_png
|
|
||||||
tmp_bezel_dict[f'overlay0_desc{count}'] = 'nul,0.5,0.5,rect,0.5,0.5'
|
|
||||||
count += 1
|
|
||||||
tmp_bezel_dict['overlay0_descs'] = count
|
|
||||||
if os.path.isfile(tmp_bezel):
|
|
||||||
os.remove(tmp_bezel)
|
|
||||||
write_file(tmp_bezel, tmp_bezel_dict)
|
|
||||||
bezel_cfg = tmp_bezel
|
|
||||||
|
|
||||||
if bezel_cfg is not None:
|
|
||||||
logger.log('using bezel')
|
|
||||||
# configure bezel
|
|
||||||
ra_append_dict['input_overlay_enable'] = 'true'
|
|
||||||
ra_append_dict['input_overlay'] = bezel_cfg
|
|
||||||
ra_append_dict['input_overlay_hide_in_menu'] = 'true'
|
|
||||||
ra_append_dict['input_overlay_opacity'] = '1.000000'
|
|
||||||
ra_append_dict['input_overlay_show_inputs'] = '2'
|
|
||||||
ra_append_dict['video_scale_integer'] = 'false'
|
|
||||||
ra_append_dict['aspect_ratio_index'] = '23'
|
|
||||||
# configure custom scaling
|
|
||||||
# needs some grouping to reflect the hack systems as well (i. e. gb=gb, gbh, gbc and gbch)
|
|
||||||
ra_append_dict['custom_viewport_x'] = system_viewport[platform][0]
|
|
||||||
ra_append_dict['custom_viewport_y'] = system_viewport[platform][1]
|
|
||||||
ra_append_dict['custom_viewport_width'] = system_viewport[platform][2]
|
|
||||||
ra_append_dict['custom_viewport_height'] = system_viewport[platform][3]
|
|
||||||
else:
|
|
||||||
logger.log('not using bezel')
|
|
||||||
# disable decorations
|
|
||||||
ra_append_dict['input_overlay_enable'] = 'false'
|
|
||||||
# set standard resolution for custom scaling
|
|
||||||
ra_append_dict['custom_viewport_x'] = system_viewport['standard'][0]
|
|
||||||
ra_append_dict['custom_viewport_y'] = system_viewport['standard'][1]
|
|
||||||
ra_append_dict['custom_viewport_width'] = system_viewport['standard'][2]
|
|
||||||
ra_append_dict['custom_viewport_height'] = system_viewport['standard'][3]
|
|
||||||
|
|
||||||
# DECK specific options TODO: integrate better in the code
|
|
||||||
# TODO: not working
|
|
||||||
#ra_append_dict['video_windowed_fullscreen'] = "true"
|
|
||||||
|
|
||||||
# Write the raappend.cfg
|
|
||||||
logger.log('Write raappend.cfg')
|
|
||||||
write_file(ra_append_conf, ra_append_dict)
|
|
||||||
|
|
||||||
logger.log('done ...')
|
|
||||||
return shader_path
|
|
||||||
|
|
||||||
# Main (if we are run as a script and not as a module)
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# Arguments
|
|
||||||
parser = ArgumentParser(description="Convert ES settings from distribution.conf to RetroArch configuration in raappend.conf.")
|
|
||||||
parser.add_argument("--core", help="core", required=True)
|
|
||||||
parser.add_argument("--platform", help="platform", required=True)
|
|
||||||
parser.add_argument("--rom", help="ROM file name", required=True)
|
|
||||||
parser.add_argument("--controllers", help="controller config", default="-p1index 0")
|
|
||||||
parser.add_argument("--autosave", help="autosave", default="0")
|
|
||||||
parser.add_argument("--snapshot", help="snapshot", default="")
|
|
||||||
args = parser.parse_args()
|
|
||||||
shader_path = set_settings(rom_name=args.rom, core=args.core, platform=args.platform, controllers=args.controllers, autosave=args.autosave, snapshot=args.snapshot)
|
|
||||||
if shader_path:
|
|
||||||
print(shader_path)
|
|
Loading…
Reference in a new issue