start rocknix

This commit is contained in:
brooksytech 2024-03-17 22:04:09 +00:00
parent ea44ab254d
commit f7b43f80e6
No known key found for this signature in database
75 changed files with 7344 additions and 90 deletions

2
.gitignore vendored
View file

@ -17,7 +17,7 @@
/target/
# options
.jelos
.rocknix
# private working directory
/.work/

View file

@ -22,7 +22,7 @@ DISTRO_DIR="${ROOT}/distributions"
PROJECT_DIR="${ROOT}/projects"
# determines DISTRO, if not forced by user
DISTRO="${DISTRO:-JELOS}"
DISTRO="${DISTRO:-ROCKNIX}"
# determines PROJECT, if not forced by user
PROJECT="${PROJECT:-PC}"

View file

@ -1,20 +0,0 @@
PKG_NAME="jelos-gamepad"
PKG_VERSION="b1fc0fb69047011d99b54029be500280d33a8027"
PKG_ARCH="aarch64"
PKG_LICENSE="GPLv3"
PKG_SITE="https://github.com/R-ARM/rinputer2"
PKG_URL="$PKG_SITE.git"
PKG_DEPENDS_TARGET="toolchain"
PKG_TOOLCHAIN="make"
GET_HANDLER_SUPPORT="git"
PKG_PATCH_DIRS+=" common"
makeinstall_target() {
mkdir -p $INSTALL/usr/bin
cp rinputer2 ${INSTALL}/usr/bin/jelos_gamepad
chmod 0755 ${INSTALL}/usr/bin/jelos_gamepad
}
post_install() {
enable_service jelos_gamepad.service
}

View file

@ -1,56 +0,0 @@
diff -rupN rinputer2.orig/main.c rinputer2/main.c
--- rinputer2.orig/main.c 2023-11-23 04:47:16.344733862 +0000
+++ rinputer2/main.c 2023-11-23 15:00:20.535535759 +0000
@@ -240,7 +240,7 @@ int rescan_devices(struct rinputer_devic
continue;
// let's not make a loop
- if(strncmp("Rinputer", name, 8) == 0)
+ if(strncmp("JELOS Gamepad", name, 8) == 0)
continue;
// ignore steam-created controllers
// they have this name, with a digit at the end
@@ -316,10 +316,10 @@ int main(void)
ioctl(outfd, UI_SET_EVBIT, EV_KEY);
- //ioctl(outfd, UI_SET_KEYBIT, BTN_DPAD_UP); // dpad up
- //ioctl(outfd, UI_SET_KEYBIT, BTN_DPAD_DOWN); // dpad down
- //ioctl(outfd, UI_SET_KEYBIT, BTN_DPAD_LEFT); // dpad left
- //ioctl(outfd, UI_SET_KEYBIT, BTN_DPAD_RIGHT); // dpad right
+ ioctl(outfd, UI_SET_KEYBIT, BTN_DPAD_UP); // dpad up
+ ioctl(outfd, UI_SET_KEYBIT, BTN_DPAD_DOWN); // dpad down
+ ioctl(outfd, UI_SET_KEYBIT, BTN_DPAD_LEFT); // dpad left
+ ioctl(outfd, UI_SET_KEYBIT, BTN_DPAD_RIGHT); // dpad right
ioctl(outfd, UI_SET_KEYBIT, BTN_NORTH); // x
ioctl(outfd, UI_SET_KEYBIT, BTN_SOUTH); // b
@@ -332,6 +332,9 @@ int main(void)
ioctl(outfd, UI_SET_KEYBIT, BTN_TR2); // L2
ioctl(outfd, UI_SET_KEYBIT, BTN_TL2); // R2
+ ioctl(outfd, UI_SET_KEYBIT, BTN_THUMBL); // L3
+ ioctl(outfd, UI_SET_KEYBIT, BTN_THUMBR); // R3
+
ioctl(outfd, UI_SET_KEYBIT, BTN_SELECT);
ioctl(outfd, UI_SET_KEYBIT, BTN_START);
@@ -350,15 +353,15 @@ int main(void)
setup_abs(outfd, ABS_RZ);
// dpad
- setup_abs(outfd, ABS_HAT0X);
- setup_abs(outfd, ABS_HAT0Y);
+ //setup_abs(outfd, ABS_HAT0X);
+ //setup_abs(outfd, ABS_HAT0Y);
// maybe we should pretend to be xbox gamepad?
memset(&usetup, 0, sizeof(usetup));
usetup.id.bustype = BUS_USB;
usetup.id.vendor = 0x1234;
usetup.id.product = 0x5678;
- strcpy(usetup.name, "Rinputer");
+ strcpy(usetup.name, "JELOS Gamepad");
ioctl(outfd, UI_DEV_SETUP, &usetup);
ioctl(outfd, UI_DEV_CREATE);

View file

@ -1,9 +0,0 @@
[Unit]
Description=Ragnarok Input Daemon
[Service]
Type=simple
ExecStart=/usr/bin/jelos_gamepad
[Install]
WantedBy=multi-user.target

View file

@ -1 +0,0 @@
SUBSYSTEM=="input", ATTRS{name}=="gpio-keys-control", ENV{ID_INPUT_JOYSTICK}=="?*", ENV{ID_INPUT_JOYSTICK}=""

View file

@ -0,0 +1,41 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
if [ -d "/storage/cache/.cores" ]
then
rm -rf /storage/cache/.cores
fi
if [ ! -d "/tmp/cache" ]
then
mkdir -p /tmp/cache
fi
ln -sf /tmp/cache /storage/cache/.cores
if [ ! -d "/storage/.config/profile.d" ]
then
mkdir -p /storage/.config/profile.d
fi
### Inspect the system config and revert
### to last known good state if corrupt.
/usr/bin/chksysconfig verify
### Clean up settings
sort_settings
### We do not want to mount the cloud drive on startup
### so we'll reset the mount option to 0.
set_setting clouddrive.mounted 0
### Set up the runtime directory.
if [ ! -d "/var/run/0-runtime-dir" ]
then
mkdir -p /var/run/0-runtime-dir
fi
chmod 0700 /var/run/0-runtime-dir

View file

@ -0,0 +1,14 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
tocon "Applying kernel parameters..."
sysctl vm.swappiness=1
sysctl kernel.nmi_watchdog=0
sysctl vm.laptop_mode=5
sysctl vm.dirty_writeback_centisecs=1500
toggle-ipv6

View file

@ -0,0 +1,18 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
if [ "$(cat /storage/.boot.hint 2>/dev/null)" = "UPDATE" ]
then
if [ -e "/usr/share/post-update" ]
then
tocon "Performing post-update configuration..."
/usr/share/post-update >/var/log/upgrade.log 2>&1
fi
rm /storage/.boot.hint
else
echo "No update hint found." >/var/log/upgrade.log 2>&1
fi

View file

@ -0,0 +1,36 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
tocon "Configuring display..."
### Variables may need to be device specific here.
BRIGHTNESS=$(get_setting system.brightness)
if [[ -z ${BRIGHTNESS} ]]
then
BRIGHTNESS="6"
fi
# Ensure user doesn't get "locked out" with super low brightness
if [[ "${BRIGHTNESS}" = "0" ]]
then
BRIGHTNESS=1
fi
brightness set ${BRIGHTNESS}
### Set the aspect ratio in ES.
ASPECT=$(get_aspect_ratio)
ES_CONFIG="/storage/.config/emulationstation/es_settings.cfg"
ES_ASPECT="${ASPECT/:/-}"
if [ "$(grep subset.aspect-ratio ${ES_CONFIG})" ]
then
sed -i 's|<string name="subset.aspect-ratio".*$|<string name="subset.aspect-ratio" value="'${ES_ASPECT}'"/>|g' ${ES_CONFIG}
else
sed -i '/<\/config>/i \\t<string name="subset.aspect-ratio" value="'${ES_ASPECT}'"/>' ${ES_CONFIG}
fi

View file

@ -0,0 +1,27 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
tocon "Setting root password..."
if [ ! -d "/storage/.cache/samba" ]
then
mkdir -p /storage/.cache/samba
touch /storage/.cache/samba/smbpasswd
fi
ROTATION=$(get_setting rotate.root.password)
if [ "${ROTATION}" == "0" ]
then
ROOTPASS=$(get_setting root.password)
setrootpass "${ROOTPASS}"
exit 0
fi
# Randomly generate the root password on startup
ROOTPASS=$(openssl rand -base64 10 2>/dev/null | sed "s#==##g")
/usr/bin/setrootpass "${ROOTPASS}"

View file

@ -0,0 +1,41 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
. /etc/profile.d/030-powerfunctions
. /etc/profile.d/099-freqfunctions
tocon "Setting performance mode..."
### Enable the desired number of threads.
tocon "Restoring cpu threads..."
NUMTHREADS=$(get_setting "system.threads")
if [ -n "${NUMTHREADS}" ]
then
onlinethreads ${NUMTHREADS} 0
else
onlinethreads all 1
fi
### If we don't have a default governor set, set it
### to schedutil if the device supports it, otherwise
### set to performance, but don't enable it.
if [ -z "$(get_setting system.cpugovernor)" ]
then
GOVTEST="$(awk '/schedutil/ {print $1}' /sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors)"
if [ -n "${GOVTEST}" ]
then
set_setting system.cpugovernor schedutil
else
set_setting system.cpugovernor performance
fi
fi
### Set the default GPU performance mode
GPUPERF=$(get_setting system.gpuperf)
if [ -n "${GPUPERF}" ]
then
gpu_performance_level ${GPUPERF}
fi

View file

@ -0,0 +1,17 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
tocon "Configure suspend mode..."
### Configure suspend mode.
MYSLEEPMODE=$(get_setting system.suspendmode)
if [ -n "${MYSLEEPMODE}" ]
then
/usr/bin/suspendmode ${MYSLEEPMODE}
else
/usr/bin/suspendmode mem
fi

View file

@ -0,0 +1,26 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
tocon "Configuring user interface..."
UIMODE=$(get_setting desktop.enabled)
if [ "${UIMODE}" = "1" ] || \
[ ! -e "/usr/bin/emulationstation" ]
then
cp -f /usr/share/weston/weston.ini /storage/.config/weston.ini
else
cp -f /usr/share/weston/kiosk.ini /storage/.config/weston.ini
fi
STARTUP=$(get_setting weston.startup)
if [ -z "${STARTUP}" ] && \
[ -e "/usr/bin/emulationstation" ]
then
STARTUP="/usr/bin/start_es.sh"
set_setting weston.startup "${STARTUP}"
fi
sed -i "s#@STARTUP@#${STARTUP}#g" /storage/.config/weston.ini

View file

@ -0,0 +1,46 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
tocon "Configuring Audio..."
STATE=$(systemctl isactive pipewire-pulse)
if [ "${STATE}" = "inactive" ]
then
systemctl start pipewire-pulse
fi
### Auto switch between internal and bluetooth devices
pactl load-module module-switch-on-connect 2>/dev/null
### Set up audio routing (Internal or HDMI)
/usr/bin/hdmi_sense 2>/dev/null
### Set the default audio path, needed for some devices
if [ ! -z "${DEVICE_PLAYBACK_PATH_SPK}" ]
then
if [ -z "${DEVICE_PLAYBACK_PATH}" ]
then
export DEVICE_PLAYBACK_PATH="Playback Path"
fi
amixer -c 0 cset name="${DEVICE_PLAYBACK_PATH}" ${DEVICE_PLAYBACK_PATH_SPK} 2>/dev/null
fi
VOLUME=$(get_setting audio.volume)
if [ -z ${VOLUME} ]
then
VOLUME="60"
elif [ -n "${DEVICE_VOLUME}" ]
then
VOLUME="${DEVICE_VOLUME}"
fi
### Set the primary card volume to 100%
### to eliminate low audio on some devices.
amixer -c 0 -q sset "Master" 100%
### Now set the pipewire mixer volume
/usr/bin/volume ${VOLUME}

View file

@ -0,0 +1,29 @@
#!/bin/bash
# SPDX-License-Identifier: MIT
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Copyright (C) 2023-present christianhaitian (https://github.com/christianhaitian)
# Copyright (C) 2023-present Rocky5 (https://github.com/rocky5)
# The purpose of this script is to permanently set the resolution
# output for hdmi when connected.
xres="$(cat /sys/class/graphics/fb0/modes | grep -o -P '(?<=:).*(?=p-)' | cut -dx -f1)"
# drm_tool source available at https://github.com/christianhaitian/drm_tool.git
mode="$(/usr/bin/drm_tool list | awk '/1280x720.*60/ {print substr($2,1,length($2)-1); exit}')"
mode2="$(/usr/bin/drm_tool list | awk '/1920x1080.*60/ {print substr($2,1,length($2)-1); exit}')"
# Now we tell drm what the hdmi mode is by writing to /var/run/drmMode
# This will get picked up by SDL2 as long as it's been patched with the batocera
# drm resolution patch. This patch can be found at
# https://github.com/christianhaitian/rk3566_core_builds/raw/master/patches/sdl2-patch-0003-drm-resolution.patch
if [ $xres -eq "1280" ]; then
echo $mode | tee /var/run/drmMode
elif [ $xres -eq "1920" ]; then
echo $mode2 | tee /var/run/drmConn
else
echo 0 | tee /var/run/drmMode
echo 1 | tee /var/run/drmConn
fi

View file

@ -0,0 +1,17 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
tocon "Configuring network..."
if [ "$(get_setting network.enabled)" == "0" ] || [ "$1" == "disable" ]
then
nohup wifictl disable &
elif [ "$(get_setting network.enabled)" == "1" ] || [ "$1" == "enable" ]
then
nohup wifictl enable &
fi

View file

@ -0,0 +1,10 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
if [ -r /storage/.cache/usbgadget/usbgadget.conf ] ; then
USB_MODE=$(cat /storage/.cache/usbgadget/usbgadget.conf | cut -d "=" -f2)
if [ "${USB_MODE}" = cdc ] || [ "${USB_MODE}" = mtp ]; then
/usr/bin/usbgadget start $USB_MODE
fi
fi

View file

@ -0,0 +1,42 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Minimal OS variable loading for performance
. /etc/profile.d/001-functions
tocon "Starting services..."
for SERVICE in /usr/lib/autostart/daemons/*
do
source ${SERVICE}
if [ ! -d "/storage/.cache/services" ]
then
mkdir -p "/storage/.cache/services"
fi
if [ -n "${CONF}" ] && \
[ -e "/storage/.cache/services/${CONF}" ]
then
rm -f "/storage/.cache/services/${CONF}"
fi
statemgr() {
for daemon in ${DAEMONS[@]}
do
nohup systemctl ${1} ${daemon} &
done
}
case "$STATE" in
"1")
touch "/storage/.cache/services/${CONF}"
statemgr start
;;
*)
statemgr stop
;;
esac
done

View file

@ -0,0 +1,219 @@
3do.integerscale=0
3do.ratio=4/3
advmame_auto_gamepad=0
amigacd32.integerscale=0
amigacd32.ratio=4/3
amiga.integerscale=0
amiga.ratio=4/3
amstradcpc.integerscale=0
arcade.autosave=0
atari2600.integerscale=0
atari5200.integerscale=0
atari7800.integerscale=0
atari800.integerscale=0
atarilynx.integerscale=0
atarilynx.ratio=core
atarist.integerscale=0
atomiswave.integerscale=0
atomiswave.ratio=4/3
audio.bgmusic=1
audio.device=headphone
audio.display_titles=1
audio.persystem=0
audio.preamp=50
audio.volume=60
bluetooth.enabled=0
boot=Emulationstation
c128.integerscale=0
c16.integerscale=0
c64.integerscale=0
cdi.integerscale=0
cdi.ratio=4/3
chip-8.integerscale=0
cloud.backup=0
colecovision.integerscale=0
colecovision.ratio=4/3
cooling.profile=quiet
cps1.integerscale=0
cps2.integerscale=0
cps3.integerscale=0
daphne.integerscale=0
daphne.ratio=4/3
desktop.enabled=0
display.brightness=50
display.contrast=50
display.hue=50
display.saturation=50
dreamcast.integerscale=0
dreamcast.ratio=4/3
easyrpg.integerscale=0
famicom.integerscale=0
famicom.ratio=4/3
fbn.integerscale=0
fbn.ratio=core
fds.integerscale=0
fds.ratio=4/3
fstrim.enabled=0
gamegear.integerscale=0
gbah.ratio=3/2
gba.ratio=3/2
gbch.integerscale=0
gbc.integerscale=0
gbh.integerscale=0
gb.integerscale=0
genesis.integerscale=0
genesis.ratio=4/3
genh.integerscale=0
genh.ratio=4/3
ggh.integerscale=0
global.analogue=1
global.audiolatency=32
global.autosave=2
global.incrementalsavestates=0
global.maxincrementalsaves=0
global.netplay=0
global.netplay.port=55435
global.netplay.relay=none
global.ratio=core
global.retroachievements=0
global.retroachievements.challengeindicators=0
global.retroachievements.hardcore=0
global.retroachievements.leaderboards=disabled
global.retroachievements.password=
global.retroachievements.richpresence=0
global.retroachievements.screenshot=0
global.retroachievements.soundenable=0
global.retroachievements.testunofficial=0
global.retroachievements.username=
global.retroachievements.verbose=0
global.retroarch.menu_driver=ozone
global.rewind=0
global.runahead=0
global.secondinstance=0
intellivision.integerscale=0
intellivision.ratio=4/3
ipv6.enabled=0
mame.autosave=0
mame.integerscale=0
mastersystem.integerscale=0
megacd.integerscale=0
megacd.ratio=4/3
megadrive.integerscale=0
megadrive-japan.integerscale=0
megadrive-japan.ratio=4/3
megadrive.ratio=4/3
megaduck.integerscale=0
moto.integerscale=0
moto.ratio=4/3
msx2.integerscale=0
msx2.ratio=4/3
msx.integerscale=0
msx.ratio=4/3
n64.controller_pak=2
n64.game_aspect_ratio=4:3
n64.input_configuration=zlswap
n64.integerscale=0
n64.internal_resolution=1
n64.parallel_n64_gamespeed=fullspeed
n64.parallel_n64_gfx_accuracy=medium
n64.parallel_n64_internal_resolution=480p
n64.parallel_n64_video_core=glide64
n64.ratio=4/3
n64.rsp_plugin=hle
n64.show_fps=0
naomi.integerscale=0
naomi.ratio=4/3
neocd.integerscale=0
neocd.ratio=core
neogeo.integerscale=0
neogeo.ratio=core
nesh.integerscale=0
nesh.ratio=4/3
nes.integerscale=0
nes.ratio=4/3
network.enabled=0
ngpc.intergerscale=1
ngp.integerscale=0
odyssey2.integerscale=0
odyssey2.ratio=4/3
pc-9800.integerscale=0
pc-9800.ratio=4/3
pcenginecd.integerscale=0
pcenginecd.ratio=4/3
pcengine.integerscale=0
pcengine.ratio=4/3
pcfx.integerscale=0
pcfx.ratio=4/3
pc.integerscale=0
pc.ratio=4/3
pet.ratio=4/3
pokemini.ratio=3/2
psx.integerscale=0
psx.ratio=4/3
rotate.root.password=1
samba.enabled=0
saturn.integerscale=0
saturn.ratio=4/3
scv.integerscale=0
scv.ratio=4/3
sega32x.integerscale=0
sega32x.ratio=4/3
segacd.integerscale=0
segacd.ratio=4/3
sfc.integerscale=0
sfc.ratio=4/3
sg-1000.integerscale=0
simplehttp.enabled=0
snesh.integerscale=0
snesh.ratio=4/3
snes.integerscale=0
snesmsu1.integerscale=0
snesmsu1.ratio=4/3
snes.ratio=4/3
splash.enabled=0
ssh.enabled=0
supergrafx.integerscale=0
supergrafx.ratio=4/3
supervision.integerscale=0
syncthing.enabled=0
system.autohotkeys=1
system.automount=1
system.battery.warning=0
system.hostname=@DEVICENAME@
system.language=en_US
system.loglevel=none
system.power.audio=1
system.merged.storage=0
system.power.cpu=1
system.power.pcie=0
system.power.rtpm=0
system.powersave=0
system.power.wifi=0
system.timezone=America/New_York
tg16cd.integerscale=0
tg16cd.ratio=4/3
tg16.integerscale=0
tg16.ratio=4/3
updates.branch=stable
updates.enabled=1
updates.force=0
uzebox.integerscale=0
uzebox.integerscale=0
vectrex.integerscale=0
vectrex.ratio=3/4
vic20.integerscale=0
vic20.ratio=4/3
videopac.integerscale=0
videopac.ratio=4/3
vircon32.integerscale=0
virtualboy.integerscale=0
weston.startup=/usr/bin/start_es.sh
wonderswancolor.integerscale=0
wonderswan.integerscale=0
wts.enabled=1
x68000.integerscale=0
x68000.ratio=4/3
zx81.integerscale=0
zx81.ratio=4/3
zxspectrum.integerscale=0
zxspectrum.ratio=4/3

View file

@ -0,0 +1,593 @@
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
Africa/Brazzaville
Africa/Bujumbura
Africa/Cairo
Africa/Casablanca
Africa/Ceuta
Africa/Conakry
Africa/Dakar
Africa/Dar_es_Salaam
Africa/Djibouti
Africa/Douala
Africa/El_Aaiun
Africa/Freetown
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Juba
Africa/Kampala
Africa/Khartoum
Africa/Kigali
Africa/Kinshasa
Africa/Lagos
Africa/Libreville
Africa/Lome
Africa/Luanda
Africa/Lubumbashi
Africa/Lusaka
Africa/Malabo
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Mogadishu
Africa/Monrovia
Africa/Nairobi
Africa/Ndjamena
Africa/Niamey
Africa/Nouakchott
Africa/Ouagadougou
Africa/Porto-Novo
Africa/Sao_Tome
Africa/Timbuktu
Africa/Tripoli
Africa/Tunis
Africa/Windhoek
America/Adak
America/Anchorage
America/Anguilla
America/Antigua
America/Araguaina
America/Argentina/Buenos_Aires
America/Argentina/Catamarca
America/Argentina/ComodRivadavia
America/Argentina/Cordoba
America/Argentina/Jujuy
America/Argentina/La_Rioja
America/Argentina/Mendoza
America/Argentina/Rio_Gallegos
America/Argentina/Salta
America/Argentina/San_Juan
America/Argentina/San_Luis
America/Argentina/Tucuman
America/Argentina/Ushuaia
America/Aruba
America/Asuncion
America/Atikokan
America/Atka
America/Bahia
America/Bahia_Banderas
America/Barbados
America/Belem
America/Belize
America/Blanc-Sablon
America/Boa_Vista
America/Bogota
America/Boise
America/Buenos_Aires
America/Cambridge_Bay
America/Campo_Grande
America/Cancun
America/Caracas
America/Catamarca
America/Cayenne
America/Cayman
America/Chicago
America/Chihuahua
America/Coral_Harbour
America/Cordoba
America/Costa_Rica
America/Creston
America/Cuiaba
America/Curacao
America/Danmarkshavn
America/Dawson
America/Dawson_Creek
America/Denver
America/Detroit
America/Dominica
America/Edmonton
America/Eirunepe
America/El_Salvador
America/Ensenada
America/Fort_Nelson
America/Fort_Wayne
America/Fortaleza
America/Glace_Bay
America/Godthab
America/Goose_Bay
America/Grand_Turk
America/Grenada
America/Guadeloupe
America/Guatemala
America/Guayaquil
America/Guyana
America/Halifax
America/Havana
America/Hermosillo
America/Indiana/Indianapolis
America/Indiana/Knox
America/Indiana/Marengo
America/Indiana/Petersburg
America/Indiana/Tell_City
America/Indiana/Vevay
America/Indiana/Vincennes
America/Indiana/Winamac
America/Indianapolis
America/Inuvik
America/Iqaluit
America/Jamaica
America/Jujuy
America/Juneau
America/Kentucky/Louisville
America/Kentucky/Monticello
America/Knox_IN
America/Kralendijk
America/La_Paz
America/Lima
America/Los_Angeles
America/Louisville
America/Lower_Princes
America/Maceio
America/Managua
America/Manaus
America/Marigot
America/Martinique
America/Matamoros
America/Mazatlan
America/Mendoza
America/Menominee
America/Merida
America/Metlakatla
America/Mexico_City
America/Miquelon
America/Moncton
America/Monterrey
America/Montevideo
America/Montreal
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
America/North_Dakota/Beulah
America/North_Dakota/Center
America/North_Dakota/New_Salem
America/Ojinaga
America/Panama
America/Pangnirtung
America/Paramaribo
America/Phoenix
America/Port-au-Prince
America/Port_of_Spain
America/Porto_Acre
America/Porto_Velho
America/Puerto_Rico
America/Punta_Arenas
America/Rainy_River
America/Rankin_Inlet
America/Recife
America/Regina
America/Resolute
America/Rio_Branco
America/Rosario
America/Santa_Isabel
America/Santarem
America/Santiago
America/Santo_Domingo
America/Sao_Paulo
America/Scoresbysund
America/Shiprock
America/Sitka
America/St_Barthelemy
America/St_Johns
America/St_Kitts
America/St_Lucia
America/St_Thomas
America/St_Vincent
America/Swift_Current
America/Tegucigalpa
America/Thule
America/Thunder_Bay
America/Tijuana
America/Toronto
America/Tortola
America/Vancouver
America/Virgin
America/Whitehorse
America/Winnipeg
America/Yakutat
America/Yellowknife
Antarctica/Casey
Antarctica/Davis
Antarctica/DumontDUrville
Antarctica/Macquarie
Antarctica/Mawson
Antarctica/McMurdo
Antarctica/Palmer
Antarctica/Rothera
Antarctica/South_Pole
Antarctica/Syowa
Antarctica/Troll
Antarctica/Vostok
Arctic/Longyearbyen
Asia/Aden
Asia/Almaty
Asia/Amman
Asia/Anadyr
Asia/Aqtau
Asia/Aqtobe
Asia/Ashgabat
Asia/Ashkhabad
Asia/Atyrau
Asia/Baghdad
Asia/Bahrain
Asia/Baku
Asia/Bangkok
Asia/Barnaul
Asia/Beirut
Asia/Bishkek
Asia/Brunei
Asia/Calcutta
Asia/Chita
Asia/Choibalsan
Asia/Chongqing
Asia/Chungking
Asia/Colombo
Asia/Dacca
Asia/Damascus
Asia/Dhaka
Asia/Dili
Asia/Dubai
Asia/Dushanbe
Asia/Famagusta
Asia/Gaza
Asia/Harbin
Asia/Hebron
Asia/Ho_Chi_Minh
Asia/Hong_Kong
Asia/Hovd
Asia/Irkutsk
Asia/Istanbul
Asia/Jakarta
Asia/Jayapura
Asia/Jerusalem
Asia/Kabul
Asia/Kamchatka
Asia/Karachi
Asia/Kashgar
Asia/Kathmandu
Asia/Katmandu
Asia/Khandyga
Asia/Kolkata
Asia/Krasnoyarsk
Asia/Kuala_Lumpur
Asia/Kuching
Asia/Kuwait
Asia/Macao
Asia/Macau
Asia/Magadan
Asia/Makassar
Asia/Manila
Asia/Muscat
Asia/Nicosia
Asia/Novokuznetsk
Asia/Novosibirsk
Asia/Omsk
Asia/Oral
Asia/Phnom_Penh
Asia/Pontianak
Asia/Pyongyang
Asia/Qatar
Asia/Qostanay
Asia/Qyzylorda
Asia/Rangoon
Asia/Riyadh
Asia/Saigon
Asia/Sakhalin
Asia/Samarkand
Asia/Seoul
Asia/Shanghai
Asia/Singapore
Asia/Srednekolymsk
Asia/Taipei
Asia/Tashkent
Asia/Tbilisi
Asia/Tehran
Asia/Tel_Aviv
Asia/Thimbu
Asia/Thimphu
Asia/Tokyo
Asia/Tomsk
Asia/Ujung_Pandang
Asia/Ulaanbaatar
Asia/Ulan_Bator
Asia/Urumqi
Asia/Ust-Nera
Asia/Vientiane
Asia/Vladivostok
Asia/Yakutsk
Asia/Yangon
Asia/Yekaterinburg
Asia/Yerevan
Atlantic/Azores
Atlantic/Bermuda
Atlantic/Canary
Atlantic/Cape_Verde
Atlantic/Faeroe
Atlantic/Faroe
Atlantic/Jan_Mayen
Atlantic/Madeira
Atlantic/Reykjavik
Atlantic/South_Georgia
Atlantic/St_Helena
Atlantic/Stanley
Australia/ACT
Australia/Adelaide
Australia/Brisbane
Australia/Broken_Hill
Australia/Canberra
Australia/Currie
Australia/Darwin
Australia/Eucla
Australia/Hobart
Australia/LHI
Australia/Lindeman
Australia/Lord_Howe
Australia/Melbourne
Australia/NSW
Australia/North
Australia/Perth
Australia/Queensland
Australia/South
Australia/Sydney
Australia/Tasmania
Australia/Victoria
Australia/West
Australia/Yancowinna
Brazil/Acre
Brazil/DeNoronha
Brazil/East
Brazil/West
CET
CST6CDT
Canada/Atlantic
Canada/Central
Canada/Eastern
Canada/Mountain
Canada/Newfoundland
Canada/Pacific
Canada/Saskatchewan
Canada/Yukon
Chile/Continental
Chile/EasterIsland
Cuba
EET
EST
EST5EDT
Egypt
Eire
Etc/GMT
Etc/GMT+0
Etc/GMT+1
Etc/GMT+10
Etc/GMT+11
Etc/GMT+12
Etc/GMT+2
Etc/GMT+3
Etc/GMT+4
Etc/GMT+5
Etc/GMT+6
Etc/GMT+7
Etc/GMT+8
Etc/GMT+9
Etc/GMT-0
Etc/GMT-1
Etc/GMT-10
Etc/GMT-11
Etc/GMT-12
Etc/GMT-13
Etc/GMT-14
Etc/GMT-2
Etc/GMT-3
Etc/GMT-4
Etc/GMT-5
Etc/GMT-6
Etc/GMT-7
Etc/GMT-8
Etc/GMT-9
Etc/GMT0
Etc/Greenwich
Etc/UCT
Etc/UTC
Etc/Universal
Etc/Zulu
Europe/Amsterdam
Europe/Andorra
Europe/Astrakhan
Europe/Athens
Europe/Belfast
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
Europe/Bucharest
Europe/Budapest
Europe/Busingen
Europe/Chisinau
Europe/Copenhagen
Europe/Dublin
Europe/Gibraltar
Europe/Guernsey
Europe/Helsinki
Europe/Isle_of_Man
Europe/Istanbul
Europe/Jersey
Europe/Kaliningrad
Europe/Kiev
Europe/Kirov
Europe/Lisbon
Europe/Ljubljana
Europe/London
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Mariehamn
Europe/Minsk
Europe/Monaco
Europe/Moscow
Europe/Nicosia
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
Europe/Rome
Europe/Samara
Europe/San_Marino
Europe/Sarajevo
Europe/Saratov
Europe/Simferopol
Europe/Skopje
Europe/Sofia
Europe/Stockholm
Europe/Tallinn
Europe/Tirane
Europe/Tiraspol
Europe/Ulyanovsk
Europe/Uzhgorod
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Vilnius
Europe/Volgograd
Europe/Warsaw
Europe/Zagreb
Europe/Zaporozhye
Europe/Zurich
GB
GB-Eire
GMT
GMT+0
GMT-0
GMT0
Greenwich
HST
Hongkong
Iceland
Indian/Antananarivo
Indian/Chagos
Indian/Christmas
Indian/Cocos
Indian/Comoro
Indian/Kerguelen
Indian/Mahe
Indian/Maldives
Indian/Mauritius
Indian/Mayotte
Indian/Reunion
Iran
Israel
Jamaica
Japan
Kwajalein
Libya
MET
MST
MST7MDT
Mexico/BajaNorte
Mexico/BajaSur
Mexico/General
NZ
NZ-CHAT
Navajo
PRC
PST8PDT
Pacific/Apia
Pacific/Auckland
Pacific/Bougainville
Pacific/Chatham
Pacific/Chuuk
Pacific/Easter
Pacific/Efate
Pacific/Enderbury
Pacific/Fakaofo
Pacific/Fiji
Pacific/Funafuti
Pacific/Galapagos
Pacific/Gambier
Pacific/Guadalcanal
Pacific/Guam
Pacific/Honolulu
Pacific/Johnston
Pacific/Kiritimati
Pacific/Kosrae
Pacific/Kwajalein
Pacific/Majuro
Pacific/Marquesas
Pacific/Midway
Pacific/Nauru
Pacific/Niue
Pacific/Norfolk
Pacific/Noumea
Pacific/Pago_Pago
Pacific/Palau
Pacific/Pitcairn
Pacific/Pohnpei
Pacific/Ponape
Pacific/Port_Moresby
Pacific/Rarotonga
Pacific/Saipan
Pacific/Samoa
Pacific/Tahiti
Pacific/Tarawa
Pacific/Tongatapu
Pacific/Truk
Pacific/Wake
Pacific/Wallis
Pacific/Yap
Poland
Portugal
ROC
ROK
Singapore
Turkey
UCT
US/Alaska
US/Aleutian
US/Arizona
US/Central
US/East-Indiana
US/Eastern
US/Hawaii
US/Indiana-Starke
US/Michigan
US/Mountain
US/Pacific
US/Pacific-New
US/Samoa
UTC
Universal
W-SU
WET
Zulu

View file

@ -0,0 +1,96 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
PKG_NAME="jelos"
PKG_VERSION=""
PKG_ARCH="any"
PKG_LICENSE="GPLv2"
PKG_SITE=""
PKG_URL=""
PKG_DEPENDS_TARGET="toolchain"
PKG_SHORTDESC="JELOS Meta Package"
PKG_LONGDESC="JELOS Meta Package"
PKG_IS_ADDON="no"
PKG_AUTORECONF="no"
PKG_TOOLCHAIN="make"
make_target() {
:
}
makeinstall_target() {
mkdir -p ${INSTALL}/usr/config/
rsync -av ${PKG_DIR}/config/* ${INSTALL}/usr/config/
ln -sf /storage/.config/system ${INSTALL}/system
find ${INSTALL}/usr/config/system/ -type f -exec chmod o+x {} \;
mkdir -p ${INSTALL}/usr/bin/
### Compatibility links for ports
ln -s /storage/roms ${INSTALL}/roms
### Add some quality of life customizations for hardworking devs.
if [ -n "${LOCAL_SSH_KEYS_FILE}" ]
then
mkdir -p ${INSTALL}/usr/config/ssh
cp ${LOCAL_SSH_KEYS_FILE} ${INSTALL}/usr/config/ssh/authorized_keys
fi
if [ -n "${LOCAL_WIFI_SSID}" ]
then
sed -i "s#network.enabled=0#network.enabled=1#g" ${INSTALL}/usr/config/system/configs/system.cfg
cat <<EOF >> ${INSTALL}/usr/config/system/configs/system.cfg
wifi.ssid=${LOCAL_WIFI_SSID}
wifi.key=${LOCAL_WIFI_KEY}
EOF
fi
}
post_install() {
ln -sf jelos.target ${INSTALL}/usr/lib/systemd/system/default.target
if [ ! -d "${INSTALL}/usr/share" ]
then
mkdir "${INSTALL}/usr/share"
fi
cp ${PKG_DIR}/sources/post-update ${INSTALL}/usr/share
chmod 755 ${INSTALL}/usr/share/post-update
# Issue banner
BUILD_ID=$(git rev-parse HEAD)
cp ${PKG_DIR}/sources/issue ${INSTALL}/etc
ln -s /etc/issue ${INSTALL}/etc/motd
cat <<EOF >> ${INSTALL}/etc/issue
... Version: ${OS_VERSION} (${BUILD_ID:0:7})
... Built: ${BUILD_DATE}
EOF
cp ${PKG_DIR}/sources/scripts/* ${INSTALL}/usr/bin
chmod 0755 ${INSTALL}/usr/bin/* 2>/dev/null ||:
### Fix and migrate to autostart package
enable_service jelos-autostart.service
### Take a backup of the system configuration on shutdown
enable_service save-sysconfig.service
sed -i "s#@DEVICENAME@#${DEVICE}#g" ${INSTALL}/usr/config/system/configs/system.cfg
### Defaults for non-main builds.
BUILD_BRANCH="$(git branch --show-current)"
if [ ! "${BUILD_BRANCH}" = "main" ]
then
sed -i "s#ssh.enabled=0#ssh.enabled=1#g" ${INSTALL}/usr/config/system/configs/system.cfg
sed -i "s#network.enabled=0#network.enabled=1#g" ${INSTALL}/usr/config/system/configs/system.cfg
sed -i "s#system.loglevel=none#system.loglevel=verbose#g" ${INSTALL}/usr/config/system/configs/system.cfg
fi
### Disable automount on AMD64
if [ "${DEVICE}" = "AMD64" ]
then
sed -i "s#system.automount=1#system.automount=0#g" ${INSTALL}/usr/config/system/configs/system.cfg
fi
}

View file

@ -0,0 +1,206 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert)
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/os-release
export XDG_RUNTIME_DIR=/var/run/0-runtime-dir
export PATH="/usr/bin:/usr/local/bin:/storage/bin:${PATH}"
export SDL_GAMECONTROLLERCONFIG_FILE="/storage/.config/SDL-GameControllerDB/gamecontrollerdb.txt"
J_DIR="/storage/.config/system"
J_CONF="${J_DIR}/configs/system.cfg"
J_CONF_LOCK="/tmp/.system.cfg.lock"
ES_CONF="/storage/.emulationstation/es_settings.cfg"
function tocon() {
echo -ne "\033[1000H\033[2K==> ${*}" >/dev/console
}
function log() {
SOURCE=${1//\/*\//}
MESSAGE=${*#${1}}
MESSAGE=${MESSAGE# }
logger -t ${SOURCE} "${MESSAGE}"
echo "$(date) ${SOURCE}: ${MESSAGE}" >>/var/log/messages
}
function get_setting() {
if [ -n "${3}" ]
then
### Test to see if we have a game setting.
VAR="$2\[\"$(echo ${3} | sed -E "s~'~\\\x27~g"';s~[()&]~\\&~g')\"\]\.$1"
OUTPUT=$(awk 'BEGIN {FS="="} /^'"${VAR}"'/ {print $NF}' ${J_CONF})
if [ ! -z "${OUTPUT}" ]
then
echo ${OUTPUT}
return
else
### If not, check to see if we have a system setting.
LOCAL=$(awk -F: '/^'"${2}.${1}"'=/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF})
if [ ! -z "${LOCAL}" ]
then
echo ${LOCAL}
return
fi
fi
fi
if [ -z "${3}" ] && [ -n "${2}" ]
then
### Check to see if we have a global setting.
LOCAL=$(awk -F: '/^'"${2}.${1}"'=/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF})
if [ ! -z "${LOCAL}" ]
then
echo ${LOCAL}
return
fi
fi
### Check to see if we have a "system." global setting.
SYSTEM=$(awk -F: '/^system.'"${1}"='/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF})
if [ -n "${SYSTEM}" ]
then
echo ${SYSTEM}
return
fi
### Check to see if we have a "global." global setting."
LOCAL=$(awk -F: '/^'"${1}"='/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF})
if [ -z "${LOCAL}" ]
then
awk -F: '/^global.'"${1}"='/ { st = index($0,"=");print substr($0,st+1);exit}' ${J_CONF}
return
else
echo ${LOCAL}
fi
return
}
function wait_lock() {
while true
do
if (set -o noclobber; echo "$$" > "${J_CONF_LOCK}") 2>/dev/null
then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
break
else
sleep 1
fi
done
}
function del_setting() {
wait_lock
if [[ "${1}" =~ ^[[:alnum:]] ]]
then
sed -i "/^${1}=/d" "${J_CONF}"
fi
rm -f "${J_CONF_LOCK}"
}
function sort_settings() {
wait_lock
cat "${J_CONF}" | grep ^[a-z0-9] | sort >"${J_CONF}.tmp"
mv "${J_CONF}.tmp" "${J_CONF}"
rm -f "${J_CONF_LOCK}"
}
function set_kill() {
if [ "${1}" = "set" ]
then
cat <<EOF >/tmp/.process-kill-data
${2}
EOF
elif [ "${1}" = "stop" ]
then
if [ -e "/tmp/.process-kill-data" ]
then
rm -f "/tmp/.process-kill-data"
fi
fi
}
function set_setting() {
if [ ! -d "/storage/.config/system/configs" ]
then
mkdir -p /storage/.config/system/configs
fi
if [ ! -e "/storage/.config/system/configs/system.cfg" ]
then
cp -f /usr/config/system/configs/system.cfg /storage/.config/system/configs/system.cfg
fi
if [[ "${1}" =~ ^[[:alnum:]] ]]
then
del_setting "${1}"
if [ ! "${2}" = "default" ]
then
wait_lock
echo "${1}=${2}" >> "${J_CONF}"
rm -f "${J_CONF_LOCK}"
fi
fi
}
function battery_percent() {
awk 'BEGIN {FS="="} /POWER_SUPPLY_CAPACITY=/ {print $2}' /sys/class/power_supply/[Bb][Aa][Tt]*/uevent 2>/dev/null
}
function get_es_setting() {
echo $(sed -n "s|\s*<${1} name=\"${2}\" value=\"\(.*\)\" />|\1|p" ${ES_CONF})
}
function fbwidth() {
local ORIENTATION=$(</sys/devices/virtual/graphics/fbcon/rotate)
if [ "${ORIENTATION}" = "0" ]
then
fbset | awk '/geometry/ {print $2}'
else
fbset | awk '/geometry/ {print $3}'
fi
}
function fbheight() {
local ORIENTATION=$(</sys/devices/virtual/graphics/fbcon/rotate)
if [ "${ORIENTATION}" = "0" ]
then
fbset | awk '/geometry/ {print $3}'
else
fbset | awk '/geometry/ {print $2}'
fi
}
function cpu_vendor() {
awk '/vendor_id/ {print $3;exit}' /proc/cpuinfo
}
function get_aspect_ratio() {
FBWIDTH=$(fbwidth)
FBHEIGHT=$(fbheight)
ASPECT=$(printf "%.2f" $(echo "(${FBWIDTH} / ${FBHEIGHT})" | bc -l))
case ${ASPECT} in
1.00)
ASPECT="1:1"
;;
1.50|0.67)
ASPECT="3:2"
;;
1.33|0.75)
ASPECT="4:3"
;;
1.67|0.60)
ASPECT="5:3"
;;
1.7*|0.56)
ASPECT="16:9"
;;
1.60|0.62)
ASPECT="16:10"
;;
esac
echo ${ASPECT}
}

View file

@ -0,0 +1,9 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
AUDIO_LATENCY=$(get_setting audiolatency)
if [ -n "${AUDIO_LATENCY}" ]
then
export PULSE_LATENCY_MSEC=${AUDIO_LATENCY}
fi

View file

@ -0,0 +1,118 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/os-release
get_tdp_range() {
if [ -n "${DEVICE_TDP_RANGE}" ]
then
for TDP in default ${DEVICE_TDP_RANGE[*]}
do
echo ${TDP}
done
fi
}
get_threads() {
for THREAD in $(seq 1 1 $(find /sys/devices/system/cpu -name online | wc -l)) all default
do
echo ${THREAD}
done
}
set_online_threads() {
AVAILABLE_THREADS=$(($(find /sys/devices/system/cpu -name online | wc -l) - 1))
MODE=${2}
if [ -z "${MODE}" ]
then
MODE=0
fi
case ${1} in
default)
return
;;
all)
THREADS=0
MODE="1"
;;
0)
THREADS=1
;;
*)
THREADS=${1}
;;
esac
for thread in $(seq 0 1 ${THREADS})
do
echo 1 | tee /sys/devices/system/cpu/cpu${thread}/online >/dev/null 2>&1
done
for thread in $(seq ${THREADS} 1 ${AVAILABLE_THREADS})
do
echo ${MODE} | tee /sys/devices/system/cpu/cpu${thread}/online >/dev/null 2>&1
done
}
set_cpu_gov() {
for POLICY in $(ls /sys/devices/system/cpu/cpufreq 2>/dev/null | grep policy[0-9])
do
if [ -e "/sys/devices/system/cpu/cpufreq/${POLICY}/scaling_governor" ]
then
echo $1 >/sys/devices/system/cpu/cpufreq/${POLICY}/scaling_governor 2>/dev/null
fi
done
}
set_dmc_gov() {
if [ -e "${DMC_FREQ}/governor" ]
then
for governor in $1 dmc_$1 simple_$1
do
echo ${governor} >${DMC_FREQ}/governor 2>/dev/null
if [ "$?" = 0 ]
then
return
fi
done
fi
}
set_gpu_gov() {
if [ -e "${GPU_FREQ}/governor" ]
then
for governor in $1 dmc_$1 simple_$1
do
echo ${governor} >${GPU_FREQ}/governor 2>/dev/null
if [ "$?" = 0 ]
then
return
fi
done
fi
}
onlinethreads() {
set_online_threads ${1} ${2}
}
performance() {
set_cpu_gov performance
set_dmc_gov performance
}
ondemand() {
set_cpu_gov ondemand
set_dmc_gov ondemand
}
schedutil() {
set_cpu_gov schedutil
set_dmc_gov ondemand
}
powersave() {
set_cpu_gov powersave
set_dmc_gov powersave
}

View file

@ -0,0 +1,7 @@
 ██ ███████ ██  ████████ ███████
 ██ ██ ██  ██ ██ ██
 ██ ███████ ██  ██ ██ ███████
██ ██ ██ ██  ██ ██ ██
███████ ███████ ███████ ████████ ███████

View file

@ -0,0 +1,96 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
LOG="/var/log/boot.log"
### This script contains items that we only want to execute after a JELOS upgrade,
### or after a fresh installation.
### Items in this block should always run after updates.
################################################################################
echo "Rebuild library cache..." >>${LOG}
tocon "Rebuilding library cache..."
### Rebuild the library cache
rm -f /storage/.cache/ld.so.cache
ldconfig -X
echo "Sync configuration files..." >>${LOG}
tocon "Re-sync configuration files..."
### Sync configurations
if [ -d "/storage/.config/system/configs" ]
then
EXCLUDE="--exclude=configs"
fi
### Remove and link es configs so they are managed with OS updates.
for es_cfg in es_features.cfg es_systems.cfg
do
mv /storage/.config/emulationstation/${es_cfg} /storage/.config/emulationstation/last_${es_cfg} >/dev/null 2>&1
ln -s /usr/config/emulationstation/${es_cfg} /storage/.config/emulationstation/${es_cfg} >/dev/null 2>&1
done
rsync -a --delete ${EXCLUDE} /usr/config/system/ /storage/.config/system/
rsync -a --ignore-existing /usr/config/game /storage/.config/
rsync -a /usr/config/modules /storage/.config/
if [ -f "/storage/.config/emulationstation/resources/logo.png" ]
then
rm -f /storage/.config/emulationstation/resources/logo.png
fi
echo "Sync modules..." >>${LOG}
tocon "Update tool modules..."
rsync -a /usr/config/modules/* /storage/.config/modules/
cp -f /usr/config/retroarch/retroarch-core-options.cfg /storage/.config/retroarch/retroarch-core-options.cfg
### Apply developer ssh keys if they exist
echo "Apply dev keys if available..." >>${LOG}
if [ -e /usr/config/ssh/authorized_keys ]
then
tocon "Update developer keys..."
cp /usr/config/ssh/authorized_keys /storage/.ssh
fi
### Sync rsync configs
echo "Update rsync configuration files..." >>${LOG}
rsync --ignore-existing /usr/config/rsync-rules.conf /storage/.config/
rsync --ignore-existing /usr/config/rsync.conf /storage/.config/
### Sync locale data
tocon "Re-sync locale data..."
rsync -a --delete /usr/config/locale/* /storage/.config/locale/ >>/var/log/configure.log 2>&1
rm -rf /storage/.config/emulationstation/locale >>/var/log/configure.log 2>&1 ||:
ln -sf /usr/share/locale /storage/.config/emulationstation/locale >>/var/log/configure.log 2>&1 ||:
### Fix Japanese language bug
if [ ! -e "/storage/.config/ppsspp/assets/NotoSansJP-Regular.ttf" ]
then
cd /storage/.config/ppsspp/assets
cp /usr/config/ppsspp/assets/NotoSansJP-Regular.ttf .
ln -s NotoSansJP-Regular.ttf Roboto-Condensed.ttf
cd -
fi
### Add items below this line that are safe to remove after a period of time.
################################################################################
## 20240312 clean config files on specific rk3326 devices
model=$(cat /sys/firmware/devicetree/base/model)
clean_list="ODROID-GO Advance Black Edition Powkiddy RGB10"
if echo "${clean_list}" | grep "$model"; then
rm -rf /storage/.config/mupen64plus
rm -rf /storage/.config/drastic
rm -f /storage/.config/ppsspp/PSP/SYSTEM/controls.ini
rm -f /storage/.config/mednafen/mednafen.cfg
fi
if [ "${model}" = "Powkiddy RGB10" ]; then
rm -f /storage/joypads/odroidgo2_v11_joypad.cfg
fi
### 20240207 - Update Vita launchers and data.
rsync -ah --update /usr/config/vita3k/* /storage/.config/vita3k 2>/dev/null
rm -f "/storage/.config/vita3k/launcher/Start Vita3K.sh"

View file

@ -0,0 +1,20 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
ip route | awk '/default/ {print $3}' >/dev/null 2>&1
if [ ! $? = 0 ]
then
echo false
exit 1
else
ping www.google.com -c1 -w1 >/dev/null 2>&1
if [ ! $? = 0 ]
then
echo false
exit 1
else
echo true
exit 0
fi
fi

View file

@ -0,0 +1,227 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
. /etc/os-release
### Vars
UPDATE_ROOT="/storage/.update"
MOUNT_GAMES=$(get_setting system.automount)
GAMES_DEVICE=$(get_setting system.gamesdevice)
MS_PATH="/storage/roms"
function unmount() {
log $0 "Unmount ${1}."
umount -f "${1}" 2>/dev/null ||:
}
function add_readme() {
cat <<EOF >/storage/roms/README
Use the \`Create Game Directories\` option in \`System Settings\` to create your game directories.
EOF
}
function start_ms() {
### Entrypoint will be either games card found (external), or not found (internal).
MOUNT_PATH="/storage/games-${1}"
MS_DEVICE=$(get_setting system.merged.device)
### If the merge target isn't defined and we have an external microsd, we should use the external card by default.
if [ -z "${MS_DEVICE}" ] && \
[ "${1}" = "external" ]
then
set_setting system.merged.device external
fi
### Determine if internal or external is the primary target by configuration.
case ${MS_DEVICE} in
internal)
LOWER="external"
UPPER="internal"
;;
*)
LOWER="internal"
UPPER="external"
;;
esac
for GAME_PATH in internal external
do
if [ ! -d "/storage/games-${GAME_PATH}/roms" ]
then
log $0 "Create /storage/games-${GAME_PATH}/roms."
mkdir -p "/storage/games-${GAME_PATH}/roms"
fi
done
MS_ENABLED=$(get_setting system.merged.storage)
if [ -e "/storage/.ms_unsupported" ] || \
[ ! "${MS_ENABLED}" = 1 ]
then
log $0 "Executing bind mount of ${MOUNT_PATH} to ${MS_PATH}"
mount --bind ${MOUNT_PATH}/roms ${MS_PATH}
else
log $0 "Enabling merged storage of /storage/games-${LOWER} and /storage/games-${UPPER} to ${MS_PATH}."
for DIR in /storage/games-${UPPER}/.tmp/games-workdir /storage/games-${LOWER}/roms /storage/games-${UPPER}/roms
do
if [ ! -d "${DIR}" ]
then
mkdir -p "${DIR}"
fi
done
mount overlay -t overlay -o lowerdir=/storage/games-${LOWER}/roms,upperdir=/storage/games-${UPPER}/roms,workdir=/storage/games-${UPPER}/.tmp/games-workdir ${MS_PATH}
fi
}
start_overlay() {
if [ -e "/storage/.overlay_unsupported" ]
then
# If we're not using the overlay, bind mount the external storage path
# so we don't need to change any configs.
grep ${MOUNT_PATH} /proc/mounts >/dev/null 2>&1
if [ ! $? = 0 ]
then
MOUNT_PATH="/storage/games-internal"
fi
log $0 "Executing bind mount of ${MOUNT_PATH} to ${OVERLAY_PATH}"
mount --bind ${MOUNT_PATH} ${OVERLAY_PATH}
exit 0
else
log $0 "Enabling overlay."
systemctl enable storage-roms.mount >/dev/null 2>&1
systemctl start storage-roms.mount >/dev/null 2>&1
fi
}
if [[ ! "${MOUNT_GAMES}" =~ [0-9] ]]
then
set_setting system.automount 1
elif [[ "${MOUNT_GAMES}" == "0" ]]
then
start_ms internal
add_readme
exit 0
fi
function load_modules() {
for MODULE in exfat vfat
do
lsmod | grep ${MODULE} >/dev/null 2>&1
if [ ! $? = 0 ]
then
log $0 "Loading ${MODULE}."
modprobe ${MODULE} >/dev/null 2>&1
fi
done
}
function mount_games() {
MOUNT_PATH="/storage/games-external"
FSTYPE=$(blkid -o export ${1} | awk 'BEGIN {FS="="} /TYPE/ {print $2}')
case ${FSTYPE} in
ext4)
log $0 "Found supported partition for overlayfs."
if [ -e "/storage/.ms_unsupported" ]
then
rm -f /storage/.ms_unsupported
fi
touch /storage/.ms_supported
;;
*)
log $0 "Partition does not support overlayfs, disabling."
if [ -e "/storage/.ms_supported" ]
then
rm -f /storage/.ms_supported
fi
touch /storage/.ms_unsupported
;;
esac
if [ ! -d "${MOUNT_PATH}" ]
then
log $0 "Create directory ${MOUNT_PATH}"
/usr/bin/busybox mkdir -p ${MOUNT_PATH} >/dev/null 2>&1
fi
NULL=$(cat /proc/mounts | grep -v -e "/var/media" 2>/dev/null | grep ${1})
if [ ! "$?" = "0" ] && \
[ -e "${1}" ] && \
[ ! -e "/storage/.please_resize_me" ]
then
### Udevil shouldn't mount it this early, but just in-case.
umount /var/media/* 2>/dev/null
log $0 "Checking filesystem ${1}."
fsck -Mly ${1} >/dev/null 2>&1
log $0 "Mounting ${1} on ${MOUNT_PATH}"
/usr/bin/busybox mount ${1} ${MOUNT_PATH} >/dev/null 2>&1
fi
start_ms external
add_readme
exit 0
}
function find_games() {
if /usr/bin/busybox mountpoint -q /storage
then
for DEV in $(for dev in mmcblk[0-9] sd[a-z] nvme[0-9]; do blkid | grep ${dev} | awk 'BEGIN {FS=":"}; /ext4/ || /fat/ {print $1}' | sort -r; done)
do
ROOTDEV=$(echo ${DEV} | sed -e "s#^/.*/##g" -e "s#p[0-9].*\$##g")
log $0 "Inspecting ${DEV}."
SIZE=$(awk '/'${ROOTDEV}'$/ {print $3}' /proc/partitions)
if (( ${SIZE} <= 8388608 ))
then
log $0 "Device ${ROOTDEV} is too small, ignoring."
# We don't want to mount partitions smaller than ~8GB.
continue
fi
if [ -L "/sys/class/block/${ROOTDEV}boot0" ]
then
log $0 "Device ${ROOTDEV} might be Android, ignoring."
# Assume this is an android boot device and ignore it.
continue
fi
ISMOUNTED="$(grep "${DEV}" /proc/mounts) >/dev/null 2>&1"
if [ ! "$?" = 0 ] && \
[ -e "${DEV}" ] && \
[ ! -e "/storage/.please_resize_me" ]
then
GAMES_DEVICE=${DEV}
log $0 "Found ${DEV} available to mount."
mount_games "${DEV}"
else
log $0 "${DEV} not available."
fi
done
log $0 "Could not find external card to mount, assume internal."
MS_DEVICE=$(get_setting system.merged.device)
### If the merge target isn't defined and we do not have an external microsd, we should use the internal card by default.
if [ -z "${MS_DEVICE}" ]
then
set_setting system.merged.device internal
fi
start_ms internal
add_readme
exit 0
fi
}
## Main..
load_modules
### Unmount any existing storage before beginning operations.
unmount /storage/games-external
unmount /storage/roms
if [ -e "${GAMES_DEVICE}" ]
then
mount_games ${GAMES_DEVICE}
else
find_games
fi

View file

@ -0,0 +1,69 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert)
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
# NOTE: to customize your backups, create a backuptool.conf file in
# /storage/.config like this:
# LOCATIONS=(
# /storage/.config/retroarch/*
# /storage/roms/savestates/*
# /some/other/folder/file.name*
# )
BACKUPFOLDER="/storage/roms/backup"
BACKUPFILE="${BACKUPFOLDER}/${OS_NAME}_BACKUP.zip"
mkdir -p ${BACKUPFOLDER}
DEFAULT=(
/storage/.config/fancontrol.conf
/storage/.config/backuptool.conf
/storage/.cache/bluetooth/*
/storage/.cache/connman*
/storage/.config/system/configs/system.cfg
/storage/.config/ppsspp/*
/storage/.config/retroarch/*
/storage/.config/moonlight/*
/storage/.config/game/*
/storage/.emulationstation/es_*.cfg
/storage/.emulationstation/scripts/*
/storage/.emulationstation/themesettings/*
$(find /storage/.emulationstation/themes/* -type d -maxdepth 0 -not -path "*es-theme-art-book-next" -not -path "*system-theme")
)
if [ -e "/storage/.config/backuptool.conf" ]
then
source /storage/.config/backuptool.conf
if [ ! $? = 0 ]
then
WARN="Error loading custom backuptool configs. Using defaults."
${DEBUG} && echo "${WARN}"
logger -t backuptool "${WARN}"
COMPRESSLOCATIONS=(${DEFAULT[@]})
else
COMPRESSLOCATIONS=(${LOCATIONS[@]})
fi
else
COMPRESSLOCATIONS=(${DEFAULT[@]})
fi
case "${1}" in
"restore")
unzip -o ${BACKUPFILE} -d /
;;
"backup")
if [ -f ${BACKUPFILE} ]
then
TODAY=`date +%y-%m-%d_%H_%M_%S`
ARCHIVEFILENAME="ARCHIVED_${OS_NAME}_BACKUP-${TODAY}.zip"
mv ${BACKUPFILE} "${BACKUPFOLDER}/${ARCHIVEFILENAME}"
fi
[ -f "${BACKUPFILE}" ] && rm "${BACKUPFILE}"
zip -9 -r ${BACKUPFILE} \
${COMPRESSLOCATIONS[@]}
;;
esac

View file

@ -0,0 +1,110 @@
#!/bin/bash
ACTION=$1
shift
do_help() {
echo "${1} list" >&2
echo "${1} trust" >&2
echo "${1} remove <device address>" >&2
}
do_list() {
find /storage/.cache/bluetooth -type f -name info |
while read FILE
do
if grep -qE '^Trusted=true$' "${FILE}"
then
DEVNAME=$(grep -E '^Name=' "${FILE}" | sed -e s+"^Name="++)
DEVADDR=$(basename $(dirname "${FILE}"))
echo "${DEVADDR} ${DEVNAME}"
fi
done
}
do_remove() {
DEV="${1}"
# output is never nice
if ! (echo "untrust ${DEV}" ; echo "remove ${DEV}") | bluetoothctl >/dev/null 2>/dev/null
then
return 1
fi
return 0
}
do_trust() {
NPID=$(pgrep -f batocera-bluetooth-agent)
test -z "${NPID}" && return 0
touch "/var/run/bt_status" || retrun 1
LAST_MSG=$(cat "/var/run/bt_status")
# start discovering
kill -10 "${NPID}"
trap "kill -12 ${NPID}" 2 3
N=30
while test $N -gt 0
do
NEW_MSG=$(cat "/var/run/bt_status")
if test "${LAST_MSG}" != "${NEW_MSG}"
then
LAST_MSG="${NEW_MSG}"
echo "${NEW_MSG}"
fi
sleep 1
let N--
done
# stop discovering
kill -12 "${NPID}"
}
do_starttrust() {
NPID=$(pgrep -f batocera-bluetooth-agent)
test -z "${NPID}" && exit 0
# start discovering
kill -10 "${NPID}"
}
do_stoptrust() {
NPID=$(pgrep -f batocera-bluetooth-agent)
test -z "${NPID}" && exit 0
# stop discovering
kill -12 "${NPID}"
}
case "${ACTION}" in
"list")
do_list
;;
"trust")
do_trust
;;
"starttrust")
do_starttrust
;;
"stoptrust")
do_stoptrust
;;
"remove")
if test $# = 1
then
do_remove "${1}" || exit 1
else
do_help "${0}"
exit 1
fi
;;
*)
do_help "${0}"
exit 1
esac
exit 0

View file

@ -0,0 +1,461 @@
#!/usr/bin/python
from __future__ import absolute_import, print_function
from optparse import OptionParser, make_option
import dbus
import dbus.service
import dbus.mainloop.glib
import bluezutils
import time
import os
import logging
import signal
from gi.repository import GLib
AGENT_INTERFACE = 'org.bluez.Agent1'
gadapter = None
gdiscovering = False
gdevices = {}
g_devices_seen = {}
logging.basicConfig(filename='/var/log/bluetooth-agent.log', level=logging.DEBUG, format='%(asctime)s %(message)s')
def bool2str(val, valiftrue, valiffalse):
if val:
return valiftrue
else:
return valiffalse
def logging_status(msg):
with open("/var/run/bt_status", "w") as file:
file.write(msg + "\n")
def connect_device(path, address, properties, forceConnect, typeInput, typeAudio):
global gdiscovering
devName = ""
trusted = False
connected = False
# avoid devices without interesting information
if "Trusted" not in properties:
return
if "Connected" not in properties:
return
rproperties = {}
# Get the adapter name and bt mac
for key, value in properties.items():
if type(value) is dbus.String:
value = value.encode('ascii', 'replace')
rproperties[key] = value
trusted = rproperties["Trusted"]
paired = rproperties["Paired"]
devName = getDevName(rproperties)
shortDevName = getShortDevName(rproperties)
connected = rproperties["Connected"]
# skip non input devices
if "Icon" not in properties:
logging.info("Skipping device {} (no type)".format(getDevName(rproperties)));
return
if not ( (typeInput and properties["Icon"].startswith("input")) or (typeAudio and properties["Icon"].startswith("audio")) ):
logging.info("Skipping device {} because of type {}".format(getDevName(rproperties), properties["Icon"]));
return
blacklistAddr, blacklistName = getBlacklistAddrAndName(properties)
# add device to the seen list
if blacklistAddr not in g_devices_seen:
g_devices_seen[blacklistAddr] = { "name": blacklistName }
updateKnownDevicesList(g_devices_seen)
# skip blacklisted devices
if blacklistAddr is not None and isDeviceBlacklisted(blacklistAddr):
logging.info("Skipping blacklisted device {}".format(blacklistName))
return
logging.info("event for " + devName + "(paired=" + bool2str(paired, "paired", "not paired") + ", trusted=" + bool2str(trusted, "trusted", "untrusted") + ", connected=" + bool2str(connected, "connected", "disconnected") + ")")
# skipping connected devices
if paired and trusted and connected:
logging.info("Skipping already connected device {}".format(getDevName(rproperties)));
return
if not paired:
if connected == False and gdiscovering:
doParing(address, devName, shortDevName)
return
# now it is paired
if not trusted and (gdiscovering or forceConnect):
logging.info("Trusting (" + devName + ")")
logging_status("Trusting " + shortDevName + "...")
bluezProps = dbus.Interface(bus.get_object("org.bluez", path), "org.freedesktop.DBus.Properties")
bluezProps.Set("org.bluez.Device1", "Trusted", True)
# now it is paired and trusted
# Connect if Trusted and paired
if not connected or forceConnect:
doConnect(address, devName, shortDevName)
def doParing(address, devName, shortDevName):
logging.info("Pairing... (" + devName + ")")
logging_status("Pairing " + shortDevName + "...")
device = bluezutils.find_device(address)
try:
device.Pair()
except Exception as e:
logging.info("Pairing failed (" + devName + ")")
logging_status("Pairing failed (" + shortDevName + ")")
def doConnect(address, devName, shortDevName):
global gadapter
global gdiscovering
try:
# discovery stopped during connection to help some devices
if gdiscovering:
logging.info("Stop discovery")
gadapter.StopDiscovery()
device = bluezutils.find_device(address)
ntry=5
while ntry > 0:
ntry = ntry -1
try:
logging.info("Connecting... (" + devName + ")")
logging_status("Connecting " + shortDevName + "...")
device.Connect()
logging.info("Connected successfully (" + devName + ")")
logging_status("Connected successfully (" + shortDevName + ")")
if gdiscovering:
logging.info("Start discovery")
gadapter.StartDiscovery()
return
except dbus.exceptions.DBusException as err:
logging.info("dbus: " + err.get_dbus_message())
time.sleep(1)
except Exception as err:
logging.info("Connection failed (" + devName + ")")
time.sleep(1)
logging.info("Connection failed. Give up. (" + devName + ")")
logging_status("Connection failed. Give up. (" + shortDevName + ")")
if gdiscovering:
logging.info("Start discovery")
gadapter.StartDiscovery()
except Exception as e:
if gdiscovering:
logging.info("Start discovery")
gadapter.StartDiscovery()
# don't raise, while startdiscovery doesn't like it
#raise e
def getDevName(properties):
#devName = properties["Name"] + " (" + properties["Address"] + ", " + properties["Icon"] + ")"
#devStatus = "Trusted=" + str(properties["Trusted"]) + ", paired=" + str(properties["Paired"]) + ", connected=" + str(properties["Connected"]), ", blocked=" + str(properties["Blocked"])
#devTech = "legacyPairing: " + str(properties["LegacyPairing"]) # + ", RSSI: " + properties["RSSI"]
if "Name" in properties and "Address" in properties and "Icon" in properties:
return str(properties["Name"]) + " (" + str(properties["Address"]) + ", " + str(properties["Icon"]) + ")"
if "Name" in properties and "Address" in properties:
return str(properties["Name"]) + " (" + str(properties["Address"]) + ")"
if "Name" in properties and "Icon" in properties:
return str(properties["Name"]) + " (" + str(properties["Icon"]) + ")"
if "Name" in properties:
return str(properties["Name"])
if "Address" in properties and "Icon" in properties:
return str(properties["Address"]) + " (" + str(properties["Icon"]) + ")"
if "Address" in properties:
return str(properties["Address"])
if "Icon" in properties:
return str(properties["Icon"])
return "unknown"
def updateKnownDevicesList(g_devices_seen):
f = open("/var/run/bluetooth_seen", "w")
for key in g_devices_seen:
f.write("{} {}\n".format(key, g_devices_seen[key]["name"]))
f.close()
def isDeviceBlacklisted(blacklistAddr):
datafile = "/var/lib/bluetooth/bluetooth_blacklisted"
# reread the file each time in case somebody changed it
if not os.path.isfile(datafile):
return False
with open(datafile) as file:
lines = file.readlines()
for line in lines:
if line[0:len(blacklistAddr)] == blacklistAddr:
return True
return False
def getBlacklistAddrAndName(properties):
if "Address" not in properties:
return None
address = str(properties["Address"])
name = ""
if "Name" in properties:
name = str(properties["Name"])
elif "Icon" in properties:
name = str(properties["Icon"])
else:
name = "unknown"
return address, name
def getShortDevName(properties):
if "Name" in properties:
return str(properties["Name"])
if "Address" in properties:
return str(properties["Address"])
if "Icon" in properties:
return str(properties["Icon"])
return "unknown"
def getBluetoothWantedTypes():
if not os.path.isfile("/var/run/bt_types"):
logging.info("no bt_types file")
return True, True
btype = ""
with open("/var/run/bt_types", "r") as file:
btype = file.read().strip()
logging.info("bt_type: {}".format(btype))
if btype == "":
return True, True
if btype == "pad":
return True, False
if btype == "audio":
return False, True
return False, False
def interfaces_added(path, interfaces):
global gdevices
if "org.bluez.Device1" not in interfaces:
return
if not interfaces["org.bluez.Device1"]:
return
properties = interfaces["org.bluez.Device1"]
if path in gdevices:
gdevices[path] = merge2dicts(gdevices[path], properties)
else:
gdevices[path] = properties
if "Address" in gdevices[path]:
typeInput, typeAudio = getBluetoothWantedTypes()
connect_device(path, properties["Address"], gdevices[path], False, typeInput, typeAudio)
def properties_changed(interface, changed, invalidated, path):
global gdevices
if interface != "org.bluez.Device1":
return
if path in gdevices:
gdevices[path] = merge2dicts(gdevices[path], changed)
else:
gdevices[path] = changed
#logging.info("Properties changed:")
#logging.info(changed)
#logging.info(invalidated)
if "Paired" in changed and changed["Paired"] == True:
# ok, do as in simple-agent, trust and connect
typeInput, typeAudio = getBluetoothWantedTypes()
connect_device(path, gdevices[path]["Address"], gdevices[path], True, typeInput, typeAudio)
return
# ok, it is now connected, what else ?
if "Connected" in changed and changed["Connected"] == True:
return
if "Connected" in changed and changed["Connected"] == False:
logging.info("Skipping (property Connected changed to False)");
return
if "Address" in gdevices[path]:
typeInput, typeAudio = getBluetoothWantedTypes()
connect_device(path, gdevices[path]["Address"], gdevices[path], False, typeInput, typeAudio)
def merge2dicts(d1, d2):
res = d1.copy()
res.update(d2)
return res
def user_signal_start_discovery(signum, frame):
global gdiscovering
global gadapter
try:
if gdiscovering == False:
gdiscovering = True
logging.info("Start discovery (signal)")
gadapter.StartDiscovery()
except:
pass
def user_signal_stop_discovery(signum, frame):
global gdiscovering
global gadapter
try:
if gdiscovering:
gdiscovering = False
logging.info("Stop discovery (signal)")
gadapter.StopDiscovery()
except:
pass
class Agent(dbus.service.Object):
exit_on_release = True
def set_exit_on_release(self, exit_on_release):
self.exit_on_release = exit_on_release
@dbus.service.method(AGENT_INTERFACE, in_signature="", out_signature="")
def Release(self):
logging.info("agent: Release")
if self.exit_on_release:
mainloop.quit()
@dbus.service.method(AGENT_INTERFACE, in_signature="os", out_signature="")
def AuthorizeService(self, device, uuid):
logging.info("agent: AuthorizeService")
return
@dbus.service.method(AGENT_INTERFACE, in_signature="o", out_signature="s")
def RequestPinCode(self, device):
logging.info("RequestPinCode (%s)" % (device))
return "0000"
@dbus.service.method(AGENT_INTERFACE, in_signature="o", out_signature="u")
def RequestPasskey(self, device):
logging.info("RequestPasskey (%s)" % (device))
return 0
@dbus.service.method(AGENT_INTERFACE, in_signature="ouq", out_signature="")
def DisplayPasskey(self, device, passkey, entered):
logging.info("agent: DisplayPasskey (%s, %06u entered %u)" % (device, passkey, entered))
@dbus.service.method(AGENT_INTERFACE, in_signature="os", out_signature="")
def DisplayPinCode(self, device, pincode):
logging.info("agent: DisplayPinCode (%s, %s)" % (device, pincode))
@dbus.service.method(AGENT_INTERFACE, in_signature="ou", out_signature="")
def RequestConfirmation(self, device, passkey):
logging.info("agent: RequestConfirmation")
return
@dbus.service.method(AGENT_INTERFACE, in_signature="o", out_signature="")
def RequestAuthorization(self, device):
logging.info("agent: RequestAuthorization")
return
@dbus.service.method(AGENT_INTERFACE, in_signature="", out_signature="")
def Cancel(self):
logging.info("agent: Cancel")
def do_main_loop(dev_id):
global gadapter
# adapter
try:
adapter = bluezutils.find_adapter(dev_id)
except:
# try to find any adapter
adapter = bluezutils.find_adapter(None)
logging.info("adapter found")
gadapter = adapter
adapters = {}
om = dbus.Interface(bus.get_object("org.bluez", "/"), "org.freedesktop.DBus.ObjectManager")
objects = om.GetManagedObjects()
for path, interfaces in objects.items():
if "org.bluez.Device1" in interfaces:
gdevices[path] = interfaces["org.bluez.Device1"]
if "org.bluez.Adapter1" in interfaces:
adapters[path] = interfaces["org.bluez.Adapter1"]
adapter_props = adapters[adapter.object_path]
logging.info(adapter_props["Name"] + "(" + adapter_props["Address"] + "), powered=" + str(adapter_props["Powered"]))
# power on adapter if needed
if adapter_props["Powered"] == 0:
try:
logging.info("powering on adapter ("+ adapter_props["Address"] +")")
adapterSetter = dbus.Interface(bus.get_object("org.bluez", adapter.object_path), "org.freedesktop.DBus.Properties")
adapterSetter.Set("org.bluez.Adapter1", "Powered", True)
except:
pass # hum, not nice
gdiscovering = False
# events
# use events while i manage to stop discovery only from the process having started it
signal.signal(signal.SIGUSR1, user_signal_start_discovery)
signal.signal(signal.SIGUSR2, user_signal_stop_discovery)
mainloop = GLib.MainLoop()
mainloop.run()
if __name__ == '__main__':
# options
option_list = [ make_option("-i", "--device", action="store", type="string", dest="dev_id") ]
parser = OptionParser(option_list=option_list)
(options, args) = parser.parse_args()
# initialize the seen devices file
updateKnownDevicesList(g_devices_seen)
# register dbus
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
bus.add_signal_receiver(interfaces_added, dbus_interface = "org.freedesktop.DBus.ObjectManager", signal_name = "InterfacesAdded")
bus.add_signal_receiver(properties_changed, dbus_interface = "org.freedesktop.DBus.Properties", signal_name = "PropertiesChanged", arg0 = "org.bluez.Device1", path_keyword = "path")
# register the agent
agentpath = "/storage/agent"
obj = bus.get_object("org.bluez", "/org/bluez")
manager = dbus.Interface(obj, "org.bluez.AgentManager1")
manager.RegisterAgent(agentpath, "NoInputNoOutput")
manager.RequestDefaultAgent(agentpath)
agent = Agent(bus, agentpath)
logging.info("agent registered")
# run the agent, allows some tries while hardware can take time to initiate
time.sleep(2)
try:
do_main_loop(options.dev_id)
except Exception as e:
logging.error("agent fails")
logging.error(e, exc_info=True)
raise
logging.error("agent gave up")

View file

@ -0,0 +1,297 @@
#!/bin/bash
. /etc/profile
. /etc/os-release
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/system/configs/config.txt"
storageFile="/storage/.config/system/configs/batocera-boot.conf"
command="$1"
mode="$2"
extra1="$3"
extra2="$4"
extra3="$5"
extra4="$6"
arch=${HW_DEVICE}
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=/var/log/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 -c 0 -M 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
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 -c 0 -M set ${DEVICE_AUDIO_MIXER} unmute || exit 1
amixer -c 0 -M set ${DEVICE_AUDIO_MIXER} -- ${mode}% || exit 1
# maximize the sound to be sure it's not 0, allow errors
amixer -c 0 -M set PCM -- 100% #|| exit 1
amixer -c 0 -M 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
system-upgrade
exit $?
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/system/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

View file

@ -0,0 +1 @@
jelos-info

View file

@ -0,0 +1,18 @@
#!/bin/bash
ACTION=$1
shift
FILEMODES="/sys/class/graphics/fb0/modes"
case "${ACTION}" in
"listModes")
;;
"setMode")
;;
"currentMode"|"currentResolution")
# mode can be different from resolution (ie on rpi)
test -e "${FILEMODES}" && head -1 "${FILEMODES}" | sed -e s+'^[^:]:\([0-9]*\)x\([0-9]*\)[a-z]*.*$'+'\1x\2'+
;;
esac
exit 0

View file

@ -0,0 +1,104 @@
#!/bin/bash
#
# Get RetroAchievements information for Batocera
#
# @lbrpdx on Batocera Forums and Discord
#
# 20191124 - v2 with now outputs in XML format (for Batocera 5.25+)
# 20200113 - updated for retroachievements.org HTML changes
# 20200124 - added badges for each game played
# 20200304 - fixed a bug in rare cases where a RA game has no success icons
# 20200410 - updated for retroachievements.org HTML changes, again
# 20200625 - retroachievements.org HTML changes, again
# 20201104 - retroachievements.org HTML changes, again, again
#
# Usage:
# batocera-retroachievements-info
#
CONFIGFILE="/storage/.config/system/configs/system.cfg"
TIMEOUT=4 # seconds before timeout (>2 sec)
USER=""
###############################
#
function usage() {
echo "$0 username"
echo " - where username is the RetroAchievements username you want to check out"
exit 1
}
###############################
#
function process() {
fn=$(date +"%s")
tmpfile=/tmp/ra_$fn
curl -H 'Cache-Control: no-cache' -m "$TIMEOUT" -o $tmpfile https://retroachievements.org/user/$USER 2>/dev/null
if [ x"$?" != x0 ]; then
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<retroachievements>"
echo " <lastrefresh>$fn</lastrefresh>"
echo " <error>RetroAchievements website is too slow to respond</error>"
echo "</retroachievements>"
exit 1;
fi
cat "$tmpfile" | awk -v FS="(<div class='username'><span class='username'>|</div><div class='userpage recentlyplayed' >)" '{print $2}' | uniq > "$tmpfile"_2
idcard=$(cat "$tmpfile" | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(</span></div><br/?>Member Since: |<br/?>Account Type:)" '{print $2}' | uniq)
parsedid=$(echo "$idcard" | sed -e "/^[[:blank:]]*$/d" | sed -e "s;\(.*\)<br>Last Activity: \(.*\);\1@\2;")
avcompletion=$(cat "$tmpfile" | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(</span><br/?>Average Completion: <b>|</b><br/?>Site Rank:)" '{print $2}' | sed -e "/^[[:blank:]]*$/d" | uniq)
points=$(cat "$tmpfile"_2 | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(</strong></a>&nbsp;|<span class='TrueRatio'>)" '{print $2}' | sed -e "s;(\([0-9]*\) points);\1;")
if [ x"$points" != x ] && [ "$points" -ge 1 ]; then
rank=$(cat "$tmpfile"_2 | sed -e "/^[[:blank:]]*$/d" | awk -v FS="(globalRanking.php|<br/?><br/?>)" '{print $3}' | sed -e "s/\?[a-zA-Z0-9=&;']*>//" -e "s;</a>;;" -e "s;%).*;%);")
## For future use: UserPic is RetroAchievements' user avatar - however the S3 bucket is protected.
# UserPic=$(cat $tmpfile | grep 'meta property=.og:image. content=' | cut -d= -f3 | awk -F\' '{print $2}')
# Workaround: use the line below
UserPic="https://retroachievements.org/UserPic/$USER".png
pic=""
curl -H 'Cache-Control: no-cache' -m "$TIMEOUT" -f -s "$UserPic" >/dev/null 2>/dev/null
if [ x"$?" == x0 ]; then
pic=" <userpic>$UserPic</userpic>\n"
fi
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<retroachievements>"
echo " <lastrefresh>$fn</lastrefresh>"
echo " <username>$USER</username>"
echo " <totalpoints>$points</totalpoints>"
echo " <rank>$rank</rank>"
echo " <averagecompletion>$avcompletion</averagecompletion>"
echo -ne "$pic"
echo "$parsedid" | sed -e "s;\(.*\)@\(.*\); <registered>\1</registered>\n <lastactivity>\2</lastactivity>;"
xmllint --html "$tmpfile" 2>/dev/null | grep '<a href="/[gG]ame/[0-9]*\">.*points.<br\?>' | sed -e "/^[[:blank:]]*$/d" | sed -e 's:\(<a href=\"/[gG]ame/[0-9]*\">.*\)points\.<br>:\1points\@\\\n:g;' > "$tmpfile"_2
cat "$tmpfile"_2 | awk -v FS="(href=\"/[gG]ame/[0-9]*\">|@)" '{print $2}' | sed -e "s;</a><br/*>\(Last played[ 0-9:-]*\)<br/*>\(.*\);@\2@\1;" | sed -e "s;achievements, ;achievements@;" | sed -e "s;Earned ;;" | sed -e "/^[[:blank:]]*$/d" > "$tmpfile"_st
cat "$tmpfile"_2 | grep -e 'div class="bb_inline" onmouseover' -e '^$' | sed "s:.*src=\"\(.*/Badge/.*\.png\)\".*:\1:" | sed "s;^$;https://batocera.org/favicon-64.png;" > "$tmpfile"_ba
i=0
if [ $(cat "$tmpfile"_ba | wc -l) -eq $(cat "$tmpfile"_st | wc -l) ]; then
while IFS= read -r line || [[ -n "$line" ]]; do
i=$((i+1))
echo "$line" | sed -e "s;\(.*\)@\(.*\) achievements@\(.*\) points@Last played \(.*\); <game>\n <name>\1</name>\n <achievements>\2</achievements>\n <points>\3</points>\n <lastplayed>\4</lastplayed>;"
cat "$tmpfile"_ba | head -n "$i" | tail -n 1 | sed "s:^: <badge>:;s:$:</badge>:"
echo " </game>"
done < "$tmpfile"_st
else
echo "$res" | sed -e "s;\(.*\)@\(.*\) achievements@\(.*\) points@Last played \(.*\); <game>\n <name>\1</name>\n <achievements>\2</achievements>\n <points>\3</points>\n <lastplayed>\4</lastplayed>\n </game>;"
fi
echo "</retroachievements>"
else
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<retroachievements>"
echo " <lastrefresh>$fn</lastrefresh>"
echo " <error>Player $USER hasn't unlocked any RetroAchievement yet</error>"
echo "</retroachievements>"
fi
rm "$tmpfile" "$tmpfile"_2 "$tmpfile"_st "$tmpfile"_ba 2>/dev/null
}
#### Main loop
#
if [ $# -lt 1 ]; then
[ -f "$CONFIGFILE" ] && USER=$(grep -E "^[ \t]*global.retroachievements.username=" "$CONFIGFILE" | cut -d= -f2 | uniq)
else
tmp="$1"
[ x"${tmp::1}" == "x-" ] && usage || USER="$1"
fi
[ x"$USER" == x ] && usage || process

View file

@ -0,0 +1,79 @@
#!/bin/bash
systemsetting="/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}" = "/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 "/storage/roms/${DOSYS}" && echo "/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

View file

@ -0,0 +1,267 @@
#!/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 system.cfg (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 #####
BATOCERA_CONFIGFILE="/storage/.config/system/configs/system.cfg"
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 system.cfg (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/system.cfg'"
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 #####

View file

@ -0,0 +1,612 @@
#!/usr/bin/env python
from __future__ import print_function
from hashlib import md5
from os.path import isfile
from collections import OrderedDict
import sys
systems = {
# Atari
"atari5200": {"name": "Atari 5200", "biosFiles": [{"md5": "281f20ea4320404ec820fb7ec0693b38", "file": "bios/5200.rom"}]},
"atari800": {"name": "Atari 800", "biosFiles": [{"md5": "06daac977823773a3eea3422fd26a703", "file": "bios/ATARIXL.ROM"},
{"md5": "0bac0c6a50104045d902df4503a4c30b", "file": "bios/ATARIBAS.ROM"},
{"md5": "eb1f32f5d9f382db1bbfb8d7f9cb343a", "file": "bios/ATARIOSA.ROM"},
{"md5": "a3e8d617c95d08031fe1b20d541434b2", "file": "bios/ATARIOSB.ROM"}]},
"atari7800": {"name": "Atari 7800", "biosFiles": [{"md5": "0763f1ffb006ddbe32e52d497ee848ae", "file": "bios/7800 BIOS (U).rom"}]},
"atarist": {"name": "Atari ST", "biosFiles": [{"md5": "b2a8570de2e850c5acf81cb80512d9f6", "file": "bios/tos.img"}]},
"atarilynx": {"name": "Lynx", "biosFiles": [{"md5": "fcd403db69f54290b51035d82f835e7b", "file": "bios/lynxboot.img"}]},
# Colecovision
"colecovision": {"name": "Colecovision", "biosFiles": [{"md5": "", "file": "bios/Machines/COL - Bit Corporation Dina/config.ini"},
{"md5": "1de922acdd742d31349c2801e9768c35", "file": "bios/Machines/COL - Bit Corporation Dina/czz50-1.rom"},
{"md5": "72b089dc55b7fe7ffb5028f365e8c045", "file": "bios/Machines/COL - Bit Corporation Dina/czz50-2.rom"},
{"md5": "2c66f5911e5b42b8ebe113403548eee7", "file": "bios/Machines/COL - ColecoVision/coleco.rom"},
{"md5": "", "file": "bios/Machines/COL - ColecoVision/config.ini"},
{"md5": "2c66f5911e5b42b8ebe113403548eee7", "file": "bios/Machines/COL - ColecoVision with Opcode Memory Extension/coleco.rom"},
{"md5": "", "file": "bios/Machines/COL - ColecoVision with Opcode Memory Extension/config.ini"},
{"md5": "", "file": "bios/Machines/COL - Spectravideo SVI-603 Coleco/config.ini"},
{"md5": "c60a2e85572c0ccb69505a7646d5c1b6", "file": "bios/Machines/COL - Spectravideo SVI-603 Coleco/SVI603.ROM"},
{"md5": "", "file": "bios/Databases/colecodb.xml"},
{"md5": "2c66f5911e5b42b8ebe113403548eee7", "file": "bios/colecovision.rom"},
{"md5": "2c66f5911e5b42b8ebe113403548eee7", "file": "bios/BIOS.col"}]},
# Commodore
"amiga": {"name": "Amiga/CD32", "biosFiles": [{"md5": "89da1838a24460e4b93f4f0c5d92d48d", "file": "bios/CDTV Extended-ROM v1.0 (1991)(Commodore)(CDTV)[!].rom"},
{"md5": "85ad74194e87c08904327de1a9443b7a", "file": "bios/Kickstart v1.2 r33.180 (1986)(Commodore)(A500-A1000-A2000)[!].rom"},
{"md5": "68c9c0826f6c0ca20546d588ee77391c", "file": "bios/Kickstart v1.2 rev 33.166 (1986)(Commodore)(A1000).rom"},
{"md5": "192d6d950d0ed3df8040b788502831c2", "file": "bios/Kickstart v1.3 r34.5 (1987)(Commodore)(A500-A1000-A2000-CDTV)[o].rom"},
{"md5": "82a21c1890cae844b3df741f2762d48d", "file": "bios/Kickstart v1.3 r34.5 (1987)(Commodore)(A500-A1000-A2000-CDTV)[!].rom"},
{"md5": "dc10d7bdd1b6f450773dfb558477c230", "file": "bios/Kickstart v2.04 r37.175 (1991)(Commodore)(A500+)[!].rom"},
{"md5": "465646c9b6729f77eea5314d1f057951", "file": "bios/Kickstart v2.05 r37.350 (1992)(Commodore)(A600HD)[!].rom"},
{"md5": "5f8924d013dd57a89cf349f4cdedc6b1", "file": "bios/Kickstart v3.1 r40.60 (1993)(Commodore)(CD32).rom"},
{"md5": "646773759326fbac3b2311fd8c8793ee", "file": "bios/Kickstart v3.1 r40.68 (1993)(Commodore)(A1200)[!].rom"},
{"md5": "413590e50098a056cfec418d3df0212d", "file": "bios/Kickstart v3.1 r40.68 (1993)(Commodore)(A3000).rom"},
{"md5": "9bdedde6a4f33555b4a270c8ca53297d", "file": "bios/Kickstart v3.1 r40.68 (1993)(Commodore)(A4000).rom"},
{"md5": "85ad74194e87c08904327de1a9443b7a", "file": "bios/kick33180.A500"},
{"md5": "82a21c1890cae844b3df741f2762d48d", "file": "bios/kick34005.A500"},
{"md5": "dc10d7bdd1b6f450773dfb558477c230", "file": "bios/kick37175.A500"},
{"md5": "5f8924d013dd57a89cf349f4cdedc6b1", "file": "bios/kick40060.CD32"},
{"md5": "bb72565701b1b6faece07d68ea5da639", "file": "bios/kick40060.CD32.ext"},
{"md5": "e40a5dfb3d017ba8779faba30cbd1c8e", "file": "bios/kick40063.A600"},
{"md5": "646773759326fbac3b2311fd8c8793ee", "file": "bios/kick40068.A1200"},
{"md5": "9bdedde6a4f33555b4a270c8ca53297d", "file": "bios/kick40068.A4000"},
{"md5": "bb72565701b1b6faece07d68ea5da639", "file": "bios/CD32 Extended-ROM r40.60 (1993)(Commodore)(CD32).rom"}]},
# Magnavox and Philips
"o2em": {"name": "Odyssey 2", "biosFiles": [{"md5": "562d5ebf9e030a40d6fabfc2f33139fd", "file": "bios/o2rom.bin"},
{"md5": "f1071cdb0b6b10dde94d3bc8a6146387", "file": "bios/c52.bin"},
{"md5": "c500ff71236068e0dc0d0603d265ae76", "file": "bios/g7400.bin"},
{"md5": "279008e4a0db2dc5f1c048853b033828", "file": "bios/jopac.bin"}]},
# Mattel
"intellivision": {"name": "Mattel Intellivision", "biosFiles": [{"md5": "62e761035cb657903761800f4437b8af", "file": "bios/exec.bin"},
{"md5": "0cd5946c6473e42e8e4c2137785e427f", "file": "bios/grom.bin"},
{"md5": "2e72a9a2b897d330a35c8b07a6146c52", "file": "bios/ECS.bin"},
{"md5": "d5530f74681ec6e0f282dab42e6b1c5f", "file": "bios/IVOICE.bin"}]},
# Microsoft
"msx": {"name": "MSX", "biosFiles": [{"md5": "", "file": "bios/Machines/Forte II Games - Pesadelo/config.ini"},
{"md5": "", "file": "bios/Machines/Forte II Games - Pesadelo/pesadelo.rom"},
{"md5": "", "file": "bios/Machines/MSX/config.ini"},
{"md5": "", "file": "bios/Machines/MSX/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX/MSX.ROM"},
{"md5": "", "file": "bios/Machines/MSX/MSX2.ROM"},
{"md5": "", "file": "bios/Machines/MSX/MSX2EXT.ROM"},
{"md5": "", "file": "bios/Machines/MSX/MSX2P.ROM"},
{"md5": "", "file": "bios/Machines/MSX/MSX2PEXT.ROM"},
{"md5": "", "file": "bios/Machines/MSX/MSXDOS2.ROM"},
{"md5": "", "file": "bios/Machines/MSX - Al Alamiah AX-170/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Arabic/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Brazilian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Brazilian/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX - C-BIOS/cbios.txt"},
{"md5": "", "file": "bios/Machines/MSX - C-BIOS/cbios_logo_msx1.rom"},
{"md5": "", "file": "bios/Machines/MSX - C-BIOS/cbios_main_msx1.rom"},
{"md5": "", "file": "bios/Machines/MSX - C-BIOS/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Canon V-10/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Canon V-20/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Daewoo DPC-100/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Daewoo DPC-180/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Daewoo DPC-200/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Estonian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Frael Bruc 100-1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - French/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - German/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - German/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX - Goldstar FC-200/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Gradiente Expert 1.0/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Gradiente Expert 1.1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Gradiente Expert 1.3/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Gradiente Expert DDPlus/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Gradiente Expert Plus/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Japanese/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Japanese/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX - JVC HC-7GB/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Korean/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Korean/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX - Mitsubishi ML-F80/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Mitsubishi ML-FX1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - National CF-1200/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1 (a)/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1F/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1FM/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1MK2/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8220/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8220 (a)/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8245/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8245F/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8250/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8255/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8280/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8280G/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips VG-8230/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips VG-8235/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sharp Epcom HotBit 1.2/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sharp Epcom HotBit 1.3b/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sharp Epcom HotBit 1.3p/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-10P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-201/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-201P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-20P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-501P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-55D/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-55P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-75D/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sony HB-75P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Spanish/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Spectravideo SVI-728/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Spectravideo SVI-738/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Spectravideo SVI-738-2 CUC/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Spectravideo SVI-738-2 JP Grobler/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Spectravideo SVI-738-2 LC Grosso/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Swedish/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Talent TPC-310/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Toshiba HX-23/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Toshiba HX-23F/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Virtual Haesung Console/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Yamaha CX7M/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Yamaha CX7M-128/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2+/MSX.ROM"},
{"md5": "", "file": "bios/Machines/MSX2+/MSX2.ROM"},
{"md5": "", "file": "bios/Machines/MSX2+/MSX2EXT.ROM"},
{"md5": "", "file": "bios/Machines/MSX2+/MSX2P.ROM"},
{"md5": "", "file": "bios/Machines/MSX2+/MSX2PEXT.ROM"},
{"md5": "", "file": "bios/Machines/MSX2+/MSXDOS2.ROM"},
{"md5": "", "file": "bios/Machines/MSX2+ - Brazilian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios.txt"},
{"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios_logo_msx2+.rom"},
{"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios_main_msx2+.rom"},
{"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios_music.rom"},
{"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios_sub.rom"},
{"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Ciel Expert 3 IDE/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Ciel Expert 3 Turbo/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Spectravideo SVI-738 Swedish/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Swedish/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Swedish/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX - Talent DPC-200/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Talent DPC-200A/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Toshiba HX-10/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Toshiba HX-10S/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Toshiba HX-20/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha CX5M-1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha CX5M-128/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha CX5M-2/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha CX5MII/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha YIS303/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503F/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503II/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503IIR/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503M/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yashica YC-64/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yeno DPC-64/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yeno MX64/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2/MSX.ROM"},
{"md5": "", "file": "bios/Machines/MSX2/MSX2.ROM"},
{"md5": "", "file": "bios/Machines/MSX2/MSX2EXT.ROM"},
{"md5": "", "file": "bios/Machines/MSX2/MSX2P.ROM"},
{"md5": "", "file": "bios/Machines/MSX2/MSX2PEXT.ROM"},
{"md5": "", "file": "bios/Machines/MSX2/MSXDOS2.ROM"},
{"md5": "", "file": "bios/Machines/MSX2 - Al Alamiah AX-350/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Al Alamiah AX-370/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Arabic/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Arabic/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - Brazilian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Brazilian/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/cbios.txt"},
{"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/cbios_logo_msx2.rom"},
{"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/cbios_main_msx2.rom"},
{"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/cbios_sub.rom"},
{"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Daewoo CPC-300/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Daewoo CPC-300E/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Daewoo CPC-400/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Daewoo CPC-400S/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Estonian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - French/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - French/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - German/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - German/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - Gradiente Expert 2.0/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Japanese/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Japanese/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - Korean/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Korean/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - National FS-4500/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - National FS-4600/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - National FS-4700/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - National FS-5000/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - National FS-5500F1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - National FS-5500F2/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Daewoo DPC-200E/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - National CF-2000/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sharp Epcom HotBit 1.1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Spectravideo SVI-738 Henrik Gilvad/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503IIR Estonian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Only PSG/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Only PSG/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips VG-8235F/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Spanish/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Spanish/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2+ - European/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - National CF-2700/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - National CF-3000/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - National CF-3300/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - National FS-1300/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - National FS-4000/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Olympia PHC-2/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Olympia PHC-28/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Panasonic CF-2700G/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Philips NMS-801/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Philips VG-8000/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Philips VG-8010/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Philips VG-8010F/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Philips VG-8020-00/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Philips VG-8020-20/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Philips VG-8020F/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Pioneer PX-7/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Pioneer PX-V60/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Russian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sanyo MPC-100/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sanyo MPC-64/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sanyo PHC-28L/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sanyo PHC-28S/config.ini"},
{"md5": "", "file": "bios/Machines/MSX - Sanyo Wavy MPC-10/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Gradiente Expert AC88+/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Gradiente Expert DDX+/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - MSXPLAYer 2003/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Panasonic FS-A1FX/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Panasonic FS-A1WSX/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Panasonic FS-A1WX/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Panasonic FS-A1WX (a)/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Sanyo Wavy PHC-35J/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Sanyo Wavy PHC-70FD1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Sanyo Wavy PHC-70FD2/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Sony HB-F1XDJ/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Sony HB-F1XV/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2+ - Sony HB-F9S+/config.ini"},
{"md5": "", "file": "bios/Machines/MSXturboR/config.ini"},
{"md5": "", "file": "bios/Machines/MSXturboR - European/config.ini"},
{"md5": "", "file": "bios/Machines/MSXturboR - Panasonic FS-A1GT/config.ini"},
{"md5": "", "file": "bios/Machines/MSXturboR - Panasonic FS-A1ST/config.ini"},
{"md5": "", "file": "bios/Machines/MSXturboR - Panasonic FS-A1ST (a)/config.ini"},
{"md5": "", "file": "bios/Machines/MSXturboR - Panasonic FS-A1ST (b)/config.ini"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2G.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXDOS23.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/ARAB1.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/ARABIC.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/BEERIDE.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/FMPAC.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/GCVMX80.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/HANGUL.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/KANJI.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MICROSOLDISK.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MOONSOUND.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2AR.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2AREXT.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2BR.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2BREXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2EXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2FR.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2FREXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2GEXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2HAN.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2J.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2JEXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2KR.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2KREXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2P.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2PEXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2PMUS.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2R.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2R2.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2REXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2SE.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2SP.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSX2SPEXT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXAR.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXBR.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXDOS2.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXFR.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXG.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXHAN.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXJ.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXKANJI.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXKR.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXR.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXR2.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXSE.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXSP.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXTR.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXTREXT.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXTRMUS.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/MSXTROPT.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/NATIONALDISK.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/NOVAXIS.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/nowindDos1.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/nowindDos2.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/PAINT.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/PANASONICDISK.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/PHILIPSDISK.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/RS232.ROM"},
{"md5": "", "file": "bios/Machines/Shared Roms/Shared.txt"},
{"md5": "", "file": "bios/Machines/Shared Roms/SUNRISEIDE.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/SWP.rom"},
{"md5": "", "file": "bios/Machines/Shared Roms/XBASIC2.rom"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-318/config.ini"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-318/svi318.rom"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328/config.ini"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328/svi328.rom"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Column/config.ini"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Column/svi328a.rom"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Column/svi806.rom"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Swedish/config.ini"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Swedish/svi328a.rom"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Swedish/svi806se.rom"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 MK2/config.ini"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 MK2/svi328a.rom"},
{"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 MK2/svi806.rom"},
{"md5": "", "file": "bios/Machines/Turbo-R/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - Philips VG-8240/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Russian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Russian/hardwareconfig.xml"},
{"md5": "", "file": "bios/Machines/MSX2 - Sanyo Wavy MPC-25FD/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sanyo Wavy PHC-23/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sharp Epcom HotBit 2.0/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F1/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F1II/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F1XD/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F1XDMK2/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F500/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F500P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F700D/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F700F/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F700P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F700S/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F900/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F900 (a)/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F9P/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F9P Russian/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F9S/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-G900AP/config.ini"},
{"md5": "", "file": "bios/Machines/MSX2 - Sony HB-G900P/config.ini"}]},
# NEC
"pcengine": {"name": "PC Engine", "biosFiles": [{"md5": "38179df8f4ac870017db21ebcbf53114;ff1a674273fe3540ccef576376407d1d", "file": "bios/syscard3.pce"}]},
"pcfx": {"name": "PC-FX", "biosFiles": [{"md5": "08e36edbea28a017f79f8d4f7ff9b6d7", "file": "bios/pcfx.rom"}]},
"supergrafx": {"name": "Supergrafx", "biosFiles": [{"md5": "38179df8f4ac870017db21ebcbf53114;ff1a674273fe3540ccef576376407d1d", "file": "bios/syscard3.pce"},
{"md5": "", "file": "bios/syscard2.pce"},
{"md5": "", "file": "bios/syscard1.pce"},
{"md5": "", "file": "bios/gexpress.pce"}]},
"pc88": {"name": "NEC - PC-8800", "biosFiles": [{"md5": "", "file": "bios/quasi88/DISK.ROM"},
{"md5": "", "file": "bios/quasi88/N88.ROM"},
{"md5": "", "file": "bios/quasi88/N88N.ROM"},
{"md5": "", "file": "bios/quasi88/N88_0.ROM"},
{"md5": "", "file": "bios/quasi88/N88_1.ROM"},
{"md5": "", "file": "bios/quasi88/N88_2.ROM"},
{"md5": "", "file": "bios/quasi88/N88_3.ROM"},
{"md5": "", "file": "bios/quasi88/N88_KNJ1.ROM"},
{"md5": "", "file": "bios/quasi88/N88_KNJ2.ROM"}]},
# Nintendo
"fds": {"name": "Nintendo Family Computer Disk System", "biosFiles": [{"md5": "", "file": "bios/NstDatabase.xml"},
{"md5": "ca30b50f880eb660a320674ed365ef7a", "file": "bios/disksys.rom"}]},
"gb": {"name": "Game Boy", "biosFiles": [{"md5": "32fbbd84168d3482956eb3c5051637f5", "file": "bios/gb_bios.bin"},
{"md5": "dbfce9db9deaa2567f6a84fde55f9680", "file": "bios/gbc_bios.bin"}]},
"gbc": {"name": "Game Boy Color", "biosFiles": [{"md5": "32fbbd84168d3482956eb3c5051637f5", "file": "bios/gb_bios.bin"},
{"md5": "dbfce9db9deaa2567f6a84fde55f9680", "file": "bios/gbc_bios.bin"}]},
"gba": {"name": "Game Boy Advance", "biosFiles": [{"md5": "a860e8c0b6d573d191e4ec7db1b1e4f6", "file": "bios/gba_bios.bin"},
{"md5": "32fbbd84168d3482956eb3c5051637f5", "file": "bios/gb_bios.bin"},
{"md5": "dbfce9db9deaa2567f6a84fde55f9680", "file": "bios/gbc_bios.bin"},
{"md5": "d574d4f9c12f305074798f54c091a8b4", "file": "bios/sgb_bios.bin"}]},
"n64": {"name": "Nintendo 64", "biosFiles": [{"md5": "8d3d9f294b6e174bc7b1d2fd1c727530", "file": "bios/64DD_IPL.bin"}]},
"nds": {"name": "Nintendo DS", "biosFiles": [{"md5": "145eaef5bd3037cbc247c213bb3da1b3", "file": "bios/firmware.bin"},
{"md5": "df692a80a5b1bc90728bc3dfc76cd948", "file": "bios/bios7.bin"},
{"md5": "a392174eb3e572fed6447e956bde4b25", "file": "bios/bios9.bin"}]},
"satellaview": {"name": "Satellaview", "biosFiles": [{"md5": "fed4d8242cfbed61343d53d48432aced;96cf17bf589fcbfa6f8de2dc84f19fa2", "file": "bios/BS-X.bin"}]},
"sufami": {"name": "Sufami", "biosFiles": [{"md5": "d3a44ba7d42a74d3ac58cb9c14c6a5ca", "file": "bios/STBIOS.bin"}]},
# Panasonic, Sanyo and Goldstar
"3do": {"name": "3DO", "biosFiles": [{"md5": "f47264dd47fe30f73ab3c010015c155b", "file": "bios/panafz1.bin"},
{"md5": "51f2f43ae2f3508a14d9f56597e2d3ce", "file": "bios/panafz10.bin"},
{"md5": "8639fd5e549bd6238cfee79e3e749114", "file": "bios/goldstar.bin"},
{"md5": "35fa1a1ebaaeea286dc5cd15487c13ea", "file": "bios/sanyotry.bin"},
{"md5": "8970fc987ab89a7f64da9f8a8c4333ff", "file": "bios/3do_arcade_saot.bin"}]},
# Sega
"naomi": {"name": "Naomi", "biosFiles": [{"md5": "3bffafac42a7767d8dcecf771f5552ba", "file": "bios/dc/naomi_boot.bin"},
{"md5": "e63d892cdb8b532351dc7020bb60b6f4", "file": "bios/dc/naomi.zip"}]},
"atomiswave": {"name": "Atomiswave", "biosFiles": [{"md5": "0ec5ae5b5a5c4959fa8b43fcf8687f7c", "file": "bios/dc/awbios.zip"}]},
"dreamcast": {"name": "Dreamcast", "biosFiles": [{"md5": "e10c53c2f8b90bab96ead2d368858623", "file": "bios/dc/dc_boot.bin"},
{"md5": "0a93f7940c455905bea6e392dfde92a4", "file": "bios/dc/dc_flash.bin"}]},
"gamegear": {"name": "Game Gear", "biosFiles": [{"md5": "672e104c3be3a238301aceffc3b23fd6", "file": "bios/bios.gg"}]},
"mastersystem": {"name": "MasterSystem", "biosFiles": [{"md5": "840481177270d5642a14ca71ee72844c", "file": "bios/bios_E.sms"},
{"md5": "840481177270d5642a14ca71ee72844c", "file": "bios/bios_U.sms"},
{"md5": "24a519c53f67b00640d0048ef7089105", "file": "bios/bios_J.sms"}]},
"saturn": {"name": "Sega Saturn", "biosFiles": [{"md5": "af5828fdff51384f99b3c4926be27762", "file": "bios/saturn_bios.bin"},
{"md5": "85ec9ca47d8f6807718151cbcca8b964", "file": "bios/sega_101.bin"},
{"md5": "3240872c70984b6cbfda1586cab68dbe", "file": "bios/mpr-17933.bin"},
{"md5": "255113ba943c92a54facd25a10fd780c", "file": "bios/mpr-18811-mx.ic1"},
{"md5": "1cd19988d1d72a3e7caa0b73234c96b4", "file": "bios/mpr-19367-mx.ic1"},
{"md5": "53a094ad3a188f86de4e64624fe9b3ca", "file": "bios/stvbios.zip"}]},
"segacd": {"name": "Sega CD", "biosFiles": [{"md5": "e66fa1dc5820d254611fdcdba0662372", "file": "bios/bios_CD_E.bin"},
{"md5": "854b9150240a198070150e4566ae1290", "file": "bios/bios_CD_U.bin"},
{"md5": "278a9397d192149e84e820ac621a8edd", "file": "bios/bios_CD_J.bin"}]},
"sc-3000": {"name": "SC-3000", "biosFiles": [{"md5": "", "file": "bios/Machines/SEGA - SC-3000/config.ini"}]},
# Sharp
"x68000": {"name": "Sharp x68000", "biosFiles": [{"md5": "", "file": "bios/keropi/iplrom.dat"},
{"md5": "", "file": "bios/keropi/iplrom30.dat"},
{"md5": "", "file": "bios/keropi/iplromco.dat"},
{"md5": "", "file": "bios/keropi/iplromxv.dat"},
{"md5": "", "file": "bios/keropi/cgrom.dat"}]},
"x1": {"name": "Sharp X1", "biosFiles": [{"md5": "eeeea1cd29c6e0e8b094790ae969bfa7", "file": "bios/xmil/IPLROM.X1"},
{"md5": "851e4a5936f17d13f8c39a980cf00d77", "file": "bios/xmil/IPLROM.X1T"}]},
# SNK
"neogeo": {"name": "NeoGeo", "biosFiles": [{"md5": "", "file": "neogeo/neogeo.zip"}]},
"neogeocd": {"name": "NeoGeo CD", "biosFiles": [{"md5": "", "file": "neogeo/neogeo.zip"},
{"md5": "", "file": "bios/neocdz.zip"},
{"md5": "e255264d85d5765013b1b2fa8109dd53", "file": "bios/neocd/ng-lo.rom"},
{"md5": "f39572af7584cb5b3f70ae8cc848aba2", "file": "bios/neocd/neocd_z.rom"}]},
# Sony Computer Entertainment
"psx": {"name": "PSX", "biosFiles": [{"md5": "8dd7d5296a650fac7319bce665a6a53c", "file": "bios/scph5500.bin"},
{"md5": "490f666e1afb15b7362b406ed1cea246", "file": "bios/scph5501.bin"},
{"md5": "32736f17079d0b2b7024407c39bd3050", "file": "bios/scph5502.bin"}]},
# Sinclair
"zxspectrum": {"name": "ZX Spectrum", "biosFiles": [{"md5": "", "file": "bios/128p-0.rom"},
{"md5": "", "file": "bios/128p-1.rom"},
{"md5": "", "file": "bios/trdos.rom"},
{"md5": "", "file": "bios/gluck.rom"},
{"md5": "", "file": "bios/256s-0.rom"},
{"md5": "", "file": "bios/256s-1.rom"},
{"md5": "", "file": "bios/256s-2.rom"},
{"md5": "", "file": "bios/256s-3.rom"}]},
}
class BiosStatus:
MISSING = "MISSING"
UNTESTED = "UNTESTED"
def md5sum(filename, blocksize=65536):
hash = md5()
with open(filename, "rb") as f:
for block in iter(lambda: f.read(blocksize), b""):
hash.update(block)
return hash.hexdigest()
def checkBios(systems, prefix):
missingBios = {}
for system in systems.keys():
for file in systems[system]["biosFiles"]:
x = 0
filepath = prefix + "/" + file["file"]
if ";" in file["md5"]:
filehashes = file["md5"].split(";")
else:
filehashes = (file["md5"],)
if isfile(filepath):
md5 = md5sum(filepath)
if md5 not in filehashes and file["md5"] != "":
if system not in missingBios:
missingBios[system] = {}
for filehash in filehashes:
x += 1
missingBios[system][file["file"]+"(hash%s)" % x] = {"status": BiosStatus.UNTESTED, "md5": filehash, "file": file["file"]}
else:
if system not in missingBios:
missingBios[system] = {}
for filehash in filehashes:
x += 1
missingBios[system][file["file"]+"(hash%s)" % x] = {"status": BiosStatus.MISSING, "md5": filehash, "file": file["file"]}
return missingBios
# Returns True if missing, False if nothing is missing
def displayMissingBios(systems, missingBios):
sortedMissingBios = OrderedDict(sorted(missingBios.items()))
if sortedMissingBios:
for system in sortedMissingBios:
print("> {}".format(systems[system]["name"]))
for file in sortedMissingBios[system].keys():
md5str = "-"
if sortedMissingBios[system][file]["md5"] != "":
md5str = sortedMissingBios[system][file]["md5"]
print("{} {} {}".format(sortedMissingBios[system][file]["status"], md5str, sortedMissingBios[system][file]["file"]))
return True
else:
print("No missing bios")
return False
def createReadme(systems):
for system in sorted(systems):
print("{}:".format(systems[system]["name"]))
for bios in systems[system]["biosFiles"]:
if ";" in bios["md5"]:
filehashes = bios["md5"].split(";")
else:
filehashes = (bios["md5"],)
for filehash in filehashes:
print("{:32} {}".format(filehash, "/storage/roms/" + bios["file"]))
print("")
if __name__ == '__main__':
if len(sys.argv) == 1:
prefix = "/storage/roms/"
if displayMissingBios(systems, checkBios(systems, prefix)):
exit(2)
elif sys.argv[1] == "--createReadme":
createReadme(systems)
elif len(sys.argv) == 3 and sys.argv[1] in ["--filter", "--strictfilter"]:
prefix = "/storage/roms/"
lowered_name = sys.argv[2].lower()
filtered_systems = {}
for system in systems:
lowered_system = system.lower()
lowered_system_name = systems[system]['name'].lower()
if ((lowered_name == lowered_system or lowered_name == lowered_system_name) or
(sys.argv[1] == "--filter" and (lowered_name in lowered_system or lowered_name in lowered_system_name))):
filtered_systems[system] = systems[system]
if len(filtered_systems) == 0:
print("No system named {} found".format(sys.argv[2]))
exit(1)
if displayMissingBios(filtered_systems, checkBios(filtered_systems, prefix)):
exit(2)

View file

@ -0,0 +1,112 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
if [ ! "${HW_ARCH}" = "x86_64" ]
then
echo "This platform is not currently supported."
exit 1
fi
HOSTNAME=$(hostname)
if [ -z "${1}" ]
then
BENCHLOG="${1}"
else
BENCHLOG="benchmark.log"
fi
LOG="${HOME}/${BENCHLOG}.log"
SYSTEM_TDP=$(get_setting system.overclock)
SYSTEM_GOV=$(get_setting system.cpugovernor)
SYSTEM_EPP=$(get_setting system.power.epp)
SYSTEM_GPU=$(get_setting system.gpuperf)
SYSTEM_THREADS=$(get_setting system.threads)
SYSTEM_POWERSAVE=$(get_setting system.powersave)
SYSTEM_COOLING=$(get_setting cooling.profile)
case ${1} in
performance)
onlinethreads all
performance
gpu_performance_level profile_peak
cpu_perftune performance
set_setting system.powersave 0
systemctl restart powerstate
set_setting cooling.profile auto
systemctl restart fancontrol
;;
balanced_performance)
onlinethreads all
schedutil
gpu_performance_level auto
cpu_perftune balance_performance
set_setting system.powersave 0
systemctl restart powerstate
set_setting cooling.profile auto
systemctl restart fancontrol
;;
balanced_powersave)
onlinethreads 4
powersave
gpu_performance_level low
cpu_perftune balance_power
set_setting system.powersave 1
systemctl restart powerstate
set_setting cooling.profile quiet
systemctl restart fancontrol
;;
powersave)
onlinethreads 4
powersave
gpu_performance_level low
cpu_perftune power
set_setting system.powersave 1
systemctl restart powerstate
set_setting cooling.profile quiet
systemctl restart fancontrol
;;
*)
# Default Settings
onlinethreads all
schedutil
gpu_performance_level auto
cpu_perftune balance_performance
set_setting system.powersave 0
systemctl restart powerstate
set_setting cooling.profile auto
systemctl restart fancontrol
;;
esac
if [ -e "${LOG}" ]
then
rm -f ${LOG}
fi
echo "${HOSTNAME} - ${1}"
for TDP in 4.5w 6w 9w 15w 18w 24w 28w
do
overclock ${TDP} >/dev/null 2>&1
echo "Testing @ ${TDP}" 2>&1 | tee -a ${LOG}
echo "----" 2>&1 | tee -a ${LOG}
glmark2-es2-wayland --fullscreen --annotate 2>&1 | awk '/glmark2 Score:/ {print "GLMark: "$3}' | tee -a ${LOG}
cd /usr/bin
./7z b 2>&1 | awk '/^Tot:/ {print "7z: "$4}' | tee -a ${LOG}
echo "----" 2>&1 | tee -a ${LOG}
done
overclock ${SYSTEM_TDP}
onlinethreads ${SYSTEM_THREADS}
${SYSTEM_GOV}
gpu_performance_level ${SYSTEM_GPU}
cpu_perftune ${SYSTEM_EPP}
set_setting system.powersave ${SYSTEM_POWERSAVE}
systemctl restart powerstate
set_setting cooling.profile ${SYSTEM_COOLING}
systemctl restart fancontrol

View file

@ -0,0 +1,217 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2019-present SumavisionQ5 (https://github.com/SumavisionQ5)
# Modifications by Shanti Gilbert (https://github.com/shantigilbert)
PLATFORM="$1"
ROMNAME=$(basename "${2%.*}")
RACONFIG="/storage/.config/retroarch/retroarch.cfg"
OPACITY="1.000000"
AR_INDEX="23"
BEZELDIR="/storage/roms/bezels"
INIFILE="/storage/.config/system/bezels/settings.ini"
DEFAULT_BEZEL="false"
case $PLATFORM in
"arcade"|"fba"|"fbn"|"neogeo"|"mame"|cps*)
PLATFORM="ARCADE"
;;
"default")
if [ -f "/storage/.config/bezels_enabled" ]; then
clear_bezel
sed -i '/input_overlay = "/d' $RACONFIG
rm "/storage/.config/bezels_enabled"
fi
exit 0
;;
"RETROPIE")
# fbterm does not need bezels
exit 0
;;
esac
if [ ! -f "/storage/.config/bezels_enabled" ]; then
touch /storage/.config/bezels_enabled
fi
# we make sure the platform is all lowercase
PLATFORM=${PLATFORM,,}
# if a backup does not exists make a copy of retroarch.cfg so we can return to it when we disable bezels
# for future use...maybe
#if [ ! -f "$RACONFIG.org" ]; then
# cp "$RACONFIG" "$RACONFIG.org"
#fi
# bezelmap.cfg in $BEZELDIR/ is to share bezels between arcade clones and parent.
BEZELMAP="/storage/.config/system/bezels/arcademap.cfg"
BZLNAME=$(sed -n "/"$PLATFORM"_"$ROMNAME" = /p" "$BEZELMAP")
BZLNAME="${BZLNAME#*\"}"
BZLNAME="${BZLNAME%\"*}"
OVERLAYDIR1=$(find $BEZELDIR/$PLATFORM -maxdepth 1 -iname "$ROMNAME*.cfg" | sort -V | head -n 1)
[ ! -z "$BZLNAME" ] && OVERLAYDIR2=$(find $BEZELDIR/$PLATFORM -maxdepth 1 -iname "$BZLNAME*.cfg" | sort -V | head -n 1)
OVERLAYDIR3="$BEZELDIR/$PLATFORM/default.cfg"
clear_bezel() {
sed -i '/aspect_ratio_index = "/d' $RACONFIG
sed -i '/custom_viewport_width = "/d' $RACONFIG
sed -i '/custom_viewport_height = "/d' $RACONFIG
sed -i '/custom_viewport_x = "/d' $RACONFIG
sed -i '/custom_viewport_y = "/d' $RACONFIG
sed -i '/video_scale_integer = "/d' $RACONFIG
sed -i '/input_overlay_opacity = "/d' $RACONFIG
echo 'video_scale_integer = "false"' >> $RACONFIG
echo 'input_overlay_opacity = "0.150000"' >> $RACONFIG
}
set_bezel() {
# $OPACITY: input_overlay_opacity
# ${AR}_INDEX: aspect_ratio_index
# $1: custom_viewport_width
# $2: custom_viewport_height
# $3: ustom_viewport_x
# $4: custom_viewport_y
# $5: video_scale_integer
# $6: video_scale
clear_bezel
sed -i '/input_overlay_opacity = "/d' $RACONFIG
sed -i "1i input_overlay_opacity = \"$OPACITY\"" $RACONFIG
sed -i "2i aspect_ratio_index = \"${AR}_INDEX\"" $RACONFIG
sed -i "3i custom_viewport_width = \"$1\"" $RACONFIG
sed -i "4i custom_viewport_height = \"$2\"" $RACONFIG
sed -i "5i custom_viewport_x = \"$3\"" $RACONFIG
sed -i "6i custom_viewport_y = \"$4\"" $RACONFIG
sed -i "7i video_scale_integer = \"$5\"" $RACONFIG
}
check_overlay_dir() {
# The bezel will be searched and used in following order:
# 1.$OVERLAYDIR1 will be used, if it does not exist, then
# 2.$OVERLAYDIR2 will be used, if it does not exist, then
# 3.$OVERLAYDIR2 platform default bezel as "$BEZELDIR/"$PLATFORM"/default.cfg\" will be used.
# 4.Default bezel at "$BEZELDIR/default.cfg\" will be used.
sed -i '/input_overlay = "/d' $RACONFIG
if [ -f "$OVERLAYDIR1" ]; then
echo -e "input_overlay = \""$OVERLAYDIR1"\"\n" >> $RACONFIG
elif [ -f "$OVERLAYDIR2" ]; then
echo -e "input_overlay = \""$OVERLAYDIR2"\"\n" >> $RACONFIG
elif [ -f "$OVERLAYDIR3" ]; then
echo -e "input_overlay = \""$OVERLAYDIR3"\"\n" >> $RACONFIG
else
echo -e "input_overlay = \"$BEZELDIR/default.cfg\"\n" >> $RACONFIG
DEFAULT_BEZEL="true"
fi
}
# Only 720P and 1080P can use bezels. For 480p/i and 576p/i we just delete bezel config.
hdmimode=$(cat /sys/class/display/mode)
case $hdmimode in
480*)
sed -i '/input_overlay = "/d' $RACONFIG
clear_bezel
;;
576*)
sed -i '/input_overlay = "/d' $RACONFIG
clear_bezel
;;
720p*)
check_overlay_dir "$PLATFORM"
case "$PLATFORM" in
"gba")
set_bezel "467" "316" "405" "190" "false"
;;
"gamegear")
set_bezel "780" "580" "245" "70" "false"
;;
"gb")
set_bezel "429" "380" "420" "155" "false"
;;
"gbc")
set_bezel "430" "380" "425" "155" "false"
;;
"ngp")
set_bezel "461" "428" "407" "145" "false"
;;
"ngpc")
set_bezel "460" "428" "407" "145" "false"
;;
"wonderswan")
set_bezel "645" "407" "325" "150" "false"
;;
"wonderswancolor")
set_bezel "643" "405" "325" "150" "false"
;;
*)
# delete aspect_ratio_index to make sure video is expanded fullscreen. Only certain AMD64 platforms need custom_viewport.
clear_bezel
sed -i '/input_overlay_opacity = "/d' $RACONFIG
sed -i "1i input_overlay_opacity = \"$OPACITY\"" $RACONFIG
;;
esac
;;
# For Amlogic TV box, the following resolution is 1080p/i.
1080*)
check_overlay_dir "$PLATFORM"
case "$1" in
"gba")
set_bezel "698" "472" "609" "288" "false"
;;
"gamegear")
set_bezel "1160" "850" "380" "120" "false"
;;
"gb")
set_bezel "625" "565" "645" "235" "false"
;;
"gbc")
set_bezel "625" "565" "645" "235" "false"
;;
"ngp")
set_bezel "700" "635" "610" "220" "false"
;;
"ngpc")
set_bezel "700" "640" "610" "215" "false"
;;
"wonderswan")
set_bezel "950" "605" "490" "225" "false"
;;
"wonderswancolor")
set_bezel "950" "605" "490" "225" "false"
;;
*)
clear_bezel
sed -i '/input_overlay_opacity = "/d' $RACONFIG
sed -i "1i input_overlay_opacity = \"$OPACITY\"" $RACONFIG
;;
esac
;;
esac
if [ "$DEFAULT_BEZEL" = "true" ]; then
set_bezel "1427" "1070" "247" "10" "false"
fi
# If we disable bezel in setting.ini for certain platform, we just delete bezel config.
Bezel=$(sed -n "/"$PLATFORM"_Bezel = /p" $INIFILE)
Bezel="${Bezel#*\"}"
Bezel="${Bezel%\"*}"
if [ "$Bezel" = "OFF" ]; then
sed -i '/input_overlay = "/d' $RACONFIG
fi
# Note:
# 1. Different AMD64 platforms have different bezels, they may need different viewport value even for same platform.
# So, I think this script should be stored in $BEZELDIR/ or some place wich can be modified by users.
# 2. For Arcade games, I created a bezelmap.cfg in $BEZELDIR/ in order to share bezels between arcade clones and parent.
# In fact, ROMs of other platforms can share certain bezel if you write mapping relationship in bezelmap.cfg.
# 3. I modified es_systems.cfg to set $1 as platfrom for all platfrom.
# For some libretro core such as <command>/usr/bin/sx05reRunEmu.sh LIBRETRO scummvm %ROM%</command>, $1 not right platform value,
# you may need some tunings on them.
# 4. I am a Linux noob, so the codes are a mess. Sorry for that:)

View file

@ -0,0 +1,90 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
## Load minimal distribution settings to improve
## performance.
. /etc/profile.d/001-functions
BRIGHTNESS_DEV="$(find /sys/class/backlight/*/ -name brightness -print -quit 2>/dev/null)"
BRIGHTNESS_PATH="${BRIGHTNESS_DEV%/brightness}"
declare -a BRIGHTNESS_TABLE
BRIGHTNESS_TABLE=($(get_setting brightness_table))
if [ -z ${BRIGHTNESS_TABLE} ]; then
BRIGHTNESS_TABLE=(0 0.04 0.08 0.13 0.19 0.25 0.33 0.42 0.54 0.71 1)
set_setting brightness_table "${BRIGHTNESS_TABLE[*]}"
fi
NUM_STEPS=${#BRIGHTNESS_TABLE[@]}
MAX=$(<$(find /sys/class/backlight/*/ -name max_brightness -print -quit 2>/dev/null))
function compute() {
echo "${BRIGHTNESS_TABLE[$NEXT]} * ${MAX}" | bc -l
}
if [ ! -f "${BRIGHTNESS_DEV}" ]
then
echo "ERROR: There is no BRIGHTNESS object to manage."
exit 1
fi
getBrightness() {
echo $(<${BRIGHTNESS_DEV})
}
setBrightness() {
echo "${1}" > ${BRIGHTNESS_DEV}
set_setting system.brightness "${2}"
}
stepUp() {
CURRENT=$(get_setting system.brightness)
NEXT=$(( ${CURRENT} + 1 ))
if (( ${NEXT} >= $NUM_STEPS ))
then
NEXT=$(( $NUM_STEPS - 1 ))
fi
BRIGHTNESS=$(printf '%.0f' "$(compute)")
if (($BRIGHTNESS > $MAX ))
then
BRIGHTNESS=$MAX
fi
setBrightness ${BRIGHTNESS} ${NEXT}
}
stepDown() {
CURRENT=$(get_setting system.brightness)
NEXT=$(( ${CURRENT} - 1 ))
if (( ${NEXT} < 0 ))
then
NEXT=0
fi
BRIGHTNESS=$(printf '%.0f' "$(compute)")
setBrightness ${BRIGHTNESS} ${NEXT}
}
case ${1} in
"up")
stepUp
;;
"down")
stepDown
;;
"device")
echo ${BRIGHTNESS_DEV}
;;
"path")
echo ${BRIGHTNESS_PATH}
;;
"set")
NEXT=${2}
setBrightness "$(printf '%.0f' "$(compute)")" ${2}
;;
*)
echo $(getBrightness)
;;
esac

View file

@ -0,0 +1,39 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
CFG_PATH="/storage/.config/system/configs"
backup() {
TYPE=$(grep a ${CFG_PATH}/system.cfg 2>&1)
if [[ ! "${TYPE}" =~ binary ]]
then
cp ${CFG_PATH}/system.cfg ${CFG_PATH}/system.cfg.backup
fi
}
restore() {
cp ${CFG_PATH}/system.cfg.backup ${CFG_PATH}/system.cfg
}
verify() {
TYPE=$(grep a ${CFG_PATH}/system.cfg 2>&1)
if [[ "${TYPE}" =~ binary ]]
then
restore
fi
}
case ${1} in
verify)
verify
;;
backup)
backup
;;
restore)
restore
;;
esac

View file

@ -0,0 +1,11 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
for STORAGE in /storage/games-internal /storage/games-external
do
find ${STORAGE} -type d -empty -delete
done
reboot

View file

@ -0,0 +1,19 @@
#!/usr/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2021-present 351ELEC
. /etc/profile
clear
if [ -n "$1" ]
then
text_viewer -w -e -t "BIOS ERROR" -m "$*"
else
ERROR=$(tail -n 25 /var/log/es_launch_stderr.log)
if [ !-z "${ERROR}" ];
then
text_viewer -w -e -t ERROR -m "${ERROR}"
fi
fi
clear

View file

@ -0,0 +1,39 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert)
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
case "${1}" in
"retroarch")
rm -f /storage/.config/retroarch/retroarch.cfg
cp -rf /usr/config/retroarch/retroarch.cfg /storage/.config/retroarch/retroarch.cfg
;;
"retroarch-full")
rm -rf /storage/.config/retroarch
cp -rf /usr/config/retroarch /storage/.config/
;;
"mednafen")
rm -f /storage/.config/mednafen/mednafen.cfg
;;
"overlays")
rm -rf $(cat /usr/lib/systemd/system/tmp-*.mount | grep -Eo 'upperdir=.*,' | sed -e 's~upperdir=~~g; s~,~~g')
sync
systemctl reboot
;;
"audio")
systemctl stop pipewire-pulse pipewire-pulse.socket pipewire pipewire.socket wireplumber
rm -rf /storage/.local/state /storage/.config/pulse /storage/asound*
systemctl reboot
;;
"ALL")
swapoff -a 2>/dev/null
umount /storage/roms 2>/dev/null ||:
umount /storage/games-external 2>/dev/null ||:
cd /
find /storage -mindepth 1 \( ! -regex '^/storage/.update.*' -a ! -regex '^/storage/roms.*' -a ! -regex '^/storage/games-.*' \) -delete 2>/dev/null
mkdir /storage/.config/
sync 2>/dev/null
systemctl reboot
;;
esac

View file

@ -0,0 +1,6 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert)
find / -type d \( -path /var/media -o -path /storage/roms \) -prune -o -iname *${1}* -print

View file

@ -0,0 +1,11 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert)
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
find /usr/share/retroarch/filters/64bit/video/ -name '*.filt' -print0 |
while IFS= read -r -d '' line; do
echo ${line#/usr/share/retroarch/filters/64bit/video/},
done | sort

View file

@ -0,0 +1,12 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert)
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
find /storage/overlays/ -name '*.cfg' -print0 |
while IFS= read -r -d '' line; do
echo ${line#/storage/overlays/},
done | sort

View file

@ -0,0 +1,23 @@
#!/bin/bash
. /etc/profile
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020-present Shanti Gilbert (https://github.com/shantigilbert)
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
if [ -z "$UI_SHADER" ]; then
option=".*\.\(glslp\|slangp\)$"
else
option=".*\.\($UI_SHADER\)$"
fi
for dir in /tmp/shaders
do
if [ -d "${dir}" ]; then
find ${dir} -regex "${option}" -print0 |
while IFS= read -r -d '' line; do
echo ${line#${dir}/},
done | sort
fi
done

View file

@ -0,0 +1,140 @@
#!/bin/bash
source /etc/profile
### Apply device quirks
if [ -e "/sys/firmware/devicetree/base/model" ]
then
export QUIRK_DEVICE="$(tr -d '\0' </sys/firmware/devicetree/base/model 2>/dev/null)"
else
export QUIRK_DEVICE="$(tr -d '\0' </sys/class/dmi/id/sys_vendor 2>/dev/null) $(tr -d '\0' </sys/class/dmi/id/product_name 2>/dev/null)"
fi
export QUIRK_DEVICE="$(echo ${QUIRK_DEVICE} | sed -e "s#[/]#-#g")"
info_quirks() {
for QUIRK in /usr/lib/autostart/quirks/platforms/"${HW_DEVICE}"/info.d/${1}/* \
/usr/lib/autostart/quirks/devices/"${QUIRK_DEVICE}"/info.d/${1}/*
do
"${QUIRK}" 2>/dev/null
done
}
### short version (for osd)
if test "$1" = "--short"
then
BATT=$(awk 'BEGIN {FS="="} /POWER_SUPPLY_CAPACITY=/ {print $2; exit}' /sys/class/power_supply/{BAT,bat}*/uevent 2>/dev/null)
DT=$(date +%H:%M)
if test -n "${BATT}"
then
echo "Battery: ${BATT}% - ${DT}"
else
echo "${DT}"
fi
exit 0
fi
###
V_CPUNB=$(grep -E $'^processor\t:' /proc/cpuinfo | wc -l)
V_CPUMODEL1=$(grep -E $'^model name\t:' /proc/cpuinfo | head -1 | sed -e s+'^model name\t: '++)
V_SYSTEM=$(uname -rs)
V_ARCH=$(uname -m)
[[ "$V_CPUMODEL1" ]] || V_CPUMODEL1="${HW_CPU}"
# battery
BATT=$(awk 'BEGIN {FS="="} /POWER_SUPPLY_CAPACITY=/ {print $2; exit}' /sys/class/power_supply/{BAT,bat}*/uevent 2>/dev/null)
case ${HW_ARCH} in
aarch64)
declare -a CF MF
CNTR=0
for CPUFREQ in /sys/devices/system/cpu/cpufreq/*
do
if [[ "${CPUFREQ}" =~ boost ]]
then
continue
fi
if [ "${CNTR}" -eq 0 ]
then
CF+=("CURRENT FREQUENCY:")
MF+=("MAXIMUM FREQUENCY:")
fi
RELCPUS=$(cat ${CPUFREQ}/related_cpus 2>/dev/null)
if [ "${#RELCPUS}" -gt 1 ]
then
FIELD="$(cat ${CPUFREQ}/related_cpus 2>/dev/null | awk '{print $1"-"$NF}')"
else
FIELD="$(cat ${CPUFREQ}/related_cpus 2>/dev/null)"
fi
CF+=("THREADS ${FIELD}: $(( $(cat ${CPUFREQ}/scaling_cur_freq 2>/dev/null | sort | tail -n 1) / 1000))MHz")
MF+=("THREADS ${FIELD}: $(( $(cat ${CPUFREQ}/scaling_max_freq 2>/dev/null | sort | tail -n 1) / 1000))MHz")
CNTR=$(( CNTR + 1 ))
done
;;
esac
echo "SYSTEM INFORMATION:"
echo "DEVICE: ${QUIRK_DEVICE}"
echo "OPERATING SYSTEM: ${OS_NAME}"
echo "VERSION: ${OS_VERSION}"
echo "BUILD ID: ${BUILD_ID:0:7} (${BUILD_BRANCH})"
echo "KERNEL: ${V_SYSTEM} ($(uname -m))"
echo "DISK SPACE:"
echo "/storage: $(df -h /storage | awk '/dev/ {print $3"/"$2" ("$5")"}')"
echo "/storage/games-internal: $(df -h /storage/games-internal | awk '/dev/ {print $3"/"$2" ("$5")"}')"
echo "/storage/games-external: $(df -h /storage/games-external | awk '/dev/ {print $3"/"$2" ("$5")"}')"
if test -n "${BATT}"
then
echo "BATTERY INFORMATION:"
echo "BATTERY REMAINING: ${BATT}%"
BATPATH="/sys/class/power_supply/$(ls /sys/class/power_supply/ | grep -i bat | tail -n 1)"
if [ -e "${BATPATH}/health" ]
then
echo "BATTERY HEALTH: $(cat ${BATPATH}/health)"
fi
if [ -e "${BATPATH}/status" ]
then
echo "BATTERY STATE: $(cat ${BATPATH}/status)"
fi
fi
echo "CPU INFORMATION:"
echo "CPU: ${V_CPUMODEL1} (${V_CPUNB} Cores)"
# temperature
# Unit: millidegree Celsius
if [ -n "${DEVICE_TEMP_SENSOR}" ]
then
TEMPE=$(printf "%.0f" $(awk '{ total += $1; count++ } END { print total/count }' ${DEVICE_TEMP_SENSOR} 2>/dev/null) 2>/dev/null | sed -e s+"[0-9][0-9][0-9]$"++)
if [ -n "${TEMPE}" ]
then
echo "CPU TEMPERATURE: ${TEMPE}°"
fi
fi
if [ "${DEVICE_HAS_FAN}" = "true" ]
then
FANSPEED=$(cat ${DEVICE_FAN_INPUT} 2>/dev/null)
if [ "${FANSPEED}" = "0" ]
then
FANSPEED="OFF"
else
FANSPEED="${FANSPEED} RPM"
fi
echo "CPU FAN: ${FANSPEED}"
fi
case ${HW_ARCH} in
aarch64)
for C in "${CF[@]}"
do
echo ${C}
done
for M in "${MF[@]}"
do
echo ${M}
done
;;
esac
info_quirks

View file

@ -0,0 +1,42 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
COLOR=$(get_setting led.color)
BRI=$(get_setting led.brightness)
if [ -z "${COLOR}" ] || \
[ "${COLOR}" = "off" ] || \
[ -n "${DEVICE_LED_CHARGING}" ]
then
FLASH_COLOR="red"
else
FLASH_COLOR="${COLOR}"
fi
if [ "${DEVICE_LED_BRIGHTNESS}" = "true" ]
then
ledcontrol brightness mid
fi
for i in $(seq 1 1 3)
do
ledcontrol ${FLASH_COLOR}
sleep .5
ledcontrol poweroff
sleep .5
done
if [ -n "${COLOR}" ]
then
ledcontrol ${COLOR}
else
ledcontrol default
fi
if [ "${DEVICE_LED_BRIGHTNESS}" = "true" ]
then
ledcontrol brightness ${BRI}
fi

View file

@ -0,0 +1,36 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
LOGFILE="/var/log/migrate.log"
read -p "WARNING: This tool can cause data loss... Make sure you have a backup before proceeding... Press control-c now to cancel, or any other key to continue..."
for GAMES in /storage/games-internal /storage/games-external
do
echo "Working on ${GAMES}..."
if [ ! -d "${GAMES}/roms" ]
then
echo "Making ${GAMES}/roms..."
mkdir -p "${GAMES}/roms" >>${LOGFILE} 2>&1 1|>>${LOGFILE}
fi
for DIR in $(find "${GAMES}/" -type d -maxdepth 1 -mindepth 1 2>/dev/null)
do
TARGET_DIR=$(basename ${DIR})
echo "Working on ${DIR}..."
if [[ "${DIR}" =~ roms$ ]]
then
continue
fi
if [ ! -d "${GAMES}/roms/${TARGET_DIR}" ]
then
echo "Making ${GAMES}/roms/${TARGET_DIR}..."
mkdir -p "${GAMES}/roms/${TARGET_DIR}" >>${LOGFILE} 2>&1
fi
mv "${DIR}"/* "${GAMES}/roms/${TARGET_DIR}" >>${LOGFILE} 2>&1
rsync -av --remove-source-files "${DIR}"/* "${GAMES}/roms/${TARGET_DIR}" >>${LOGFILE} 2>&1
done
echo "Clean empties in ${GAMES}..."
find "${GAMES}" -type d -empty -delete >>${LOGFILE} 2>&1 1|>>${LOGFILE}
echo "Your games have been migrated, however you will need to manually clean up stale directories. Please reboot your system now by running the `reboot` command."
done

View file

@ -0,0 +1,104 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
# ARGS:
#
# 1 - property to adjust (gamma (brightness)/contrast/saturation/hue)
# 2 - up/down or a defined value
PROPERTY=${1}
NEWVAL=${2}
# Command usage:
# drm_tool set /dev/dri/card0 133 saturation value
# Define the basics
MIN=1
MAX=100
STEP=1
if [ ! -e /dev/dri/card0 ]
then
echo "ERROR: No display found."
exit 1
fi
log() {
$DEBUG && echo "Info: ${*}" >>/var/log/display.log
}
getValue() {
MYVAL=$(get_setting display.${1})
if [ -n "${MYVAL}" ]
then
if [ "${MYVAL}" > "${MAX}" ]
then
MYVAL=${MAX}
elif [ "${MYVAL}" < "${MIN}" ]
then
MYVAL=${MIN}
fi
echo ${MYVAL}
else
echo $(drm_tool list 2>/dev/null | sed -n '/Connector: '${CONNECTOR}'/,$p' | awk '/'${1}'/ {print $5}')
fi
}
setValue() {
log "Set (${1}: ${2})"
drm_tool set /dev/dri/card0 ${CONNECTOR} ${1} ${2} 2>/dev/null
if [ $? = 0 ]
then
set_setting display.${1} ${2}
fi
}
stepUp() {
LASTVAL=$(getValue ${PROPERTY})
NEWVAL=$(expr ${LASTVAL} + 1)
log "Step up (${PROPERTY}: ${NEWVAL})"
setValue ${PROPERTY} ${NEWVAL}
}
stepDown() {
LASTVAL=$(getValue ${PROPERTY})
NEWVAL=$(expr ${LASTVAL} - 1)
log "Step down (${PROPERTY}: ${NEWVAL})"
setValue ${PROPERTY} ${NEWVAL}
}
restoreSettings() {
for PROPERTY in brightness contrast saturation hue
do
RESTVAL=$(getValue ${PROPERTY})
setValue ${PROPERTY} ${RESTVAL}
done
}
CONNECTOR=$(drm_tool list | grep -B1 "mode.*:" | awk '/Connector/ {print $2}')
case ${NEWVAL} in
"up")
stepUp
;;
"down")
stepDown
;;
"restore")
restoreSettings
;;
*)
if [[ "${NEWVAL}" =~ ^[0-9] ]] && \
[ "${NEWVAL}" -le "${MAX}" ] && \
[ "${NEWVAL}" -ge "${MIN}" ]
then
setValue ${PROPERTY} ${NEWVAL}
else
echo "Error: Invalid value."
exit 1
fi
;;
esac

View file

@ -0,0 +1,35 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
ui_state() {
clear >/dev/console
systemctl ${1} ${UI_SERVICE}
}
if [ "${UI_SERVICE}" = "weston.service" ]
then
if [ -f "${*}" ]
then
RUN=$(echo ${*} | sed 's# #\\ #g')
weston-terminal --command="${RUN}"
else
weston-terminal --command="${*}"
fi
else
ui_state stop
clear >/dev/console
$* >/dev/console
if [ "$?" == 0 ]
then
ui_state start
exit 0
else
"$*" >/dev/console
ui_state start
exit 0
fi
fi

View file

@ -0,0 +1,461 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert)
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Source predefined functions and variables
. /etc/profile
. /etc/os-release
### Switch to performance mode early to speed up configuration and reduce time it takes to get into games.
performance
# Command line schema
# $1 = Game/Port
# $2 = Platform
# $3 = Core
# $4 = Emulator
ARGUMENTS="$@"
PLATFORM="${ARGUMENTS##*-P}" # read from -P onwards
PLATFORM="${PLATFORM%% *}" # until a space is found
CORE="${ARGUMENTS##*--core=}" # read from --core= onwards
CORE="${CORE%% *}" # until a space is found
EMULATOR="${ARGUMENTS##*--emulator=}" # read from --emulator= onwards
EMULATOR="${EMULATOR%% *}" # until a space is found
ROMNAME="$1"
BASEROMNAME=${ROMNAME##*/}
GAMEFOLDER="${ROMNAME//${BASEROMNAME}}"
### Define the variables used throughout the script
BLUETOOTH_STATE=$(get_setting bluetooth.enabled)
ES_CONFIG="/storage/.emulationstation/es_settings.cfg"
VERBOSE=false
LOG_DIRECTORY="/var/log"
LOG_FILE="exec.log"
RUN_SHELL="/usr/bin/bash"
RETROARCH_TEMP_CONFIG="/storage/.config/retroarch/retroarch.cfg"
RETROARCH_APPEND_CONFIG="/tmp/.retroarch.cfg"
NETWORK_PLAY="No"
SET_SETTINGS_TMP="/tmp/shader"
OUTPUT_LOG="${LOG_DIRECTORY}/${LOG_FILE}"
SCRIPT_NAME=$(basename "$0")
### Function Library
function log() {
if [ ${LOG} == true ]
then
if [[ ! -d "$LOG_DIRECTORY" ]]
then
mkdir -p "$LOG_DIRECTORY"
fi
echo "${SCRIPT_NAME}: $*" 2>&1 | tee -a ${LOG_DIRECTORY}/${LOG_FILE}
else
echo "${SCRIPT_NAME}: $*"
fi
}
function loginit() {
if [ ${LOG} == true ]
then
if [ -e ${LOG_DIRECTORY}/${LOG_FILE} ]
then
rm -f ${LOG_DIRECTORY}/${LOG_FILE}
fi
cat <<EOF >${LOG_DIRECTORY}/${LOG_FILE}
Emulation Run Log - Started at $(date)
ARG1: $1
ARG2: $2
ARG3: $3
ARG4: $4
ARGS: $*
EMULATOR: ${EMULATOR}
PLATFORM: ${PLATFORM}
CORE: ${CORE}
ROM NAME: ${ROMNAME}
BASE ROM NAME: ${ROMNAME##*/}
USING CONFIG: ${RETROARCH_TEMP_CONFIG}
USING APPENDCONFIG : ${RETROARCH_APPEND_CONFIG}
EOF
else
log $0 "Emulation Run Log - Started at $(date)"
fi
}
function quit() {
${VERBOSE} && log $0 "Cleaning up and exiting"
bluetooth enable
set_kill set "emulationstation"
clear_screen
DEVICE_CPU_GOVERNOR=$(get_setting system.cpugovernor)
${DEVICE_CPU_GOVERNOR}
exit $1
}
function clear_screen() {
${VERBOSE} && log $0 "Clearing screen"
clear
}
function bluetooth() {
if [ "$1" == "disable" ]
then
${VERBOSE} && log $0 "Disabling BT"
if [[ "${BLUETOOTH_STATE}" == "1" ]]
then
NPID=$(pgrep -f batocera-bluetooth-agent)
if [[ ! -z "$NPID" ]]; then
kill "$NPID"
fi
fi
elif [ "$1" == "enable" ]
then
${VERBOSE} && log $0 "Enabling BT"
if [[ "${BLUETOOTH_STATE}" == "1" ]]
then
systemd-run batocera-bluetooth-agent
fi
fi
}
### Enable logging
case $(get_setting system.loglevel) in
off|none)
LOG=false
;;
verbose)
LOG=true
VERBOSE=true
;;
*)
LOG=true
;;
esac
### Prepare to load our emulator and game.
loginit "$1" "$2" "$3" "$4"
clear_screen
bluetooth disable
set_kill stop
### Determine which emulator we're launching and make appropriate adjustments before launching.
${VERBOSE} && log $0 "Configuring for ${EMULATOR}"
case ${EMULATOR} in
mednafen)
set_kill set "-9 mednafen"
RUNTHIS='${RUN_SHELL} /usr/bin/start_mednafen.sh "${ROMNAME}" "${CORE}" "${PLATFORM}"'
;;
retroarch)
# Make sure NETWORK_PLAY isn't defined before we start our tests/configuration.
del_setting netplay.mode
case ${ARGUMENTS} in
*"--host"*)
${VERBOSE} && log $0 "Setup netplay host."
NETWORK_PLAY="${ARGUMENTS##*--host}" # read from --host onwards
NETWORK_PLAY="${NETWORK_PLAY%%--nick*}" # until --nick is found
NETWORK_PLAY="--host ${NETWORK_PLAY} --nick"
set_setting netplay.mode "host"
;;
*"--connect"*)
${VERBOSE} && log $0 "Setup netplay client."
NETWORK_PLAY="${ARGUMENTS##*--connect}" # read from --connect onwards
NETWORK_PLAY="${NETWORK_PLAY%%--nick*}" # until --nick is found
NETWORK_PLAY="--connect ${NETWORK_PLAY} --nick"
set_setting netplay.mode "client"
;;
*"--netplaymode spectator"*)
${VERBOSE} && log $0 "Setup netplay spectator."
set_setting "netplay.mode" "spectator"
;;
esac
### Set set_kill to kill the appropriate retroarch
set_kill set "retroarch retroarch32"
### Assume we're running 64bit Retroarch
RABIN="retroarch"
case ${HW_ARCH} in
aarch64)
if [[ "${CORE}" =~ pcsx_rearmed32 ]] || \
[[ "${CORE}" =~ gpsp ]] || \
[[ "${CORE}" =~ desmume ]]
then
### Configure for 32bit Retroarch
${VERBOSE} && log $0 "Configuring for 32bit cores."
export LIBRARY_PATH="/usr/lib32"
export LD_LIBRARY_PATH="${LIBRARY_PATH}"
export SPA_PLUGIN_DIR="${LIBRARY_PATH}/spa-0.2"
export PIPEWIRE_MODULE_DIR="${LIBRARY_PATH}/pipewire-0.3/"
export LIBGL_DRIVERS_PATH="${LIBRARY_PATH}/dri"
export RABIN="retroarch32"
fi
;;
esac
### Configure specific emulator requirements
case ${CORE} in
freej2me*)
${VERBOSE} && log $0 "Setup freej2me requirements."
/usr/bin/freej2me.sh
JAVA_HOME='/storage/jdk'
export JAVA_HOME
PATH="$JAVA_HOME/bin:$PATH"
export PATH
;;
easyrpg*)
# easyrpg needs runtime files to be downloaded on the first run
${VERBOSE} && log $0 "Setup easyrpg requirements."
/usr/bin/easyrpg.sh
;;
esac
RUNTHIS='${EMUPERF} /usr/bin/${RABIN} -L /tmp/cores/${CORE}_libretro.so --config ${RETROARCH_TEMP_CONFIG} --appendconfig ${RETROARCH_APPEND_CONFIG} "${ROMNAME}"'
CONTROLLERCONFIG="${ARGUMENTS#*--controllers=*}"
if [[ "${ARGUMENTS}" == *"-state_slot"* ]]
then
CONTROLLERCONFIG="${CONTROLLERCONFIG%% -state_slot*}" # until -state is found
SNAPSHOT="${ARGUMENTS#*-state_slot *}" # -state_slot x
SNAPSHOT="${SNAPSHOT%% -*}"
if [[ "${ARGUMENTS}" == *"-autosave"* ]]; then
CONTROLLERCONFIG="${CONTROLLERCONFIG%% -autosave*}" # until -autosave is found
AUTOSAVE="${ARGUMENTS#*-autosave *}" # -autosave x
AUTOSAVE="${AUTOSAVE%% -*}"
else
AUTOSAVE=""
fi
else
CONTROLLERCONFIG="${CONTROLLERCONFIG%% --*}" # until a -- is found
SNAPSHOT=""
AUTOSAVE=""
fi
# Configure platform specific requirements
case ${PLATFORM} in
"atomiswave")
rm ${ROMNAME}.nvmem*
;;
"scummvm")
GAMEDIR=$(cat "${ROMNAME}" | awk 'BEGIN {FS="\""}; {print $2}')
cd "${GAMEDIR}"
RUNTHIS='${RUN_SHELL} /usr/bin/start_scummvm.sh libretro .'
;;
esac
### Configure retroarch
if [ -e "${SET_SETTINGS_TMP}" ]
then
rm -f "${SET_SETTINGS_TMP}"
fi
${VERBOSE} && log $0 "Execute setsettings (${PLATFORM} ${ROMNAME} ${CORE} --controllers=${CONTROLLERCONFIG} --autosave=${AUTOSAVE} --snapshot=${SNAPSHOT})"
(/usr/bin/setsettings.sh "${PLATFORM}" "${ROMNAME}" "${CORE}" --controllers="${CONTROLLERCONFIG}" --autosave="${AUTOSAVE}" --snapshot="${SNAPSHOT}" >${SET_SETTINGS_TMP})
### If setsettings wrote data in the background, grab it and assign it to EXTRAOPTS
if [ -e "${SET_SETTINGS_TMP}" ]
then
EXTRAOPTS=$(cat ${SET_SETTINGS_TMP})
rm -f ${SET_SETTINGS_TMP}
${VERBOSE} && log $0 "Extra Options: ${EXTRAOPTS}"
fi
if [[ ${EXTRAOPTS} != 0 ]]; then
RUNTHIS=$(echo ${RUNTHIS} | sed "s|--config|${EXTRAOPTS} --config|")
fi
;;
*)
case ${PLATFORM} in
"setup")
RUNTHIS='${RUN_SHELL} "${ROMNAME}"'
;;
"gamecube")
RUNTHIS='${RUN_SHELL} /usr/bin/start_dolphin_gc.sh "${ROMNAME}"'
;;
"wii")
RUNTHIS='${RUN_SHELL} /usr/bin/start_dolphin_wii.sh "${ROMNAME}"'
;;
"ports")
RUNTHIS='${RUN_SHELL} "${ROMNAME}"'
sed -i "/^ACTIVE_GAME=/c\ACTIVE_GAME=\"${ROMNAME}\"" /storage/.config/PortMaster/mapper.txt
;;
"shell")
RUNTHIS='${RUN_SHELL} "${ROMNAME}"'
;;
*)
RUNTHIS='${RUN_SHELL} "start_${CORE%-*}.sh" "${ROMNAME}"'
;;
esac
;;
esac
### Execution time.
clear_screen
${VERBOSE} && log $0 "executing game: ${ROMNAME}"
${VERBOSE} && log $0 "script to execute: ${RUNTHIS}"
### Set the cores to use
CORES=$(get_setting "cores" "${PLATFORM}" "${ROMNAME##*/}")
${VERBOSE} && log $0 "Configure big.little (${CORES})"
case ${CORES} in
little)
EMUPERF="${SLOW_CORES}"
;;
big)
EMUPERF="${FAST_CORES}"
;;
*)
unset EMUPERF
;;
esac
### We need the original system cooling profile later so get it now!
COOLINGPROFILE=$(get_setting cooling.profile)
### Set CPU TDP and EPP
CPU_VENDOR=$(cpu_vendor)
case ${CPU_VENDOR} in
AuthenticAMD)
### Set the overclock mode
OVERCLOCK=$(get_setting "overclock" "${PLATFORM}" "${ROMNAME##*/}")
if [ ! -z "${OVERCLOCK}" ]
then
${VERBOSE} && log $0 "Set TDP to (${OVERCLOCK})"
/usr/bin/overclock ${OVERCLOCK}
fi
;;
esac
### Apply energy performance preference
if [ -e "/usr/bin/set_epp" ]
then
EPP=$(get_setting "power.epp" "${PLATFORM}" "${ROMNAME##*/}")
if [ ! -z ${EPP} ]
then
${VERBOSE} && log $0 "Set EPP to (${EPP})"
/usr/bin/set_epp ${EPP}
fi
fi
### Configure GPU performance mode
GPUPERF=$(get_setting "gpuperf" "${PLATFORM}" "${ROMNAME##*/}")
if [ ! -z ${GPUPERF} ]
then
${VERBOSE} && log $0 "Set GPU performance to (${GPUPERF})"
gpu_performance_level ${GPUPERF}
get_gpu_performance_level >/tmp/.gpu_performance_level
fi
if [ "${DEVICE_HAS_FAN}" = "true" ]
then
### Set any custom fan profile (make this better!)
GAMEFAN=$(get_setting "cooling.profile" "${PLATFORM}" "${ROMNAME##*/}")
if [ ! -z "${GAMEFAN}" ]
then
${VERBOSE} && log $0 "Set fan profile to (${GAMEFAN})"
set_setting cooling.profile ${GAMEFAN}
systemctl restart fancontrol
fi
fi
### Offline all but the number of threads we need for this game if configured.
NUMTHREADS=$(get_setting "threads" "${PLATFORM}" "${ROMNAME##*/}")
if [ -n "${NUMTHREADS}" ] &&
[ ! ${NUMTHREADS} = "default" ]
then
${VERBOSE} && log $0 "Configure active cores (${NUMTHREADS})"
onlinethreads ${NUMTHREADS} 0
fi
### Set the performance mode for emulation
PERFORMANCE_MODE=$(get_setting "cpugovernor" "${PLATFORM}" "${ROMNAME##*/}")
${VERBOSE} && log $0 "Set emulation performance mode to (${PERFORMANCE_MODE})"
${PERFORMANCE_MODE}
# If the rom is a shell script just execute it, useful for DOSBOX and ScummVM scan scripts
if [[ "${ROMNAME}" == *".sh" ]]; then
${VERBOSE} && log $0 "Executing shell script ${ROMNAME}"
"${ROMNAME}" &>>${OUTPUT_LOG}
ret_error=$?
else
${VERBOSE} && log $0 "Executing $(eval echo ${RUNTHIS})"
eval ${RUNTHIS} &>>${OUTPUT_LOG}
ret_error=$?
fi
### Switch back to performance mode to clean up
performance
clear_screen
### Restore cooling profile.
if [ "${DEVICE_HAS_FAN}" = "true" ]
then
${VERBOSE} && log $0 "Restore system cooling profile (${COOLINGPROFILE})"
set_setting cooling.profile ${COOLINGPROFILE}
systemctl restart fancontrol &
fi
### Restore system GPU performance mode
GPUPERF=$(get_setting "system.gpuperf")
if [ ! -z ${GPUPERF} ]
then
${VERBOSE} && log $0 "Restore system GPU performance mode (${GPUPERF})"
gpu_performance_level ${GPUPERF} &
else
${VERBOSE} && log $0 "Restore system GPU performance mode (auto)"
gpu_performance_level auto &
fi
rm -f /tmp/.gpu_performance_level 2>/dev/null
### Restore system EPP
EPP=$(get_setting "system.power.epp")
if [ ! -z ${EPP} ]
then
${VERBOSE} && log $0 "Restore system EPP (${EPP})"
/usr/bin/set_epp ${EPP} &
fi
### Restore system TDP
OVERCLOCK=$(get_setting "system.overclock")
if [ ! -z "${OVERCLOCK}" ]
then
${VERBOSE} && log $0 "Restore system TDP (${OVERCLOCK})"
/usr/bin/overclock ${OVERCLOCK} &
fi
### Reset the number of cores to use.
NUMTHREADS=$(get_setting "system.threads")
${VERBOSE} && log $0 "Restore active threads (${NUMTHREADS})"
if [ -n "${NUMTHREADS}" ]
then
onlinethreads ${NUMTHREADS} 0 &
else
onlinethreads all 1 &
fi
### Backup save games
CLOUD_BACKUP=$(get_setting "cloud.backup")
if [ "${CLOUD_BACKUP}" = "1" ]
then
INETUP=$(/usr/bin/amionline >/dev/null 2>&1)
if [ $? == 0 ]
then
log $0 "backup saves to the cloud."
/usr/bin/run /usr/bin/cloud_backup
fi
fi
${VERBOSE} && log $0 "Checking errors: ${ret_error} "
if [ "${ret_error}" == "0" ]
then
quit 0
else
log $0 "exiting with ${ret_error}"
quit 1
fi

View file

@ -0,0 +1,22 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
AUDIOTEST=$(ps -ef | grep [p]ipewire)
if [ ! $? = 0 ]
then
PLAYCMD="aplay -q"
else
PLAYCMD="paplay"
fi
case $1 in
-b)
espeak --stdout "$(battery_percent)%" | ${PLAYCMD}
;;
*)
espeak --stdout "$*" | ${PLAYCMD}
;;
esac

View file

@ -0,0 +1,30 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2019-present Shanti Gilbert (https://github.com/shantigilbert)
## workaround for ES performance with big conf files
## This is no longer in use!
EE_CONF="/storage/.config/system/configs/emuoptions.conf"
[ ! -f ${EE_CONF} ] && touch ${EE_CONF}
case "$1" in
"set")
PAT=$(echo "$2" | sed -e 's|\"|\\"|g' | sed -e 's|\[|\\\[|g' | sed -e 's|\]|\\\]|g')
sed -i "/$PAT/d" "${EE_CONF}"
S2=${2}
S3=${3}
shift 2
if [ "${S3}" != "auto" ]; then
[ ${S3} == "disable" ] && echo "#${S2}=" >> "${EE_CONF}" || echo "${S2}=${@}" >> "${EE_CONF}"
fi
;;
"get")
PAT=$(echo ${2} | sed -e 's|\"|\\"|g' | sed -e 's|\[|\\\[|g' | sed -e 's|\]|\\\]|g' | sed -e 's|(|\\\(|g' | sed -e 's|)|\\\)|g')
PAT="^${PAT}=(.*)"
EES=$(cat "${EE_CONF}" | grep -oE "${PAT}")
echo "${EES##*=}"
;;
esac

View file

@ -0,0 +1,44 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
ROOTPASS="$1"
LPC=$(awk -F: '/^root/{print $3}' /storage/.cache/shadow)
CURRENT=$(awk -F: '/^root/{print $2}' /storage/.cache/shadow)
# Turn it into a usable hash
NEW=$(cryptpw -m sha512 "${ROOTPASS}" 2>/dev/null)
# Set the root password.
sed -i "s#root:${CURRENT}:${LPC}::::::#root:${NEW}:${LPC}::::::#g" /storage/.cache/shadow 2>/dev/null
# Create a root user and set the password.
echo -ne "${ROOTPASS}\n${ROOTPASS}\n" | smbpasswd -sa root 2>/dev/null
# Set the root user and password for SyncThing
syncthing generate --gui-user "root" --gui-password "${ROOTPASS}" >/dev/null 2>&1
# Save the password so we can display it in ES
set_setting root.password "${ROOTPASS}"
# Restart syncthing if it was enabled.
SYNCSTATUS=$(get_setting syncthing.enabled)
SYNCACTIVE=$(systemctl status syncthing | awk '/active/ {print $2}')
if [ "${SYNCSTATUS}" = "1" ] &&
[ "${SYNCACTIVE}" = "active" ]
then
systemctl restart syncthing >/dev/null 2>&1
fi
# Restart simple-http-server if it is enabled
SIMPLESTATUS=$(get_setting simplehttp.enabled)
SIMPLEACTIVE=$(systemctl status simple-http-server | awk '/active/ {print $2}')
if [ "${SIMPLESTATUS}" = "1" ] &&
[ "${SIMPLEACTIVE}" = "active" ]
then
systemctl restart simple-http-server >/dev/null 2>&1
fi

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,32 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
CHANGELOG="/storage/.cache/changelog"
if [ ! -e "${CHANGELOG}" ]
then
exit 0
fi
WIDTH=$(fbwidth)
if [ "${WIDTH}" -le "480" ]
then
FONTSIZE=8
elif [ "${WIDTH}" -gt "480" ] && [ "${WIDTH}" -le "640" ]
then
FONTSIZE=12
elif [ "${WIDTH}" -gt "640" ] && [ "${WIDTH}" -le "720" ]
then
FONTSIZE=14
elif [ "${WIDTH}" -gt "720" ] && [ "${WIDTH}" -lt "1080" ]
then
FONTSIZE=20
else
FONTSIZE=24
fi
/usr/bin/text_viewer -f ${FONTSIZE} ${CHANGELOG}

View file

@ -0,0 +1,55 @@
#!/bin/bash
. /etc/profile
REQUESTED_MODE="${*}"
SUSPEND_MODE=$(get_setting system.suspendmode)
if [ ! "${REQUESTED_MODE}" = "${SUSPEND_MODE}" ]
then
cat <<EOF >/storage/.config/sleep.conf.d/sleep.conf
[Sleep]
EOF
case ${REQUESTED_MODE} in
off)
cat <<EOF >>/storage/.config/sleep.conf.d/sleep.conf
AllowSuspend=no
EOF
;;
freeze)
cat <<EOF >>/storage/.config/sleep.conf.d/sleep.conf
AllowSuspend=yes
SuspendState=freeze standby mem
EOF
;;
standby)
cat <<EOF >>/storage/.config/sleep.conf.d/sleep.conf
AllowSuspend=yes
SuspendState=standby mem freeze
EOF
;;
mem)
cat <<EOF >>/storage/.config/sleep.conf.d/sleep.conf
AllowSuspend=yes
SuspendState=mem standby freeze
EOF
;;
default)
del_setting system.suspendmode
if [ -e "/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/030-suspend_mode" ]
then
"/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/030-suspend_mode"
elif [ -e "/usr/lib/autostart/quirks/devices/${QUIRK_DEVICE}/030-suspend_mode" ]
then
"/usr/lib/autostart/quirks/platforms/${HW_DEVICE}/030-suspend_mode"
fi
;;
*)
cat <<EOF >>/storage/.config/sleep.conf.d/sleep.conf
AllowSuspend=yes
SuspendState=${REQUESTED_MODE}
EOF
;;
esac
set_setting system.suspendmode ${1}
systemctl restart systemd-logind
fi

View file

@ -0,0 +1,166 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
ORGANIZATION="${GIT_ORGANIZATION}"
BRANCH="$(get_setting updates.branch)"
case ${BRANCH} in
dev)
PROJECT="${GIT_REPO}-dev"
;;
*)
PROJECT="${GIT_REPO}"
;;
esac
FORCE="$(get_setting updates.force)"
GIT_REPO="https://github.com/${ORGANIZATION}/${PROJECT}"
GIT_API="https://api.github.com/repos/${ORGANIZATION}/${PROJECT}"
UPDATE_PATH="/storage/.update"
EXTENSION="tar"
function check_network() {
GW=$(ip route | awk '/eth0/ {a=$0} END{print $1}')
if [[ ${GW} =~ [0-9] ]]
then
echo true
else
echo false
fi
}
get_available() {
echo $(df | awk '/'$1'/ {printf $4; exit}')
}
get_size() {
echo $(df | awk '/'$1'/ {printf $2; exit}')
}
check_space() {
MYSIZE="$(get_$1 $2)"
VOLNAME="$3"
REQUIRED="$4"
if [ "${MYSIZE}" -lt "${REQUIRED}" ]
then
NEEDED=$(( (${REQUIRED} - ${MYSIZE} ) / 1024 ))
echo -e "There is not enough free space available ${VOLNAME} to install this update. Free up an additional ${NEEDED}MB, or reflash the newer version."
echo "Exiting in 5 seconds..." && sleep 5
exit 1
fi
}
get_changelog() {
echo "Fetching change log."
echo -e "Change Log" >/storage/.cache/changelog
lynx --dump "${GIT_REPO}/releases/latest" 2>/dev/null | awk '/Contributors|Assets [0-9]/ {exit}; /Change Log/{p++;if(p==1){next}}p;' >>/storage/.cache/changelog
if [ ! "$?" = "0" ]
then
echo "Unable to fetch the change log, please ensure you have a network connection." >>/storage/.cache/changelog
fi
}
get_release_list() {
DATA=($(curl -H 'Cache-Control: no-cache' -Ls "${GIT_API}/releases" 2>/dev/null | python -c "import sys, json; data=json.load(sys.stdin); print(\"\\n\".join([str(data[i]['tag_name']) for i in range(10)]))"))
if [ ! -z "${DATA}" ]
then
printf "%s\n" "${DATA[@]}"
else
echo "Unable to fetch releases."
fi
}
function cleanup() {
if [ -e "/tmp/release.data" ]
then
rm -f /tmp/release.data
fi
}
###
### Check for passed arguments. If we receive changelog, fetch it. If we receive a version, force install it.
###
case ${1} in
changelog)
get_changelog >/dev/null 2>&1
exit 0
;;
releases)
get_release_list
exit 0
;;
[0-9][0-9]*)
UPDATE_PACKAGE=${1}
FORCE=1
;;
esac
ONLINE_STATUS=$(check_network)
if [ ! "${ONLINE_STATUS}" == true ]
then
echo "System not online, cannot continue..."
echo "Exiting in 5 seconds..." && sleep 5
exit 0
fi
echo -e "=> ${OS_NAME} UPGRADE UTILITY"
# Check storage
check_space size flash boot 2048000 2>/dev/null
if [ "$(mountpoint -q /storage/roms)" ]
then
check_space available .update GAMES 4096000 2>/dev/null
fi
if [ -z "${UPDATE_PACKAGE}" ]
then
curl -o /tmp/release.data -H 'Cache-Control: no-cache' -Ls "${GIT_API}/releases"
UPDATE_PACKAGE=$(awk 'BEGIN {FS="\""} /'${OS_NAME}-${HW_DEVICE}.${HW_ARCH}'.*tar/ {print $4; exit}' /tmp/release.data | sed -e "s~${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-~~g;s~.tar$~~g")
if [ "${UPDATE_PACKAGE}" -le "${OS_VERSION}" ] \
&& [ ! "${FORCE}" == "1" ]
then
cleanup
echo "No new updates are available..."
echo "Exiting in 5 seconds..." && sleep 5
exit 0
fi
fi
echo -e "\nFetching: ${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-${UPDATE_PACKAGE}.${EXTENSION}"
curl -Lo "${UPDATE_PATH}/${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-${UPDATE_PACKAGE}.${EXTENSION}" "${GIT_REPO}/releases/download/${UPDATE_PACKAGE}/${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-${UPDATE_PACKAGE}.tar"
echo -e "Fetching: ${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-${UPDATE_PACKAGE}.${EXTENSION}.sha256"
curl -Lo "${UPDATE_PATH}/${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-${UPDATE_PACKAGE}.${EXTENSION}.sha256" "${GIT_REPO}/releases/download/${UPDATE_PACKAGE}/${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-${UPDATE_PACKAGE}.tar.sha256"
echo -e "\nVerifying download, please wait..."
# Verify
MYSUM=$(sha256sum ${UPDATE_PATH}/${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-${UPDATE_PACKAGE}.${EXTENSION} | awk '{print $1}')
DLSUM=$(cat ${UPDATE_PATH}/${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-${UPDATE_PACKAGE}.${EXTENSION}.sha256 | awk '{print $1}')
if [ ! "${MYSUM}" == "${DLSUM}" ]
then
echo "Verification failed, cleaning up and exiting..."
rm -f ${UPDATE_PATH}/*
sleep 5
clear
exit 1
else
echo "Verification successful..."
fi
get_changelog
if [ "${FORCE}" == "1" ]
then
set_setting updates.force 0
fi
echo -e "\nRebooting to complete OS upgrade..."
sync
sleep 3
reboot

View file

@ -0,0 +1,22 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2020-2022 Shanti Gilbert (https://github.com/shantigilbert)
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
function get_timezone() {
readlink -f /etc/localtime | sed 's;/usr/share/zoneinfo/;;'
}
function list_timezones() {
cat /usr/share/zoneinfo/zone1970.tab | grep -v "^#" | awk '{ print $3"," }' | sort -u
}
case "${1}" in
"current_timezone")
get_timezone
;;
"timezones")
list_timezones
;;
esac

View file

@ -0,0 +1,16 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
if [ "$(get_setting ipv6.enabled)" == "1" ]
then
sysctl net.ipv6.conf.all.disable_ipv6=0
sysctl net.ipv6.conf.default.disable_ipv6=0
sysctl net.ipv6.conf.lo.disable_ipv6=0
else
sysctl net.ipv6.conf.all.disable_ipv6=1
sysctl net.ipv6.conf.default.disable_ipv6=1
sysctl net.ipv6.conf.lo.disable_ipv6=1
fi

View file

@ -0,0 +1,55 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
. /etc/profile
ORGANIZATION="${GIT_ORGANIZATION}"
BRANCH="$(get_setting updates.branch)"
case ${BRANCH} in
dev)
PROJECT="${GIT_REPO}-dev"
;;
*)
PROJECT="${GIT_REPO}"
;;
esac
GIT_REPO="https://github.com/${ORGANIZATION}/${PROJECT}"
GIT_API="https://api.github.com/repos/${ORGANIZATION}/${PROJECT}"
FORCE="$(get_setting updates.force)"
function check_network() {
GW=$(ip route | awk '/eth0/ {a=$0} END{print $1}')
if [[ ${GW} =~ [0-9] ]]
then
echo true
else
echo false
fi
}
function cleanup() {
if [ -e "/tmp/release.data" ]
then
rm -f /tmp/release.data
fi
}
ONLINE_STATUS=$(check_network)
if [ "${ONLINE_STATUS}" == true ]
then
curl -o /tmp/release.data -H 'Cache-Control: no-cache' -Ls "${GIT_API}/releases"
UPDATE_PACKAGE=$(awk 'BEGIN {FS="\""} /'${OS_NAME}-${HW_DEVICE}.${HW_ARCH}'.*tar/ {print $4; exit}' /tmp/release.data | sed -e "s~${OS_NAME}-${HW_DEVICE}.${HW_ARCH}-~~g;s~.tar$~~g")
if [ "${UPDATE_PACKAGE}" -gt "${OS_VERSION}" ] \
|| [ "${FORCE}" == "1" ]
then
echo "${UPDATE_PACKAGE}"
cleanup
exit 0
fi
fi
cleanup
exit 12

View file

@ -0,0 +1,113 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
for mod in usb_f_ecm usb_f_fs; do
modprobe -q ${mod}
done
mkdir -p /storage/.cache/usbgadget
if [ ! -f /storage/.cache/usbgadget/ip_address.conf ] ; then
echo "10.1.1.2" > /storage/.cache/usbgadget/ip_address.conf
fi
if [ ! -f /storage/.cache/usbgadget/udhcpd.conf ] ; then
echo -e "interface usb0\nstart 10.1.1.1\nend 10.1.1.1\nopt subnet 255.255.255.0\nopt lease 86400\nmax_leases 1\nlease_file /dev/null\nremaining no" >> /storage/.cache/usbgadget/udhcpd.conf
fi
VENDOR=JELOS
MACHINE=$(cat /etc/hostname)
UDC_NAME=$(ls -1 /sys/class/udc |head -n1)
IP=$(cat /storage/.cache/usbgadget/ip_address.conf)
usb_disable() {
echo "" > /sys/kernel/config/usb_gadget/gadget/UDC
echo "USB_MODE=disabled" > /storage/.cache/usbgadget/usbgadget.conf
}
usb_start() {
if [ -r /storage/.cache/usbgadget/usbgadget.conf ] ; then
. /storage/.cache/usbgadget/usbgadget.conf
fi
if [ "$1" ] ; then
USB_MODE=$1
fi
cd /sys/kernel/config/usb_gadget
mkdir gadget \
gadget/strings/0x409 \
gadget/configs/c.1 \
gadget/configs/c.1/strings/0x409 \
gadget/functions/ffs.mtp \
gadget/functions/ecm.usb0
echo $VENDOR > gadget/strings/0x409/manufacturer
echo $MACHINE > gadget/strings/0x409/product
if [ "${USB_MODE}" = mtp ] ; then
echo 0x1d6b > gadget/idVendor
echo 0x0100 > gadget/idProduct
echo mtp > gadget/configs/c.1/strings/0x409/configuration
ln -s gadget/functions/ffs.mtp gadget/configs/c.1
mkdir /dev/ffs-umtp
mount mtp -t functionfs /dev/ffs-umtp
/usr/sbin/umtprd &
sleep 1
echo "${UDC_NAME}" > gadget/UDC
elif [ "${USB_MODE}" = cdc ] ; then
echo cdc > gadget/configs/c.1/strings/0x409/configuration
echo 0x1d6b > gadget/idVendor
echo 0x104 > gadget/idProduct
ln -s gadget/functions/ecm.usb0 gadget/configs/c.1
echo "${UDC_NAME}" > gadget/UDC
ifconfig usb0 $IP up
/usr/sbin/udhcpd -S /storage/.cache/usbgadget/udhcpd.conf
else
exit 0
fi
echo "USB_MODE=$(cat gadget/configs/c.1/strings/0x409/configuration)" > /storage/.cache/usbgadget/usbgadget.conf
}
usb_stop() {
(
cd /sys/kernel/config/usb_gadget
usb_disable
umount /dev/ffs-umtp
rmdir /dev/ffs-umtp
rm -f mtp/configs/c.1/ffs.mtp \
gadget/configs/c.1/ecm.usb0 \
rmdir gadget/configs/c.1/strings/0x409 \
gadget/configs/c.1 \
gadget/functions/ffs.mtp \
gadget/functions/ecm.usb0 \
gadget/strings/0x409 \
gadget
killall udhcpd
killall umtprd
) >/dev/null 2>&1
}
case "$1" in
start)
usb_start $2
;;
stop)
usb_stop
;;
restart)
usb_stop
usb_start $2
;;
*)
echo "Usage: usbgadget [start|stop|restart]"
;;
esac

View file

@ -0,0 +1,40 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Source minimal predefined functions and variables
# to ensure as much performance as possible.
. /etc/profile.d/001-functions
VOLUME=$(get_setting "audio.volume")
MAX_VOLUME=100
MIN_VOLUME=0
STEP=10
case ${1} in
"+"|"up")
VOLUME=$(( ${VOLUME} + ${STEP} ))
;;
"-"|"down")
VOLUME=$(( ${VOLUME} - ${STEP} ))
;;
*)
VOLUME=${1}
;;
esac
if (( ${VOLUME} < ${MIN_VOLUME} ))
then
VOLUME=${MIN_VOLUME}
elif (( ${VOLUME} > ${MAX_VOLUME} ))
then
VOLUME=${MAX_VOLUME}
elif [ -z "${VOLUME}" ]
then
VOLUME=60
fi
pactl -- set-sink-volume @DEFAULT_SINK@ ${VOLUME}%
set_setting "audio.volume" ${VOLUME}

View file

@ -0,0 +1,220 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
# Copyright (C) 2022 kkoshelev (https://github.com/kkoshelev)
. /etc/profile
###
### Basic WIFI properties used across the tool.
###
### Usage:
###  wifictl command [ssid] [psk]
###
CFG_ROOT="/storage/.cache"
WIFI_CFG="${CFG_ROOT}/connman/wifi.config"
HOSTAPD_CFG="${CFG_ROOT}/.hostapd.conf"
WIFI_TYPE=$(get_setting network.adhoc.enabled)
NETWORK_ADDRESS="192.168.80"
ADHOC_CLIENT_ID=$(get_setting wifi.adhoc.id)
WIFI_DEV="wlan0"
DEFAULT_CHAN="6"
### ES won't save the configuration in time
### for it to be useable by the script, so
### we have to accept the ssid and key on the
### command line too.
if [ ! -z "${2}" ]
then
SSID="${2}"
else
SSID="$(get_setting wifi.ssid)" 2>/dev/null
fi
if [ ! -z "${3}" ]
then
PSK="${3}"
else
PSK="$(get_setting wifi.key)" 2>/dev/null
fi
if [ "${WIFI_TYPE}" = "1" ]
then
GENERATED=($(awk '! /^HW_|BUILD_DATE/ {print}' /etc/os-release | md5sum))
SSID="${GENERATED[0]:0:10}"
PSK="${GENERATED[0]: -10}"
fi
if [ ! -d "${CFG_ROOT}/connman" ]
then
mkdir -p "${CFG_ROOT}/connman"
fi
ADHOC_CHAN=$(get_setting wifi.adhoc.channel)
if [ -z "${ADHOC_CHAN}" ]
then
ADHOC_CHAN="${DEFAULT_CHAN}"
set_setting wifi.adhoc.channel ${DEFAULT_CHAN}
fi
###
### Functions...
###
# lists all wifi services in service=ssid format
list_wifi() {
connmanctl services | cut -b 5- | awk '/\S+.+\s+wifi/ {a=$0; sub(/\s+wifi_.*$/,"", a); b=$0; sub(a, "", b); sub(/\s+/, "", b); print b "=" a}' | sort | uniq
}
# Looksup connman service name based on ssid
# $1 - SSID to lookup
get_wifi_service() {
list_wifi | awk -v ssid="${1}" '{ split($0, a, "="); if (a[2]==ssid) print a[1] }'
}
set_powersave() {
ENABLED=$(get_setting system.power.wifi)
if [ "${ENABLED}" = "1" ]
then
log $0 "Enabling WIFI power saving."
iw ${WIFI_DEV} set power_save on 2>/dev/null
else
log $0 "Disabling WIFI power saving."
iw ${WIFI_DEV} set power_save off 2>/dev/null
fi
}
wifi_service() {
for SERVICE in wpa_supplicant connman-vpn connman
do
systemctl ${1} ${SERVICE}
done
}
connect_wifi() {
systemctl restart connman 2>/dev/null
connmanctl enable wifi 2>/dev/null
connmanctl connect $(connmanctl services 2>&1 | awk '/\s'${SSID}'\s/ {gsub(/^\*[A-z][A-z]/,""); print $2}') 2>/dev/null
set_powersave 2>/dev/null
}
create_adhoc() {
wifi_service stop
rfkill unblock wifi
cat <<EOF >${HOSTAPD_CFG}
interface=${WIFI_DEV}
auth_algs=1
channel=${ADHOC_CHAN}
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
wpa_passphrase=${PSK}
ssid=${SSID}
EOF
sysctl -w net.ipv4.ip_forward=1
### Flush any existing IP
ip addr flush dev ${WIFI_DEV}
### Set our IP
ip addr add ${NETWORK_ADDRESS}.${ADHOC_CLIENT_ID}/24 dev ${WIFI_DEV} >/dev/null 2>&1
systemctl start hostapd
exit 0
}
destroy_adhoc() {
ip addr flush dev ${WIFI_DEV}
ip link set ${WIFI_DEV} down
systemctl stop hostapd
}
set_profile() {
wifi_service stop
cat > "${WIFI_CFG}" <<EOF
[Settings]
AutoConnect = true
[service_${OS_NAME}_default]
Type = wifi
Name = ${SSID}
EOF
# Only add a PSK if one is provided, in order to connect to
# open networks.
if [ ! -z "${PSK}" ] ; then
cat >> "${WIFI_CFG}" <<EOF
Passphrase = ${PSK}
EOF
fi
if [ "${WIFI_TYPE}" = "1" ]
then
cat >> "${WIFI_CFG}" <<EOF
Security = wpa
IPv4 = ${NETWORK_ADDRESS}.${ADHOC_CLIENT_ID}/255.255.255.0/255.255.255.254
IPv6 = off
EOF
fi
rm -rf ${CFG_ROOT}/connman/wifi_*
wifi_service restart
}
case "${1}" in
enable)
set_profile >/dev/null 2>&1
if [ "${WIFI_TYPE}" = "1" ] && \
[ "${ADHOC_CLIENT_ID}" = "1" ]
then
create_adhoc >/dev/null 2>&1
else
destroy_adhoc >/dev/null 2>&1
fi
connect_wifi >/dev/null 2>&1
set_setting network.enabled 1
;;
disable)
if [ "${WIFI_TYPE}" = "1" ]
then
destroy_adhoc >/dev/null 2>&1
fi
connmanctl disable wifi >/dev/null 2>&1
rfkill block wifi >/dev/null 2>&1
rm -f "${WIFI_CFG}" 2>/dev/null
set_setting network.enabled 0
;;
reconnect)
/usr/bin/wifictl disable
/usr/bin/wifictl enable
;;
list)
list_wifi | awk '{sub(/\S+=/,"",$0);print}'
;;
channels)
iw list | awk '/[0-9] MHz \[/ && ! /disabled|radar|no IR/ { gsub(/^.*\[/,""); gsub(/\].*$/,""); print}'
;;
scan)
connmanctl scan wifi 2>/dev/null
;;
scanlist)
set_wifi scan 2>/dev/null
list_wifi | awk '{sub(/\S+=/,"",$0);print}'
;;
service)
get_wifi_service "${SSID}"
;;
setpowersave)
set_powersave
;;
setprofile)
set_profile
;;
esac

View file

@ -0,0 +1,11 @@
[Unit]
Description=Start bluetooth agent
After=bluetooth.service
PartOf=bluetooth.service
[Service]
Type=simple
ExecStart=/usr/bin/batocera-bluetooth-agent
[Install]
WantedBy=bluetooth.service

View file

@ -0,0 +1,14 @@
[Unit]
Description=JELOS user autostart script
Before=autostart.service
After=systemd-tmpfiles-setup.service
[Service]
Type=oneshot
Environment=HOME=/storage
EnvironmentFile=/etc/profile
ExecStart=/usr/bin/automount
RemainAfterExit=yes
[Install]
WantedBy=jelos.target

View file

@ -0,0 +1,9 @@
[Unit]
Description=jelos
Requires=multi-user.target graphical.target
After=graphical.target
Conflicts=rescue.target
AllowIsolate=yes
[Install]
Alias=default.target

View file

@ -0,0 +1,12 @@
[Unit]
Description=Back up the system config before shutting down
DefaultDependencies=no
Before=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/bin/chksysconfig backup
TimeoutStartSec=0
[Install]
WantedBy=shutdown.target

View file

@ -13,7 +13,7 @@ PKG_DEPENDS_TARGET="toolchain squashfs-tools:host dosfstools:host fakeroot:host
${BOOTLOADER} busybox umtprd util-linux usb-modeswitch unzip poppler jq socat \
p7zip file initramfs grep wget util-linux zstd lz4 empty lzo libzip \
bash coreutils modules system-utils autostart quirks powerstate gnupg \
gzip six lynx xmlstarlet vim pyudev dialog dbus-python network jelos"
gzip six lynx xmlstarlet vim pyudev dialog dbus-python network rocknix"
PKG_UI="emulationstation es-themes textviewer"

View file

@ -3,7 +3,7 @@
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)
###
### Simple script to build JELOS
### Simple script to build ROCKNX
###
if [ !"${ARCH}" == true ]