2023-05-12 20:26:09 +00:00
#!/bin/bash
directory_browse( ) {
# This function browses for a directory and returns the path chosen
# USAGE: path_to_be_browsed_for=$(directory_browse $action_text)
local path_selected = false
while [ $path_selected = = false ]
do
2024-06-28 20:07:35 +00:00
local target = " $( rd_zenity --file-selection --title= " Choose $1 " --directory) "
2023-11-27 15:42:56 +00:00
if [ ! -z " $target " ] #yes
2023-05-12 20:26:09 +00:00
then
2024-06-28 20:07:35 +00:00
rd_zenity --question --no-wrap --window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --title "RetroDECK" --cancel-label= "No" --ok-label "Yes" \
2023-05-12 20:26:09 +00:00
--text= " Directory $target chosen, is this correct? "
if [ $? = = 0 ]
then
path_selected = true
2023-11-27 15:42:56 +00:00
echo " $target "
2023-05-12 20:26:09 +00:00
break
fi
else
2024-06-28 20:07:35 +00:00
rd_zenity --question --no-wrap --window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --title "RetroDECK" --cancel-label= "No" --ok-label "Yes" \
2023-05-12 20:26:09 +00:00
--text= "No directory selected. Do you want to exit the selection process?"
if [ $? = = 0 ]
then
break
fi
fi
done
}
file_browse( ) {
# This function browses for a file and returns the path chosen
# USAGE: file_to_be_browsed_for=$(file_browse $action_text)
local file_selected = false
while [ $file_selected = = false ]
do
2024-06-28 20:07:35 +00:00
local target = " $( rd_zenity --file-selection --title= " Choose $1 " ) "
2023-05-12 20:26:09 +00:00
if [ ! -z " $target " ] #yes
then
2024-06-28 20:07:35 +00:00
rd_zenity --question --no-wrap --window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --title "RetroDECK" --cancel-label= "No" --ok-label "Yes" \
2023-05-12 20:26:09 +00:00
--text= " File $target chosen, is this correct? "
if [ $? = = 0 ]
then
file_selected = true
echo " $target "
break
fi
else
2024-06-28 20:07:35 +00:00
rd_zenity --question --no-wrap --window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --title "RetroDECK" --cancel-label= "No" --ok-label "Yes" \
2023-05-12 20:26:09 +00:00
--text= "No file selected. Do you want to exit the selection process?"
if [ $? = = 0 ]
then
break
fi
fi
done
}
verify_space( ) {
# Function used for verifying adequate space before moving directories around
# USAGE: verify_space $source_dir $dest_dir
# Function returns "true" if there is enough space, "false" if there is not
source_size = $( du -sk " $1 " | awk '{print $1}' )
source_size = $(( source_size+( source_size/10)) ) # Add 10% to source size for safety
dest_avail = $( df -k --output= avail " $2 " | tail -1)
if [ [ $source_size -ge $dest_avail ] ] ; then
echo "false"
else
echo "true"
fi
}
move( ) {
# Function to move a directory from one parent to another
# USAGE: move $source_dir $dest_dir
source_dir = " $( echo $1 | sed 's![^/]$!&/!' ) " # Add trailing slash if it is missing
dest_dir = " $( echo $2 | sed 's![^/]$!&/!' ) " # Add trailing slash if it is missing
2024-02-28 14:55:44 +00:00
log d " Moving \" $source_dir \" to \" $dest_dir \" "
2023-05-12 20:26:09 +00:00
(
rsync -a --remove-source-files --ignore-existing --mkpath " $source_dir " " $dest_dir " # Copy files but don't overwrite conflicts
find " $source_dir " -type d -empty -delete # Cleanup empty folders that were left behind
) |
2024-06-28 20:07:35 +00:00
rd_zenity --icon-name= net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
2023-05-12 20:26:09 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Utility - Move in Progress" \
--text= " Moving directory $( basename " $1 " ) to new location of $2 , please wait. "
if [ [ -d " $source_dir " ] ] ; then # Some conflicting files remain
2024-06-28 20:07:35 +00:00
rd_zenity --icon-name= net.retrodeck.retrodeck --error --no-wrap \
2023-05-12 20:26:09 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Utility - Move Directories" \
--text= "There were some conflicting files that were not moved.\n\nAll files that could be moved are in the new location,\nany files that already existed at the new location have not been moved and will need to be handled manually."
fi
}
2024-02-28 14:55:44 +00:00
create_dir( ) {
# A simple function that creates a directory checking if is still there while logging the activity
# If -d it will delete it prior the creation
if [ [ " $1 " = = "-d" ] ] ; then
# If "force" flag is provided, delete the directory first
shift # Remove the first argument (-f)
if [ [ -e " $1 " ] ] ; then
rm -rf " $1 " # Forcefully delete the directory
log d " Found \" $1 \", deleting it. "
fi
fi
if [ [ ! -d " $1 " ] ] ; then
mkdir -p " $1 " # Create directory if it doesn't exist
log d " Created directory: $1 "
else
log d " Directory \" $1 \" already exists, skipping. "
fi
}
2024-02-05 16:10:18 +00:00
download_file( ) {
# Function to download file from the Internet, with Zenity progress bar
# USAGE: download_file $source_url $file_dest $file_name
# source_url is the location the file is downloaded from
# file_dest is the destination the file should be in the filesystem, needs filename included!
# file_name is a user-readable file name or description to be put in the Zenity dialog
(
2024-02-23 18:05:14 +00:00
wget " $1 " -O " $2 " -q
2024-02-05 16:10:18 +00:00
) |
2024-06-28 20:07:35 +00:00
rd_zenity --progress \
2024-02-05 16:10:18 +00:00
--title= "Downloading File" \
--text= " Downloading $3 ... " \
2024-02-23 18:05:14 +00:00
--pulsate \
2024-02-05 16:10:18 +00:00
--auto-close
}
2023-05-12 20:26:09 +00:00
update_rd_conf( ) {
# This function will import a default retrodeck.cfg file and update it with any current settings. This will allow us to expand the file over time while retaining current user settings.
# USAGE: update_rd_conf
# STAGE 1: For current files that haven't been broken into sections yet, where every setting name is unique
conf_read # Read current settings into memory
mv -f $rd_conf $rd_conf_backup # Backup config file before update
cp $rd_defaults $rd_conf # Copy defaults file into place
conf_write # Write old values into new default file
# STAGE 2: To handle presets sections that use duplicate setting names
generate_single_patch $rd_defaults $rd_conf_backup $rd_update_patch retrodeck # Create a patch file for differences between defaults and current user settings
sed -i '/change^^version/d' $rd_update_patch # Remove version line from temporary patch file
deploy_single_patch $rd_defaults $rd_update_patch $rd_conf # Re-apply user settings to defaults file
set_setting_value $rd_conf "version" " $hard_version " retrodeck # Set version of currently running RetroDECK to updated retrodeck.cfg
rm -f $rd_update_patch # Cleanup temporary patch file
conf_read # Read all settings into memory
2023-05-16 14:21:23 +00:00
# STAGE 3: Eliminate any preset incompatibility with existing user settings and new defaults
2023-05-12 20:26:09 +00:00
2024-08-07 07:20:27 +00:00
# Fetch incompatible presets from JSON and create a lookup list
incompatible_presets = $( jq -r '
.incompatible_presets | to_entries[ ] |
[
"\(.key):\(.value)" ,
"\(.value):\(.key)"
] | join( "\n" )
' config/retrodeck/reference_lists/features.json)
2023-05-12 20:26:09 +00:00
while IFS = read -r current_setting_line # Read the existing retrodeck.cfg
do
if [ [ ( ! -z " $current_setting_line " ) && ( ! " $current_setting_line " = = "#" *) && ( ! " $current_setting_line " = = "[]" ) ] ] ; then # If the line has a valid entry in it
if [ [ ! -z $( grep -o -P " ^\[.+?\] $" <<< " $current_setting_line " ) ] ] ; then # If the line is a section header
local current_section = $( sed 's^[][]^^g' <<< $current_setting_line ) # Remove brackets from section name
else
2023-05-16 14:21:23 +00:00
if [ [ ! ( " $current_section " = = "" || " $current_section " = = "paths" || " $current_section " = = "options" || " $current_section " = = "cheevos" || " $current_section " = = "cheevos_hardcore" ) ] ] ; then
local system_name = $( get_setting_name " $current_setting_line " "retrodeck" ) # Read the variable name from the current line
local system_enabled = $( get_setting_value " $rd_conf " " $system_name " "retrodeck" " $current_section " ) # Read the variables value from active retrodeck.cfg
local default_setting = $( get_setting_value " $rd_defaults " " $system_name " "retrodeck" " $current_section " ) # Read the variable value from the retrodeck defaults
if [ [ " $system_enabled " = = "true" ] ] ; then
while IFS = : read -r preset_being_checked known_incompatible_preset; do
if [ [ " $current_section " = = " $preset_being_checked " ] ] ; then
if [ [ $( get_setting_value " $rd_conf " " $system_name " "retrodeck" " $known_incompatible_preset " ) = = "true" ] ] ; then
set_setting_value " $rd_conf " " $system_name " "false" "retrodeck" " $current_section "
fi
fi
2024-08-07 07:20:27 +00:00
done <<< " $incompatible_presets "
2023-05-12 20:26:09 +00:00
fi
fi
fi
fi
done < $rd_conf
}
2024-08-07 07:20:27 +00:00
2023-05-12 20:26:09 +00:00
conf_read( ) {
# This function will read the RetroDECK config file into memory
# USAGE: conf_read
while IFS = read -r current_setting_line # Read the existing retrodeck.cfg
do
if [ [ ( ! -z " $current_setting_line " ) && ( ! " $current_setting_line " = = "#" *) && ( ! " $current_setting_line " = = "[]" ) ] ] ; then # If the line has a valid entry in it
if [ [ ! -z $( grep -o -P " ^\[.+?\] $" <<< " $current_setting_line " ) ] ] ; then # If the line is a section header
local current_section = $( sed 's^[][]^^g' <<< $current_setting_line ) # Remove brackets from section name
else
if [ [ " $current_section " = = "" || " $current_section " = = "paths" || " $current_section " = = "options" ] ] ; then
local current_setting_name = $( get_setting_name " $current_setting_line " "retrodeck" ) # Read the variable name from the current line
local current_setting_value = $( get_setting_value " $rd_conf " " $current_setting_name " "retrodeck" " $current_section " ) # Read the variables value from retrodeck.cfg
2023-11-27 15:42:56 +00:00
declare -g " $current_setting_name = $current_setting_value " # Write the current setting name and value to memory
2023-05-12 20:26:09 +00:00
fi
fi
fi
done < $rd_conf
}
2023-05-16 14:21:23 +00:00
conf_write( ) {
# This function will update the RetroDECK config file with matching variables from memory
# USAGE: conf_write
while IFS = read -r current_setting_line # Read the existing retrodeck.cfg
do
if [ [ ( ! -z " $current_setting_line " ) && ( ! " $current_setting_line " = = "#" *) && ( ! " $current_setting_line " = = "[]" ) ] ] ; then # If the line has a valid entry in it
if [ [ ! -z $( grep -o -P " ^\[.+?\] $" <<< " $current_setting_line " ) ] ] ; then # If the line is a section header
local current_section = $( sed 's^[][]^^g' <<< $current_setting_line ) # Remove brackets from section name
else
if [ [ " $current_section " = = "" || " $current_section " = = "paths" || " $current_section " = = "options" ] ] ; then
local current_setting_name = $( get_setting_name " $current_setting_line " "retrodeck" ) # Read the variable name from the current line
local current_setting_value = $( get_setting_value " $rd_conf " " $current_setting_name " "retrodeck" " $current_section " ) # Read the variables value from retrodeck.cfg
local memory_setting_value = $( eval " echo \$ ${ current_setting_name } " ) # Read the variable names' value from memory
if [ [ ! " $current_setting_value " = = " $memory_setting_value " && ! -z " $memory_setting_value " ] ] ; then # If the values are different...
set_setting_value " $rd_conf " " $current_setting_name " " $memory_setting_value " "retrodeck" " $current_section " # Update the value in retrodeck.cfg
fi
fi
fi
fi
done < $rd_conf
}
2023-05-12 20:26:09 +00:00
dir_prep( ) {
# This script is creating a symlink preserving old folder contents and moving them in the new one
# Call me with:
# dir prep "real dir" "symlink location"
2024-03-29 19:59:01 +00:00
real = " $( realpath -s $1 ) "
symlink = " $( realpath -s $2 ) "
2023-05-12 20:26:09 +00:00
2024-02-29 19:48:27 +00:00
log d " Preparing directory $symlink in $real "
2023-05-12 20:26:09 +00:00
# if the symlink dir is already a symlink, unlink it first, to prevent recursion
if [ -L " $symlink " ] ;
then
2024-02-29 19:48:27 +00:00
log d " $symlink is already a symlink, unlinking to prevent recursives "
2023-05-12 20:26:09 +00:00
unlink " $symlink "
fi
# if the dest dir exists we want to backup it
if [ -d " $symlink " ] ;
then
2024-02-29 19:48:27 +00:00
log d " $symlink found "
2023-05-12 20:26:09 +00:00
mv -f " $symlink " " $symlink .old "
fi
# if the real dir is already a symlink, unlink it first
if [ -L " $real " ] ;
then
2024-01-08 13:42:09 +00:00
log d " $real is already a symlink, unlinking to prevent recursives " #DEBUG
2023-05-12 20:26:09 +00:00
unlink " $real "
fi
# if the real dir doesn't exist we create it
if [ ! -d " $real " ] ;
then
2024-01-08 13:42:09 +00:00
log d " $real not found, creating it " #DEBUG
2024-02-28 14:55:44 +00:00
create_dir " $real "
2023-05-12 20:26:09 +00:00
fi
# creating the symlink
2024-01-08 13:42:09 +00:00
log d " linking $real in $symlink " #DEBUG
2024-02-28 14:55:44 +00:00
create_dir " $( dirname " $symlink " ) " # creating the full path except the last folder
2023-05-12 20:26:09 +00:00
ln -svf " $real " " $symlink "
# moving everything from the old folder to the new one, delete the old one
if [ -d " $symlink .old " ] ;
then
2024-01-08 13:42:09 +00:00
log d " Moving the data from $symlink .old to $real " #DEBUG
2024-02-21 16:05:01 +00:00
mv -f " $symlink .old " /{ .[ !.] ,} * " $real "
2024-01-08 13:42:09 +00:00
log d " Removing $symlink .old " #DEBUG
2023-05-12 20:26:09 +00:00
rm -rf " $symlink .old "
fi
2024-03-28 18:06:15 +00:00
log i " $symlink is now $real "
2023-05-12 20:26:09 +00:00
}
2024-06-28 20:03:36 +00:00
rd_zenity( ) {
# This function replaces the standard 'zenity' command and filters out annoying GTK errors on Steam Deck
zenity 2> >( grep -v 'Gtk' >& 2) " $@ "
}
2023-05-12 20:26:09 +00:00
update_rpcs3_firmware( ) {
2024-02-28 14:55:44 +00:00
create_dir " $roms_folder /ps3/tmp "
2023-05-12 20:26:09 +00:00
chmod 777 " $roms_folder /ps3/tmp "
2024-02-05 16:10:18 +00:00
download_file " $rpcs3_firmware " " $roms_folder /ps3/tmp/PS3UPDAT.PUP " "RPCS3 Firmware"
2023-05-12 20:26:09 +00:00
rpcs3 --installfw " $roms_folder /ps3/tmp/PS3UPDAT.PUP "
rm -rf " $roms_folder /ps3/tmp "
}
2024-02-23 18:14:39 +00:00
update_vita3k_firmware( ) {
2024-02-24 07:57:46 +00:00
download_file "http://dus01.psv.update.playstation.net/update/psv/image/2022_0209/rel_f2c7b12fe85496ec88a0391b514d6e3b/PSVUPDAT.PUP" "/tmp/PSVUPDAT.PUP" "Vita3K Firmware file: PSVUPDAT.PUP"
download_file "http://dus01.psp2.update.playstation.net/update/psp2/image/2019_0924/sd_8b5f60b56c3da8365b973dba570c53a5/PSP2UPDAT.PUP?dest=us" "/tmp/PSP2UPDAT.PUP" "Vita3K Firmware file: PSP2UPDAT.PUP"
2024-02-23 18:14:39 +00:00
Vita3K --firmware /tmp/PSVUPDAT.PUP
Vita3K --firmware /tmp/PSP2UPDAT.PUP
}
2023-05-12 20:26:09 +00:00
backup_retrodeck_userdata( ) {
2024-02-28 14:55:44 +00:00
create_dir " $backups_folder "
2023-05-12 20:26:09 +00:00
zip -rq9 " $backups_folder / $( date +"%0m%0d" ) _retrodeck_userdata.zip " " $saves_folder " " $states_folder " " $bios_folder " " $media_folder " " $themes_folder " " $logs_folder " " $screenshots_folder " " $mods_folder " " $texture_packs_folder " " $borders_folder " > $logs_folder /$( date +"%0m%0d" ) _backup_log.log
}
2023-05-15 20:33:54 +00:00
make_name_pretty( ) {
# This function will take an internal system name (like "gbc") and return a pretty version for user display ("Nintendo GameBoy Color")
# USAGE: make_name_pretty "system name"
local system = $( grep " $1 ^ " " $pretty_system_names_reference_list " )
2024-02-27 19:31:51 +00:00
if [ [ ! -z " $system " ] ] ; then
IFS = '^' read -r internal_name pretty_name < <( echo " $system " )
else
2024-06-20 17:27:51 +00:00
pretty_name = " $1 "
2024-02-27 19:31:51 +00:00
fi
2023-05-15 20:33:54 +00:00
echo " $pretty_name "
}
2023-05-12 20:26:09 +00:00
finit_browse( ) {
# Function for choosing data directory location during first/forced init
path_selected = false
while [ $path_selected = = false ]
do
2024-06-28 20:07:35 +00:00
local target = " $( rd_zenity --file-selection --title= "Choose RetroDECK data directory location" --directory) "
2023-05-12 20:26:09 +00:00
if [ [ ! -z " $target " ] ] ; then
if [ [ -w " $target " ] ] ; then
2024-06-28 20:07:35 +00:00
rd_zenity --question --no-wrap --window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --title "RetroDECK" \
2023-05-12 20:26:09 +00:00
--cancel-label= "No" \
--ok-label "Yes" \
--text= " Your RetroDECK data folder will be:\n\n $target /retrodeck\n\nis that ok? "
if [ $? = = 0 ] #yes
then
path_selected = true
echo " $target /retrodeck "
break
else
2024-06-28 20:07:35 +00:00
rd_zenity --question --no-wrap --window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --title "RetroDECK" --cancel-label= "No" --ok-label "Yes" --text= "Do you want to quit?"
2023-05-12 20:26:09 +00:00
if [ $? = = 0 ] # yes, quit
then
2023-12-16 07:55:12 +00:00
quit_retrodeck
2023-05-12 20:26:09 +00:00
fi
fi
fi
else
2024-06-28 20:07:35 +00:00
rd_zenity --error --no-wrap \
2023-05-12 20:26:09 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK" \
--ok-label "Quit" \
--text= "No location was selected. Please run RetroDECK again to retry."
2023-12-16 07:55:12 +00:00
quit_retrodeck
2023-05-12 20:26:09 +00:00
fi
done
}
finit_user_options_dialog( ) {
finit_available_options = ( )
2024-06-29 19:17:08 +00:00
while IFS = "^" read -r enabled option_name option_desc option_tag || [ [ -n " $enabled " ] ] ;
2023-05-12 20:26:09 +00:00
do
2024-06-29 19:31:05 +00:00
if [ [ ! $enabled = = "#" * ] ] && [ [ ! -z " $enabled " ] ] ; then
finit_available_options = ( " ${ finit_available_options [@] } " " $enabled " " $option_name " " $option_desc " " $option_tag " )
fi
2023-05-12 20:26:09 +00:00
done < $finit_options_list
2024-06-28 20:07:35 +00:00
local choices = $( rd_zenity \
2023-05-12 20:26:09 +00:00
--list --width= 1200 --height= 720 \
--checklist --hide-column= 4 --ok-label= "Confirm Selections" --extra-button= "Enable All" \
--separator= " " --print-column= 4 \
--text= "Choose which options to enable:" \
--column "Enabled?" \
--column "Option" \
--column "Description" \
--column "option_flag" \
" ${ finit_available_options [@] } " )
echo " ${ choices [*] } "
}
finit( ) {
# Force/First init, depending on the situation
2024-01-08 13:42:09 +00:00
log i "Executing finit"
2023-05-12 20:26:09 +00:00
# Internal or SD Card?
2024-03-04 12:46:21 +00:00
local finit_dest_choice = $( configurator_destination_choice_dialog "RetroDECK data" "Welcome to the first setup of RetroDECK.\nPlease carefully read each message prompted during the installation process to avoid any unwanted misconfigurations.\n\nWhere do you want your RetroDECK data folder to be located?\nIn this location a \"retrodeck\" folder will be created.\nThis is the folder that you will use to contain all your important files, such as your own ROMs, BIOSs, Saves and Scraped Data." )
2024-01-08 13:42:09 +00:00
log i " Choice is $finit_dest_choice "
2023-05-12 20:26:09 +00:00
2023-11-27 15:42:56 +00:00
case " $finit_dest_choice " in
2023-05-12 20:26:09 +00:00
2024-03-04 12:46:21 +00:00
"Quit" | "" ) # Back or X button quits
2023-05-12 20:26:09 +00:00
rm -f " $rd_conf " # Cleanup unfinished retrodeck.cfg if first install is interrupted
2024-01-08 13:42:09 +00:00
log i "Now quitting"
2023-12-16 07:55:12 +00:00
quit_retrodeck
2023-05-12 20:26:09 +00:00
; ;
"Internal Storage" ) # Internal
2024-01-08 13:42:09 +00:00
log i "Internal selected"
2023-05-12 20:26:09 +00:00
rdhome = " $HOME /retrodeck "
2023-11-27 15:42:56 +00:00
if [ [ -L " $rdhome " ] ] ; then #Remove old symlink from existing install, if it exists
unlink " $rdhome "
2023-05-12 20:26:09 +00:00
fi
; ;
"SD Card" )
2024-01-08 13:42:09 +00:00
log i "SD Card selected"
2023-05-12 20:26:09 +00:00
if [ ! -d " $sdcard " ] # SD Card path is not existing
then
2024-01-08 13:42:09 +00:00
log e "SD card not found"
2024-06-28 20:07:35 +00:00
rd_zenity --error --no-wrap \
2023-05-12 20:26:09 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK" \
--ok-label "Browse" \
2023-11-27 15:42:56 +00:00
--text= "SD Card was not found in the default location.\nPlease choose the SD Card root.\nA retrodeck folder will be created starting from the directory that you selected."
rdhome = " $( finit_browse) " # Calling the browse function
if [ [ -z " $rdhome " ] ] ; then # If user hit the cancel button
2023-05-12 20:26:09 +00:00
rm -f " $rd_conf " # Cleanup unfinished retrodeck.cfg if first install is interrupted
exit 2
fi
elif [ ! -w " $sdcard " ] #SD card found but not writable
then
2024-01-08 13:42:09 +00:00
log e "SD card found but not writable"
2024-06-28 20:07:35 +00:00
rd_zenity --error --no-wrap \
2023-05-12 20:26:09 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK" \
--ok-label "Quit" \
--text= "SD card was found but is not writable\nThis can happen with cards formatted on PC.\nPlease format the SD card through the Steam Deck's Game Mode and run RetroDECK again."
rm -f " $rd_conf " # Cleanup unfinished retrodeck.cfg if first install is interrupted
2024-01-08 13:42:09 +00:00
log i "Now quitting"
2023-12-16 07:55:12 +00:00
quit_retrodeck
2023-05-12 20:26:09 +00:00
else
rdhome = " $sdcard /retrodeck "
fi
; ;
"Custom Location" )
2024-01-08 13:42:09 +00:00
log i "Custom Location selected"
2024-06-28 20:07:35 +00:00
rd_zenity --info --no-wrap \
2023-05-12 20:26:09 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK" \
--ok-label "Browse" \
--text= "Please choose the root folder for the RetroDECK data.\nA retrodeck folder will be created starting from the directory that you selected."
2023-11-27 15:42:56 +00:00
rdhome = " $( finit_browse) " # Calling the browse function
if [ [ -z " $rdhome " ] ] ; then # If user hit the cancel button
2023-05-12 20:26:09 +00:00
rm -f " $rd_conf " # Cleanup unfinished retrodeck.cfg if first install is interrupted
exit 2
fi
; ;
esac
2024-06-22 12:00:07 +00:00
log i " \"retrodeck\" folder will be located in \" $rdhome \" "
2024-01-16 08:14:27 +00:00
prepare_component "reset" "retrodeck" # Parse the [paths] section of retrodeck.cfg and set the value of / create all needed folders
2023-05-12 20:26:09 +00:00
conf_write # Write the new values to retrodeck.cfg
configurator_generic_dialog "RetroDECK Initial Setup" "The next dialog will be a list of optional actions to take during the initial setup.\n\nIf you choose to not do any of these now, they can be done later through the Configurator."
local finit_options_choices = $( finit_user_options_dialog)
if [ [ " $finit_options_choices " = ~ ( rpcs3_firmware| Enable All) ] ] ; then # Additional information on the firmware install process, as the emulator needs to be manually closed
configurator_generic_dialog "RPCS3 Firmware Install" "You have chosen to install the RPCS3 firmware during the RetroDECK first setup.\n\nThis process will take several minutes and requires network access.\n\nRPCS3 will be launched automatically at the end of the RetroDECK setup process.\nOnce the firmware is installed, please close the emulator to finish the process."
fi
2023-11-27 15:42:56 +00:00
2024-02-23 18:14:39 +00:00
if [ [ " $finit_options_choices " = ~ ( vita3k_firmware| Enable All) ] ] ; then # Additional information on the firmware install process, as the emulator needs to be manually closed
configurator_generic_dialog "Vita3K Firmware Install" "You have chosen to install the Vita3K firmware during the RetroDECK first setup.\n\nThis process will take several minutes and requires network access.\n\nVita3K will be launched automatically at the end of the RetroDECK setup process.\nOnce the firmware is installed, please close the emulator to finish the process."
fi
2024-06-28 20:07:35 +00:00
rd_zenity --icon-name= net.retrodeck.retrodeck --info --no-wrap \
2023-05-12 20:26:09 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --title "RetroDECK" \
--text= "RetroDECK will now install the needed files, which can take up to one minute.\nRetroDECK will start once the process is completed.\n\nPress OK to continue."
(
2024-01-16 08:14:27 +00:00
prepare_component "reset" "all"
2023-05-16 14:21:23 +00:00
build_retrodeck_current_presets
2023-09-12 14:40:28 +00:00
deploy_helper_files
2023-11-27 15:42:56 +00:00
2023-05-12 20:26:09 +00:00
# Optional actions based on user choices
if [ [ " $finit_options_choices " = ~ ( rpcs3_firmware| Enable All) ] ] ; then
if [ [ $( check_network_connectivity) = = "true" ] ] ; then
update_rpcs3_firmware
fi
fi
2024-02-23 18:14:39 +00:00
if [ [ " $finit_options_choices " = ~ ( vita3k_firmware| Enable All) ] ] ; then
if [ [ $( check_network_connectivity) = = "true" ] ] ; then
update_vita3k_firmware
fi
fi
2023-05-12 20:26:09 +00:00
if [ [ " $finit_options_choices " = ~ ( rd_controller_profile| Enable All) ] ] ; then
install_retrodeck_controller_profile
fi
2023-11-27 15:42:56 +00:00
if [ [ " $finit_options_choices " = ~ ( rd_prepacks| Enable All) ] ] ; then
2023-05-12 20:26:09 +00:00
install_retrodeck_starterpack
fi
) |
2024-06-28 20:07:35 +00:00
rd_zenity --icon-name= net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
2023-05-12 20:26:09 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Finishing Initialization" \
--text= "RetroDECK is finishing the initial setup process, please wait."
create_lock
}
install_retrodeck_starterpack( ) {
# This function will install the roms, gamelists and metadata for the RetroDECK Starter Pack, a curated selection of games the creators of RetroDECK enjoy.
# USAGE: install_retrodeck_starterpack
2023-11-27 15:42:56 +00:00
2023-05-12 20:26:09 +00:00
## DOOM section ##
cp /app/retrodeck/extras/doom1.wad " $roms_folder /doom/doom1.wad " # No -f in case the user already has it
2024-02-28 14:55:44 +00:00
create_dir "/var/config/ES-DE/gamelists/doom"
2024-02-21 13:26:23 +00:00
if [ [ ! -f "/var/config/ES-DE/gamelists/doom/gamelist.xml" ] ] ; then # Don't overwrite an existing gamelist
cp "/app/retrodeck/rd_prepacks/doom/gamelist.xml" "/var/config/ES-DE/gamelists/doom/gamelist.xml"
2023-05-12 20:26:09 +00:00
fi
2024-02-28 14:55:44 +00:00
create_dir " $media_folder /doom "
2023-05-12 20:26:09 +00:00
unzip -oq "/app/retrodeck/rd_prepacks/doom/doom.zip" -d " $media_folder /doom/ "
}
install_retrodeck_controller_profile( ) {
# This function will install the needed files for the custom RetroDECK controller profile
# NOTE: These files need to be stored in shared locations for Steam, outside of the normal RetroDECK folders and should always be an optional user choice
2023-06-08 17:49:14 +00:00
# BIGGER NOTE: As part of this process, all emulators will need to have their configs hard-reset to match the controller mappings of the profile
2023-05-12 20:26:09 +00:00
# USAGE: install_retrodeck_controller_profile
2024-02-27 20:41:54 +00:00
if [ [ -d " $HOME /.steam/steam/controller_base/templates/ " || -d " $HOME /.var/app/com.valvesoftware.Steam/.steam/steam/controller_base/templates/ " ] ] ; then
if [ [ -d " $HOME /.steam/steam/controller_base/templates/ " ] ] ; then # If a normal binary Steam install exists
rsync -rlD --mkpath "/app/retrodeck/binding_icons/" " $HOME /.steam/steam/tenfoot/resource/images/library/controller/binding_icons/ "
2024-08-05 01:45:21 +00:00
rsync -rlD --mkpath " $config /retrodeck/controller_configs/ " " $HOME /.steam/steam/controller_base/templates/ "
2024-02-27 20:41:54 +00:00
fi
if [ [ -d " $HOME /.var/app/com.valvesoftware.Steam/.steam/steam/controller_base/templates/ " ] ] ; then # If a Flatpak Steam install exists
rsync -rlD --mkpath "/app/retrodeck/binding_icons/" " $HOME /.var/app/com.valvesoftware.Steam/.steam/steam/tenfoot/resource/images/library/controller/binding_icons/ "
2024-08-05 01:45:21 +00:00
rsync -rlD --mkpath " $config /retrodeck/controller_configs/ " " $HOME /.var/app/com.valvesoftware.Steam/.steam/steam/controller_base/templates/ "
2024-02-27 20:41:54 +00:00
fi
2023-05-12 20:26:09 +00:00
else
configurator_generic_dialog "RetroDECK Controller Profile Install" "The target directories for the controller profile do not exist.\n\nThis may happen if you do not have Steam installed or the location is does not have permission to be read."
fi
}
create_lock( ) {
# creating RetroDECK's lock file and writing the version in the config file
version = $hard_version
touch " $lockfile "
conf_write
}
update_splashscreens( ) {
# This script will purge any existing ES graphics and reload them from RO space into somewhere ES will look for it
# USAGE: update_splashscreens
2024-02-29 19:48:27 +00:00
log i "Updating splash screen"
2024-02-23 14:50:03 +00:00
rm -rf /var/config/ES-DE/resources/graphics
rsync -rlD --mkpath "/app/retrodeck/graphics/" "/var/config/ES-DE/resources/graphics/"
2024-02-23 09:00:50 +00:00
2023-05-12 20:26:09 +00:00
}
deploy_helper_files( ) {
# This script will distribute helper documentation files throughout the filesystem according to the $helper_files_list
# USAGE: deploy_helper_files
2024-06-29 19:17:08 +00:00
while IFS = '^' read -r file dest || [ [ -n " $file " ] ] ;
2023-05-12 20:26:09 +00:00
do
if [ [ ! " $file " = = "#" * ] ] && [ [ ! -z " $file " ] ] ; then
eval current_dest = " $dest "
cp -f " $helper_files_folder / $file " " $current_dest / $file "
fi
done < " $helper_files_list "
}
2024-08-07 06:35:13 +00:00
splash_screen( ) {
# This function will replace the RetroDECK startup splash screen with a different image if the day and time match a listing in the JSON data.
# USAGE: splash_screen
current_day = $( date +"%m%d" ) # Read the current date in a format that can be calculated in ranges
current_time = $( date +"%H%M" ) # Read the current time in a format that can be calculated in ranges
# Read the JSON file and extract splash screen data using jq
splash_screen = $( jq -r --arg current_day " $current_day " --arg current_time " $current_time " '
.splash_screens | to_entries[ ] |
select (
( $current_day | tonumber) >= ( .value.start_date | tonumber) and
( $current_day | tonumber) <= ( .value.end_date | tonumber) and
( $current_time | tonumber) >= ( .value.start_time | tonumber) and
( $current_time | tonumber) <= ( .value.end_time | tonumber)
) | .value.filename' config/retrodeck/reference_lists/features.json)
# Determine the splash file to use
if [ [ -n " $splash_screen " ] ] ; then
new_splash_file = " $splashscreen_dir / $splash_screen "
2023-05-12 20:26:09 +00:00
else
new_splash_file = " $default_splash_file "
fi
cp -f " $new_splash_file " " $current_splash_file " # Deploy assigned splash screen
}
2024-03-06 22:22:09 +00:00
ponzu( ) {
# This function is used to extract some specific appimages
# Check if any of the specified files exist
2024-03-08 16:41:15 +00:00
# If RetroDECK is reset Ponzu must re-cooked
2024-03-06 22:22:09 +00:00
2024-03-09 08:11:14 +00:00
log d "Checking for Ponzu"
2024-03-08 16:32:56 +00:00
local tmp_folder = "/tmp/extracted"
local ponzu_files = ( " $rdhome " /ponzu/Citra*.AppImage " $rdhome " /ponzu/citra*.AppImage " $rdhome " /ponzu/Yuzu*.AppImage " $rdhome " /ponzu/yuzu*.AppImage)
local data_dir
local appimage
local executable
2024-03-19 08:53:45 +00:00
# if the binaries are found, ponzu should be set as true into the retrodeck config
if [ -f "/var/data/ponzu/Citra/bin/citra-qt" ] ; then
log d "Citra binaries has already been installed, checking for updates and forcing the setting as true."
set_setting_value $rd_conf "akai_ponzu" "true" retrodeck "options"
fi
if [ -f "/var/data/ponzu/Yuzu/bin/yuzu" ] ; then
log d "Yuzu binaries has already been installed, checking for updates and forcing the setting as true."
set_setting_value $rd_conf "kiroi_ponzu" "true" retrodeck "options"
fi
2024-03-08 16:32:56 +00:00
# Loop through all ponzu files
for ponzu_file in " ${ ponzu_files [@] } " ; do
# Check if the current ponzu file exists
if [ -f " $ponzu_file " ] ; then
2024-03-08 20:22:30 +00:00
if [ [ " $ponzu_file " = = *itra* ] ] ; then
2024-03-08 16:32:56 +00:00
log i "Found akai ponzu! Elaborating it"
2024-03-08 16:41:15 +00:00
data_dir = "/var/data/ponzu/Citra"
2024-03-08 16:32:56 +00:00
local message = "Akai ponzu is served, enjoy"
elif [ [ " $ponzu_file " = = *uzu* ] ] ; then
log i "Found kiroi ponzu! Elaborating it"
2024-03-08 16:41:15 +00:00
data_dir = "/var/data/ponzu/Yuzu"
2024-03-08 16:32:56 +00:00
local message = "Kiroi ponzu is served, enjoy"
else
log e "AppImage not recognized, not a ponzu ingredient!"
exit 1
fi
appimage = " $ponzu_file "
2024-03-09 08:11:14 +00:00
chmod +x " $ponzu_file "
2024-03-06 22:22:09 +00:00
create_dir " $data_dir "
log d " Moving AppImage in \" $data_dir \" "
mv " $appimage " " $data_dir "
cd " $data_dir "
2024-03-09 08:11:14 +00:00
local filename = $( basename " $ponzu_file " )
log d " Setting appimage= $data_dir / $filename "
appimage = " $data_dir / $filename "
2024-03-06 22:22:09 +00:00
log d "Extracting AppImage"
" $appimage " --appimage-extract
create_dir " $tmp_folder "
log d "Cleaning up"
cp -r squashfs-root/* " $tmp_folder "
rm -rf *
2024-03-09 08:11:14 +00:00
if [ [ " $ponzu_file " = = *itra* ] ] ; then
2024-03-08 20:22:30 +00:00
mv " $tmp_folder /usr/ " ** .
2024-04-13 05:55:13 +00:00
executable = " $data_dir /bin/citra "
log d " Making $executable and $executable -qt executable "
2024-03-08 20:22:30 +00:00
chmod +x " $executable "
2024-04-13 05:55:13 +00:00
chmod +x " $executable -qt "
prepare_component "reset" "citra"
2024-03-08 17:21:43 +00:00
set_setting_value $rd_conf "akai_ponzu" "true" retrodeck "options"
elif [ [ " $ponzu_file " = = *uzu* ] ] ; then
2024-03-08 20:22:30 +00:00
mv " $tmp_folder /usr/ " ** .
executable = " $data_dir /bin/yuzu "
log d " Making $executable executable "
chmod +x " $executable "
2024-04-13 05:58:55 +00:00
prepare_component "reset" "yuzu"
2024-03-08 17:21:43 +00:00
set_setting_value $rd_conf "kiroi_ponzu" "true" retrodeck "options"
fi
2024-03-06 22:22:09 +00:00
cd -
2024-03-08 16:32:56 +00:00
log i " $message "
2024-03-09 08:11:14 +00:00
rm -rf " $tmp_folder "
2024-03-08 16:32:56 +00:00
fi
done
2024-03-09 08:11:14 +00:00
rm -rf " $rdhome /ponzu "
2024-03-06 22:22:09 +00:00
}
2024-05-30 14:54:29 +00:00
ponzu_remove( ) {
2024-03-09 13:37:42 +00:00
# Call me with yuzu or citra and I will remove them
if [ [ " $1 " = = "citra" ] ] ; then
if [ [ $( configurator_generic_question_dialog "Ponzu - Remove Citra" "Do you really want to remove Citra binaries?\n\nYour games and saves will not be deleted." ) = = "true" ] ] ; then
log i "Ponzu: removing Citra"
rm -rf "/var/data/ponzu/Citra"
set_setting_value $rd_conf "akai_ponzu" "false" retrodeck "options"
configurator_generic_dialog "Ponzu - Remove Citra" "Done, Citra is now removed from RetroDECK"
fi
elif [ [ " $1 " = = "yuzu" ] ] ; then
if [ [ $( configurator_generic_question_dialog "Ponzu - Remove Yuzu" "Do you really want to remove Yuzu binaries?\n\nYour games and saves will not be deleted." ) = = "true" ] ] ; then
log i "Ponzu: removing Yuzu"
rm -rf "/var/data/ponzu/Yuzu"
set_setting_value $rd_conf "kiroi_ponzu" "false" retrodeck "options"
configurator_generic_dialog "Ponzu - Remove Yuzu" "Done, Yuzu is now removed from RetroDECK"
fi
else
log e " Ponzu: \" $1 \" is not a vaild choice for removal, quitting "
fi
configurator_retrodeck_tools_dialog
}
2024-02-20 10:57:26 +00:00
# TODO: this function is not yet used
2024-02-20 08:43:21 +00:00
branch_selector( ) {
2024-02-28 14:29:12 +00:00
log d "Fetch branches from GitHub API excluding \"main\""
2024-08-01 15:57:19 +00:00
branches = $( curl -s https://api.github.com/repos/RetroDECK/RetroDECK/branches | grep '"name":' | awk -F '"' '$4 != "main" {print $4}' )
2024-02-20 08:43:21 +00:00
# Create an array to store branch names
branch_array = ( )
# Loop through each branch and add it to the array
while IFS = read -r branch; do
branch_array += ( " $branch " )
done <<< " $branches "
# TODO: logging - Creating array of branch names
# Display branches in a Zenity list dialog
2024-02-20 10:57:26 +00:00
selected_branch = $(
2024-06-28 20:07:35 +00:00
rd_zenity --list \
2024-02-20 10:57:26 +00:00
--icon-name= net.retrodeck.retrodeck \
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Cooker Branch - Select Branch" \
--column= "Branch" --width= 1280 --height= 800 " ${ branch_array [@] } "
)
2024-02-20 08:43:21 +00:00
# TODO: logging - Displaying branches in Zenity list dialog
# Display warning message
if [ $selected_branch ] ; then
2024-06-28 20:07:35 +00:00
rd_zenity --question --icon-name= net.retrodeck.retrodeck --no-wrap \
2024-02-20 10:57:26 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Cooker Branch - Switch Branch" \
--text= " Are you sure you want to move to \" $selected_branch \" branch? "
2024-02-20 08:43:21 +00:00
# Output selected branch
echo " Selected branch: $selected_branch " # TODO: logging - Outputting selected branch
2024-02-20 12:10:20 +00:00
set_setting_value " $rd_conf " "branch" " $selected_branch " "retrodeck" "options"
2024-02-20 12:22:06 +00:00
branch = "feat/sftp"
# Get the latest release for the specified branch
2024-08-01 15:50:57 +00:00
latest_release = $( curl -s "https://api.github.com/repos/RetroDECK/Cooker/releases" | jq " .[] | select(.target_commitish == \" $branch_name \") | .tag_name " | head -n 1)
2024-02-20 12:22:06 +00:00
# TODO: this will fail because the builds coming from the PRs are not published yet, we should fix them
2024-02-20 10:57:26 +00:00
# TODO: form a proper url: $flatpak_file_url
configurator_generic_dialog "RetroDECK Online Update" "The update process may take several minutes.\n\nAfter the update is complete, RetroDECK will close. When you run it again you will be using the latest version."
(
local desired_flatpak_file = $( curl --silent $flatpak_file_url | grep '"browser_download_url":' | sed -E 's/.*"([^"]+)".*/\1/' )
2024-02-28 14:55:44 +00:00
create_dir " $rdhome /RetroDECK_Updates "
2024-02-20 10:57:26 +00:00
wget -P " $rdhome /RetroDECK_Updates " $desired_flatpak_file
flatpak-spawn --host flatpak remove --noninteractive -y net.retrodeck.retrodeck # Remove current version before installing new one, to avoid duplicates
flatpak-spawn --host flatpak install --user --bundle --noninteractive -y " $rdhome /RetroDECK_Updates/RetroDECK-cooker.flatpak "
rm -rf " $rdhome /RetroDECK_Updates " # Cleanup old bundles to save space
) |
2024-06-28 20:07:35 +00:00
rd_zenity --icon-name= net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
2024-02-20 10:57:26 +00:00
--window-icon= "/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Updater" \
--text= " RetroDECK is updating to the latest \" $selected_branch \" version, please wait. "
configurator_generic_dialog "RetroDECK Online Update" "The update process is now complete!\n\nPlease restart RetroDECK to keep the fun going."
exit 1
2024-02-20 08:43:21 +00:00
else
2024-02-20 10:57:26 +00:00
configurator_generic_dialog "No branch selected, exiting."
2024-02-20 08:43:21 +00:00
# TODO: logging
fi
}
2023-12-16 07:55:12 +00:00
quit_retrodeck( ) {
2024-03-04 13:26:50 +00:00
log i "Quitting ES-DE"
pkill -f "es-de"
log i "Shutting down RetroDECK's framework"
pkill -f "retrodeck"
log i "See you next time"
2023-12-16 07:55:12 +00:00
}
2023-05-12 20:26:09 +00:00
start_retrodeck( ) {
2024-08-07 06:35:13 +00:00
splash_screen # Check if today has a surprise splashscreen and load it if so
2024-03-06 22:22:09 +00:00
ponzu
2024-01-04 16:34:02 +00:00
log i " Starting RetroDECK v $version "
2024-03-19 18:50:02 +00:00
es-de
2023-05-12 20:26:09 +00:00
}