Merge branch 'cooker' of https://github.com/RetroDECK/RetroDECK into cooker

This commit is contained in:
XargonWan 2025-03-26 12:44:30 +09:00
commit e1580ade33
17 changed files with 891 additions and 368 deletions

View file

@ -1,6 +1,6 @@
[
{
"parserType": "Glob",
"parserType": "Manual",
"configTitle": "RetroDECK Steam Sync",
"steamDirectory": "${steamdirglobal}",
"romDirectory": "${romsdirglobal}",
@ -8,11 +8,9 @@
"RetroDECK"
],
"executableArgs": "",
"executableModifier": "\"${exePath}\"",
"executableModifier": "",
"startInDirectory": "",
"titleModifier": "${fuzzyTitle}",
"fetchControllerTemplatesButton": null,
"removeControllersButton": null,
"steamInputEnabled": "2",
"imageProviders": [
"sgdb",
@ -29,7 +27,7 @@
]
},
"parserInputs": {
"glob": "${title}.sh"
"manualManifests": "${romsdirglobal}"
},
"executable": {
"path": "",
@ -108,7 +106,6 @@
],
"sizes": [],
"sizesHero": [],
"sizesTall": null,
"sizesIcon": []
}
},
@ -256,4 +253,4 @@
"parserId": "173908444383456337",
"version": 25
}
]
]

View file

@ -2,7 +2,7 @@
compress_game() {
# Function for compressing one or more files to .chd format
# USAGE: compress_game $format $full_path_to_input_file $system(optional)
# USAGE: compress_game $format $full_path_to_input_file $cleanup_choice $system(optional)
local file="$2"
local filename_no_path=$(basename "$file")
local filename_no_extension="${filename_no_path%.*}"
@ -11,8 +11,9 @@ compress_game() {
local dest_file=$(dirname "$(realpath "$file")")"/""$filename_no_extension"
if [[ "$1" == "chd" ]]; then
case "$3" in # Check platform-specific compression options
case "$4" in # Check platform-specific compression options
"psp" )
log d "Compressing PSP game $source_file into $dest_file"
/app/bin/chdman createdvd --hunksize 2048 -i "$source_file" -o "$dest_file".chd -c zstd
;;
"ps2" )
@ -32,7 +33,7 @@ compress_game() {
dolphin-tool convert -f rvz -b 131072 -c zstd -l 5 -i "$source_file" -o "$dest_file.rvz"
fi
if [[ $post_compression_cleanup == "true" ]]; then # Remove file(s) if requested
if [[ "$3" == "true" ]]; then # Remove file(s) if requested
if [[ -f "${file%.*}.$1" ]]; then
log i "Performing post-compression file cleanup"
if [[ "$file" == *".cue" ]]; then
@ -149,13 +150,13 @@ find_compatible_games() {
compression_format="$1"
fi
local compressable_systems_list
local compressible_systems_list
if [[ "$compression_format" == "all" ]]; then
compressable_systems_list=$(jq -r '.compression_targets | to_entries[] | .value[]' "$features")
log d "compressable_systems_list: $compressable_systems_list"
compressible_systems_list=$(jq -r '.compression_targets | to_entries[] | .value[]' "$features")
log d "compressible_systems_list: $compressible_systems_list"
else
compressable_systems_list=$(jq -r '.compression_targets["'"$compression_format"'"][]' "$features")
log d "compressable_systems_list: $compressable_systems_list"
compressible_systems_list=$(jq -r '.compression_targets["'"$compression_format"'"][]' "$features")
log d "compressible_systems_list: $compressible_systems_list"
fi
log d "Finding compatible games for compression ($1)"
@ -163,59 +164,51 @@ find_compatible_games() {
while IFS= read -r system; do
log d "Checking system: $system"
local compression_candidates
compression_candidates=$(find "$roms_folder/$system" -type f -not -iname "*.txt")
if [[ -n "$compression_candidates" ]]; then
while IFS= read -r game; do
log d "Checking game: $game"
local compatible_compression_format
compatible_compression_format=$(find_compatible_compression_format "$game")
local file_ext="${game##*.}"
case "$compression_format" in
"chd")
if [[ "$compatible_compression_format" == "chd" ]]; then
if [[ "$file_ext" == "chd" ]]; then
log d "Skipping $game because it is already a CHD file."
elif [[ ! -f "${game%.*}.chd" ]]; then
if [[ -d "$roms_folder/$system" ]]; then
local compression_candidates
compression_candidates=$(find "$roms_folder/$system" -type f -not -iname "*.txt")
if [[ -n "$compression_candidates" ]]; then
while IFS= read -r game; do
log d "Checking game: $game"
local compatible_compression_format
compatible_compression_format=$(find_compatible_compression_format "$game")
if [[ -f "${game%.*}.$compatible_compression_format" ]]; then # If a compressed version of this game already exists
log d "Skipping $game because a $compatible_compression_format version already exists."
continue
fi
local file_ext="${game##*.}"
case "$compression_format" in
"chd")
if [[ "$compatible_compression_format" == "chd" ]]; then
log d "Game $game is compatible with CHD compression"
echo "${game}^chd" >> "$output_file"
fi
fi
;;
"zip")
if [[ "$compatible_compression_format" == "zip" ]]; then
if [[ "$file_ext" == "zip" ]]; then
log d "Skipping $game because it is already a ZIP file."
elif [[ ! -f "${game%.*}.zip" ]]; then
;;
"zip")
if [[ "$compatible_compression_format" == "zip" ]]; then
log d "Game $game is compatible with ZIP compression"
echo "${game}^zip" >> "$output_file"
fi
fi
;;
"rvz")
if [[ "$compatible_compression_format" == "rvz" ]]; then
if [[ "$file_ext" == "rvz" ]]; then
log d "Skipping $game because it is already an RVZ file."
elif [[ ! -f "${game%.*}.rvz" ]]; then
;;
"rvz")
if [[ "$compatible_compression_format" == "rvz" ]]; then
log d "Game $game is compatible with RVZ compression"
echo "${game}^rvz" >> "$output_file"
fi
fi
;;
"all")
if [[ "$compatible_compression_format" != "none" ]]; then
if [[ "$file_ext" == "$compatible_compression_format" ]]; then
log d "Skipping $game because it is already in $compatible_compression_format format."
else
;;
"all")
if [[ "$compatible_compression_format" != "none" ]]; then
log d "Game $game is compatible with $compatible_compression_format compression"
echo "${game}^${compatible_compression_format}" >> "$output_file"
fi
fi
;;
esac
done < <(printf '%s\n' "$compression_candidates")
;;
esac
done < <(printf '%s\n' "$compression_candidates")
fi
else
log d "Rom folder for $system is missing, skipping"
fi
done < <(printf '%s\n' "$compressable_systems_list")
done < <(printf '%s\n' "$compressible_systems_list")
log d "Compatible games have been written to $output_file"
cat "$output_file"
@ -226,23 +219,32 @@ cli_compress_single_game() {
# USAGE: cli_compress_single_game $full_file_path
local file=$(realpath "$1")
read -p "Do you want to have the original file removed after compression is complete? Please answer y/n and press Enter: " post_compression_cleanup
read -p "RetroDECK will now attempt to compress your selected game. Press Enter key to continue..."
if [[ ! -z "$file" ]]; then
if [[ -f "$file" ]]; then
local system=$(echo "$file" | grep -oE "$roms_folder/[^/]+" | grep -oE "[^/]+$")
local compatible_compression_format=$(find_compatible_compression_format "$file")
if [[ ! $compatible_compression_format == "none" ]]; then
log i "$(basename "$file") can be compressed to $compatible_compression_format"
compress_game "$compatible_compression_format" "$file" "$system"
if [[ "$post_compression_cleanup" == "y" || "$post_compression_cleanup" == "n" ]]; then
read -p "RetroDECK will now attempt to compress your selected game. Press Enter key to continue..."
if [[ ! -z "$file" ]]; then
if [[ -f "$file" ]]; then
local system=$(echo "$file" | grep -oE "$roms_folder/[^/]+" | grep -oE "[^/]+$")
local compatible_compression_format=$(find_compatible_compression_format "$file")
if [[ ! $compatible_compression_format == "none" ]]; then
log i "$(basename "$file") can be compressed to $compatible_compression_format"
if [[ "$post_compression_cleanup" == "y" ]]; then
post_compression_cleanup="true"
else
post_compression_cleanup="false"
fi
compress_game "$compatible_compression_format" "$file" "$post_compression_cleanup" "$system"
else
log w "$(basename "$file") does not have any compatible compression formats."
fi
else
log w "$(basename "$file") does not have any compatible compression formats."
log w "File not found, please specify the full path to the file to be compressed."
fi
else
log w "File not found, please specify the full path to the file to be compressed."
fi
else
log i "Please use this command format \"--compress-one <path to file to compress>\""
fi
else
log i "Please use this command format \"--compress-one <path to file to compress>\""
fi
else
log i "The response for post-compression file cleanup was not correct. Please try again."
fi
}
cli_compress_all_games() {
@ -257,31 +259,39 @@ cli_compress_all_games() {
local compressable_game=""
local all_compressable_games=()
if [[ $compression_format == "all" ]]; then
local compressable_systems_list=$(jq -r '.compression_targets | to_entries[] | .value[]' $features)
local compressible_systems_list=$(jq -r '.compression_targets | to_entries[] | .value[]' $features)
else
local compressable_systems_list=$(jq -r '.compression_targets["'"$compression_format"'"][]' $features)
local compressible_systems_list=$(jq -r '.compression_targets["'"$compression_format"'"][]' $features)
fi
read -p "Do you want to have the original files removed after compression is complete? Please answer y/n and press Enter: " post_compression_cleanup
read -p "RetroDECK will now attempt to compress all compatible games. Press Enter key to continue..."
while IFS= read -r system # Find and validate all games that are able to be compressed with this compression type
do
local compression_candidates=$(find "$roms_folder/$system" -type f -not -iname "*.txt")
if [[ ! -z "$compression_candidates" ]]; then
log i "Checking files for $system"
while IFS= read -r file
do
local compatible_compression_format=$(find_compatible_compression_format "$file")
if [[ ! "$compatible_compression_format" == "none" ]]; then
log i "$(basename "$file") can be compressed to $compatible_compression_format"
compress_game "$compatible_compression_format" "$file" "$system"
else
log w "No compatible compression format found for $(basename "$file")"
fi
done < <(printf '%s\n' "$compression_candidates")
if [[ "$post_compression_cleanup" == "y" || "$post_compression_cleanup" == "n" ]]; then
read -p "RetroDECK will now attempt to compress all compatible games. Press Enter key to continue..."
if [[ "$post_compression_cleanup" == "y" ]]; then
post_compression_cleanup="true"
else
log w "No compatible files found for compression in $system"
post_compression_cleanup="false"
fi
done < <(printf '%s\n' "$compressable_systems_list")
while IFS= read -r system # Find and validate all games that are able to be compressed with this compression type
do
local compression_candidates=$(find "$roms_folder/$system" -type f -not -iname "*.txt")
if [[ ! -z "$compression_candidates" ]]; then
log i "Checking files for $system"
while IFS= read -r file
do
local compatible_compression_format=$(find_compatible_compression_format "$file")
if [[ ! "$compatible_compression_format" == "none" ]]; then
log i "$(basename "$file") can be compressed to $compatible_compression_format"
compress_game "$compatible_compression_format" "$file" "$post_compression_cleanup" "$system"
else
log w "No compatible compression format found for $(basename "$file")"
fi
done < <(printf '%s\n' "$compression_candidates")
else
log w "No compatible files found for compression in $system"
fi
done < <(printf '%s\n' "$compressible_systems_list")
else
log i "The response for post-compression file cleanup was not correct. Please try again."
fi
}

View file

@ -23,14 +23,14 @@ find_empty_rom_folders() {
if [[ $count -eq 0 ]]; then
# Directory is empty
empty_rom_folders_list=("${empty_rom_folders_list[@]}" "false" "$(realpath $dir)")
all_empty_folders=("${all_empty_folders[@]}" "$(realpath $dir)")
echo "$(realpath $dir)" >> "$godot_empty_roms_folders" # Godot data transfer temp file
empty_rom_folders_list=("${empty_rom_folders_list[@]}" "false" "$(realpath "$dir")")
all_empty_folders=("${all_empty_folders[@]}" "$(realpath "$dir")")
echo "$(realpath "$dir")" >> "$godot_empty_roms_folders" # Godot data transfer temp file
elif [[ $count -eq 1 ]] && [[ "$(basename "${files[0]}")" == "systeminfo.txt" ]]; then
# Directory contains only systeminfo.txt
empty_rom_folders_list=("${empty_rom_folders_list[@]}" "false" "$(realpath $dir)")
all_empty_folders=("${all_empty_folders[@]}" "$(realpath $dir)")
echo "$(realpath $dir)" >> "$godot_empty_roms_folders" # Godot data transfer temp file
empty_rom_folders_list=("${empty_rom_folders_list[@]}" "false" "$(realpath "$dir")")
all_empty_folders=("${all_empty_folders[@]}" "$(realpath "$dir")")
echo "$(realpath "$dir")" >> "$godot_empty_roms_folders" # Godot data transfer temp file
elif [[ $count -eq 2 ]] && [[ "$files" =~ "systeminfo.txt" ]]; then
contains_helper_file="false"
for helper_file in "${all_helper_files[@]}" # Compare helper file list to dir file list
@ -42,9 +42,9 @@ find_empty_rom_folders() {
done
if [[ "$contains_helper_file" == "true" ]]; then
# Directory contains only systeminfo.txt and a helper file
empty_rom_folders_list=("${empty_rom_folders_list[@]}" "false" "$(realpath $dir)")
all_empty_folders=("${all_empty_folders[@]}" "$(realpath $dir)")
echo "$(realpath $dir)" >> "$godot_empty_roms_folders" # Godot data transfer temp file
empty_rom_folders_list=("${empty_rom_folders_list[@]}" "false" "$(realpath "$dir")")
all_empty_folders=("${all_empty_folders[@]}" "$(realpath "$dir")")
echo "$(realpath "$dir")" >> "$godot_empty_roms_folders" # Godot data transfer temp file
fi
fi
done
@ -61,5 +61,4 @@ configurator_check_multifile_game_structure() {
else
configurator_generic_dialog "RetroDECK Configurator - Verify Multi-file Structure" "No incorrect multi-file game folder structures found."
fi
configurator_welcome_dialog
}

View file

@ -92,11 +92,11 @@ configurator_move_folder_dialog() {
if [[ ! "$rd_dir_name" == "rdhome" ]]; then # If a sub-folder is being moved, find it's path without the source_root. So /home/deck/retrodeck/roms becomes retrodeck/roms
local rd_dir_path="$(echo "$dir_to_move" | sed "s/.*\(retrodeck\/.*\)/\1/; s/\/$//")"
else # Otherwise just set the retrodeck root folder
local rd_dir_path="$(basename $dir_to_move)"
local rd_dir_path="$(basename "$dir_to_move")"
fi
if [[ -d "$dir_to_move" ]]; then # If the directory selected to move already exists at the expected location pulled from retrodeck.cfg
choice=$(configurator_destination_choice_dialog "RetroDECK Data" "Please choose a destination for the $(basename $dir_to_move) folder.")
choice=$(configurator_destination_choice_dialog "RetroDECK Data" "Please choose a destination for the $(basename "$dir_to_move") folder.")
case $choice in
"Internal Storage" | "SD Card" | "Custom Location" ) # If the user picks a location
@ -105,17 +105,17 @@ configurator_move_folder_dialog() {
elif [[ "$choice" == "SD Card" ]]; then # If the user wants to move the folder to the predefined SD card location, set the target as sdcard from retrodeck.cfg
local dest_root="$sdcard"
else
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "Select the parent folder you would like to store the $(basename $dir_to_move) folder in."
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "Select the parent folder you would like to store the $(basename "$dir_to_move") folder in."
local dest_root=$(directory_browse "RetroDECK directory location") # Set the destination root as the selected custom location
fi
if [[ (! -z "$dest_root") && ( -w "$dest_root") ]]; then # If user picked a destination and it is writable
if [[ (-d "$dest_root/$rd_dir_path") && (! -L "$dest_root/$rd_dir_path") && (! $rd_dir_name == "rdhome") ]] || [[ "$(realpath $dir_to_move)" == "$dest_root/$rd_dir_path" ]]; then # If the user is trying to move the folder to where it already is (excluding symlinks that will be unlinked)
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "The $(basename $dir_to_move) folder is already at that location, please pick a new one."
if [[ (-d "$dest_root/$rd_dir_path") && (! -L "$dest_root/$rd_dir_path") && (! $rd_dir_name == "rdhome") ]] || [[ "$(realpath "$dir_to_move")" == "$dest_root/$rd_dir_path" ]]; then # If the user is trying to move the folder to where it already is (excluding symlinks that will be unlinked)
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "The $(basename "$dir_to_move") folder is already at that location, please pick a new one."
configurator_move_folder_dialog "$rd_dir_name"
else
if [[ $(verify_space "$(echo $dir_to_move | sed 's/\/$//')" "$dest_root") ]]; then # Make sure there is enough space at the destination
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "Moving $(basename $dir_to_move) folder to $choice"
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "Moving $(basename "$dir_to_move") folder to $choice"
unlink "$dest_root/$rd_dir_path" # In case there is already a symlink at the picked destination
move "$dir_to_move" "$dest_root/$rd_dir_path"
if [[ -d "$dest_root/$rd_dir_path" ]]; then # If the move succeeded
@ -128,7 +128,7 @@ configurator_move_folder_dialog() {
if [[ -z $(ls -1 "$source_root/retrodeck") ]]; then # Cleanup empty old_path/retrodeck folder if it was left behind
rmdir "$source_root/retrodeck"
fi
configurator_process_complete_dialog "moving the RetroDECK data directory to internal storage"
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "moving the RetroDECK data directory to internal storage"
else
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "The moving process was not completed, please try again."
fi
@ -150,12 +150,12 @@ configurator_move_folder_dialog() {
esac
else # The folder to move was not found at the path pulled from retrodeck.cfg and it needs to be reconfigured manually.
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "The $(basename $dir_to_move) folder was not found at the expected location.\n\nThis may have happened if the folder was moved manually.\n\nPlease select the current location of the folder."
dir_to_move=$(directory_browse "RetroDECK $(basename $dir_to_move) directory location")
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "The $(basename "$dir_to_move") folder was not found at the expected location.\n\nThis may have happened if the folder was moved manually.\n\nPlease select the current location of the folder."
dir_to_move=$(directory_browse "RetroDECK $(basename "$dir_to_move") directory location")
declare -g "$rd_dir_name=$dir_to_move"
prepare_component "postmove" "all"
conf_write
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "RetroDECK $(basename $dir_to_move) folder now configured at\n$dir_to_move."
configurator_generic_dialog "RetroDECK Configurator - Move Folder" "RetroDECK $(basename "$dir_to_move") folder now configured at\n$dir_to_move."
configurator_move_folder_dialog "$rd_dir_name"
fi
}

View file

@ -8,6 +8,11 @@
: "${logging_level:=info}" # Initializing the log level variable if not already valued, this will be actually red later from the config file
rd_logs_folder="/var/config/retrodeck/logs" # Static location to write all RetroDECK-related logs
if [ -h "$rd_logs_folder" ]; then # Check if internal logging folder is already a symlink
if [ ! -e "$rd_logs_folder" ]; then # Check if internal logging folder symlink is broken
unlink "$rd_logs_folder" # Remove broken symlink so the folder is recreated when sourcing logger.sh
fi
fi
source /app/libexec/logger.sh
rotate_logs
@ -47,6 +52,7 @@ source /app/libexec/prepare_component.sh
source /app/libexec/presets.sh
source /app/libexec/configurator_functions.sh
source /app/libexec/run_game.sh
source /app/libexec/steam_sync.sh
# Static variables
rd_conf="/var/config/retrodeck/retrodeck.cfg" # RetroDECK config file path
@ -236,14 +242,13 @@ else
# Verify rdhome is where it is supposed to be.
if [[ ! -d "$rdhome" ]]; then
prev_home_path="$rdhome"
configurator_generic_dialog "RetroDECK Setup" "The RetroDECK data folder was not found in the expected location.\nThis may happen when SteamOS is updated.\n\nPlease browse to the current location of the \"retrodeck\" folder."
new_home_path=$(directory_browse "RetroDECK folder location")
set_setting_value $rd_conf "rdhome" "$new_home_path" retrodeck "paths"
conf_read
#tmplog_merger # This function is tempry(?) removed
prepare_component "retrodeck" "postmove"
prepare_component "all" "postmove"
prepare_component "postmove" "retrodeck"
prepare_component "postmove" "all"
conf_write
fi
@ -252,9 +257,11 @@ else
multi_user_data_folder="$rdhome/multi-user-data" # The default location of multi-user environment profiles
fi
logs_folder="$rdhome/logs" # The path of the logs folder, here we collect all the logs
steamsync_folder="$rdhome/.sync" # Folder containing all the steam sync launchers for SRM
steamsync_folder_tmp="$rdhome/.sync-tmp" # Temp folder containing all the steam sync launchers for SRM
backups_folder="$rdhome/backups" # Folder containing all the RetroDECK backups
# Steam ROM Manager user files and paths
steamsync_folder="$rdhome/.sync" # Folder containing favorites manifest for SRM
retrodeck_favorites_file="$steamsync_folder/retrodeck_favorites.json" # The current SRM manifest of all games that have been favorited in ES-DE
srm_log="$logs_folder/srm_log.log" # Log file for capturing the output of the most recent SRM run, for debugging purposes
retrodeck_removed_favorites="$steamsync_folder/retrodeck_removed_favorites.json" # Temporary manifest of any games that were unfavorited in ES-DE and should be removed from Steam
export GLOBAL_SOURCED=true

View file

@ -273,8 +273,8 @@ dir_prep() {
# Call me with:
# dir prep "real dir" "symlink location"
real="$(realpath -s $1)"
symlink="$(realpath -s $2)"
real="$(realpath -s "$1")"
symlink="$(realpath -s "$2")"
log d "Preparing directory $symlink in $real"
@ -354,8 +354,288 @@ update_vita3k_firmware() {
}
backup_retrodeck_userdata() {
# This function can compress one or more RetroDECK userdata folders into a single zip file for backup.
# The function can do a "complete" backup of all userdata including ROMs and ES-DE media, so can end up being very large.
# The function can also do a "core" backup of all the very important userdata files (like saves, states and gamelists) or a "custom" backup of only specified paths
# The function can take both folder names as defined in retrodeck.cfg or full paths as arguments for folders to backup
# It will also validate that all the provided paths exist and that there is enough free space to perform the backup before actually proceeding.
# It will also rotate backups so that there are only 3 maximum of each type (standard or custom)
# USAGE: backup_retrodeck_userdata complete
# backup_retrodeck_userdata core
# backup_retrodeck_userdata custom saves_folder states_folder /some/other/path
create_dir "$backups_folder"
zip -rq9 "$backups_folder/$(date +"%0m%0d")_retrodeck_userdata.zip" "$saves_folder" "$states_folder" "$bios_folder" "$media_folder" "$themes_folder" "$rdhome/ES-DE/collections" "$rdhome/ES-DE/gamelists" "$logs_folder" "$screenshots_folder" "$mods_folder" "$texture_packs_folder" "$borders_folder" > $logs_folder/$(date +"%0m%0d")_backup_log.log
backup_date=$(date +"%0m%0d_%H%M")
backup_log_file="$logs_folder/${backup_date}_${backup_type}_backup_log.log"
# Check if first argument is the type
if [[ "$1" == "complete" || "$1" == "core" || "$1" == "custom" ]]; then
backup_type="$1"
shift # Remove the first argument
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "No valid backup option chosen. Valid options are <standard> and <custom>."
fi
log e "No valid backup option chosen. Valid options are <standard> and <custom>."
exit 1
fi
zip_file="$backups_folder/retrodeck_${backup_date}_${backup_type}.zip"
# Initialize paths arrays
paths_to_backup=()
declare -A config_paths # Requires an associative (dictionary) array to work
# Build array of folder names and real paths from retrodeck.cfg
while read -r config_line; do
local current_setting_name=$(get_setting_name "$config_line" "retrodeck")
if [[ ! $current_setting_name =~ (rdhome|sdcard|backups_folder) ]]; then # Ignore these locations
local current_setting_value=$(get_setting_value "$rd_conf" "$current_setting_name" "retrodeck" "paths")
config_paths["$current_setting_name"]="$current_setting_value"
fi
done < <(grep -v '^\s*$' $rd_conf | awk '/^\[paths\]/{f=1;next} /^\[/{f=0} f')
# Determine which paths to backup
if [[ "$backup_type" == "complete" ]]; then
for folder_name in "${!config_paths[@]}"; do
path_value="${config_paths[$folder_name]}"
if [[ -e "$path_value" ]]; then
paths_to_backup+=("$path_value")
log i "Adding to backup: $folder_name = $path_value"
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The $folder_name was not found at its expected location, $path_value\nSomething may be wrong with your RetroDECK installation."
fi
log i "Warning: Path does not exist: $folder_name = $path_value"
fi
done
# Add static paths not defined in retrodeck.cfg
if [[ -e "$rdhome/ES-DE/collections" ]]; then
paths_to_backup+=("$rdhome/ES-DE/collections")
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The ES-DE collections folder was not found at its expected location, $rdhome/ES-DE/collections\nSomething may be wrong with your RetroDECK installation."
fi
log i "Warning: Path does not exist: ES-DE/collections = $rdhome/ES-DE/collections"
fi
if [[ -e "$rdhome/ES-DE/gamelists" ]]; then
paths_to_backup+=("$rdhome/ES-DE/gamelists")
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The ES-DE gamelists folder was not found at its expected location, $rdhome/ES-DE/gamelists\nSomething may be wrong with your RetroDECK installation."
fi
log i "Warning: Path does not exist: ES-DE/gamelists = $rdhome/ES-DE/gamelists"
fi
if [[ -e "$rdhome/ES-DE/custom_systems" ]]; then
paths_to_backup+=("$rdhome/ES-DE/custom_systems")
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The ES-DE custom_systems folder was not found at its expected location, $rdhome/ES-DE/custom_systems\nSomething may be wrong with your RetroDECK installation."
fi
log i "Warning: Path does not exist: ES-DE/custom_systems = $rdhome/ES-DE/custom_systems"
fi
# Check if we found any valid paths
if [[ ${#paths_to_backup[@]} -eq 0 ]]; then
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "No valid userdata folders were found.\nSomething may be wrong with your RetroDECK installation."
fi
log e "Error: No valid paths found in config file"
return 1
fi
elif [[ "$backup_type" == "core" ]]; then
for folder_name in "${!config_paths[@]}"; do
if [[ $folder_name =~ (saves_folder|states_folder|logs_folder) ]]; then # Only include these paths
path_value="${config_paths[$folder_name]}"
if [[ -e "$path_value" ]]; then
paths_to_backup+=("$path_value")
log i "Adding to backup: $folder_name = $path_value"
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The $folder_name was not found at its expected location, $path_value\nSomething may be wrong with your RetroDECK installation."
fi
log i "Warning: Path does not exist: $folder_name = $path_value"
fi
fi
done
# Add static paths not defined in retrodeck.cfg
if [[ -e "$rdhome/ES-DE/collections" ]]; then
paths_to_backup+=("$rdhome/ES-DE/collections")
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The ES-DE collections folder was not found at its expected location, $rdhome/ES-DE/collections\nSomething may be wrong with your RetroDECK installation."
fi
log i "Warning: Path does not exist: ES-DE/collections = $rdhome/ES-DE/collections"
fi
if [[ -e "$rdhome/ES-DE/gamelists" ]]; then
paths_to_backup+=("$rdhome/ES-DE/gamelists")
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The ES-DE gamelists folder was not found at its expected location, $rdhome/ES-DE/gamelists\nSomething may be wrong with your RetroDECK installation."
fi
log i "Warning: Path does not exist: ES-DE/gamelists = $rdhome/ES-DE/gamelists"
fi
if [[ -e "$rdhome/ES-DE/custom_systems" ]]; then
paths_to_backup+=("$rdhome/ES-DE/custom_systems")
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The ES-DE custom_systems folder was not found at its expected location, $rdhome/ES-DE/custom_systems\nSomething may be wrong with your RetroDECK installation."
fi
log i "Warning: Path does not exist: ES-DE/custom_systems = $rdhome/ES-DE/custom_systems"
fi
# Check if we found any valid paths
if [[ ${#paths_to_backup[@]} -eq 0 ]]; then
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "No valid userdata folders were found.\nSomething may be wrong with your RetroDECK installation."
fi
log e "Error: No valid paths found in config file"
return 1
fi
elif [[ "$backup_type" == "custom" ]]; then
if [[ "$#" -eq 0 ]]; then # Check if any paths were provided in the arguments
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "No valid backup locations were specified. Please try again."
fi
log e "Error: No paths specified for custom backup"
return 1
fi
# Process each argument - it could be a variable name or a direct path
for arg in "$@"; do
# Check if argument is a variable name in the config
if [[ -n "${config_paths[$arg]}" ]]; then
path_value="${config_paths[$arg]}"
if [[ -e "$path_value" ]]; then
paths_to_backup+=("$path_value")
log i "Added to backup: $arg = $path_value"
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The $arg was not found at its expected location, $path_value.\nSomething may be wrong with your RetroDECK installation."
fi
log e "Error: Path from variable '$arg' does not exist: $path_value"
return 1
fi
# Otherwise treat it as a direct path
elif [[ -e "$arg" ]]; then
paths_to_backup+=("$arg")
log i "Added to backup: $arg"
else
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "The path $arg was not found at its expected location.\nPlease check the path and try again."
fi
log e "Error: '$arg' is neither a valid variable name nor an existing path"
return 1
fi
done
fi
# Calculate total size of selected paths
log i "Calculating size of backup data..."
total_size=0
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then # Show progress dialog if running Zenity Configurator
total_size_file=$(mktemp) # Create temp file for Zenity subshell data extraction
(
for path in "${paths_to_backup[@]}"; do
if [[ -e "$path" ]]; then
log d "Checking size of path $path"
path_size=$(du -sk "$path" 2>/dev/null | cut -f1) # Get size in KB
path_size=$((path_size * 1024)) # Convert to bytes for calculation
total_size=$((total_size + path_size))
echo "$total_size" > $total_size_file
fi
done
) |
rd_zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Utility - Userdata Backup" \
--text="Verifying there is enough free space for the backup, please wait..."
total_size=$(cat "$total_size_file")
rm "$total_size_file" # Clean up temp file
else # If running in CLI
for path in "${paths_to_backup[@]}"; do
if [[ -e "$path" ]]; then
log d "Checking size of path $path"
path_size=$(du -sk "$path" 2>/dev/null | cut -f1) # Get size in KB
path_size=$((path_size * 1024)) # Convert to bytes for calculation
total_size=$((total_size + path_size))
fi
done
fi
# Get available space at destination
available_space=$(df -B1 "$backups_folder" | awk 'NR==2 {print $4}')
# Log sizes for reference
log i "Total size of backup data: $(numfmt --to=iec-i --suffix=B $total_size)"
log i "Available space at destination: $(numfmt --to=iec-i --suffix=B $available_space)"
# Check if we have enough space (using uncompressed size as a conservative estimate)
if [[ "$available_space" -lt "$total_size" ]]; then
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
configurator_generic_dialog "RetroDECK Userdata Backup" "There is not enough free space to perform this backup.\n\nYou need at least $(numfmt --to=iec-i --suffix=B $total_size),\nplease free up some space and try again."
fi
log e "Error: Not enough space to perform backup. Need at least $(numfmt --to=iec-i --suffix=B $total_size)"
return 1
fi
log i "Starting backup process..."
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then # Show progress dialog if running Zenity Configurator
(
# Create zip with selected paths
if zip -rq9 "$zip_file" "${paths_to_backup[@]}" >> "$backup_log_file" 2>&1; then
# Rotate backups for the specific type
cd "$backups_folder" || return 1
ls -t *_${backup_type}.zip | tail -n +4 | xargs -r rm
final_size=$(du -h "$zip_file" | cut -f1)
configurator_generic_dialog "RetroDECK Userdata Backup" "The backup to $zip_file was successful, final size is $final_size.\n\nThe backups have been rotated, keeping the last 3 of the $backup_type backup type."
log i "Backup completed successfully: $zip_file (Size: $final_size)"
log i "Older backups rotated, keeping latest 3 of type $backup_type"
if [[ ! -s "$backup_log_file" ]]; then # If the backup log file is empty, meaning zip threw no errors
rm -f "$backup_log_file"
fi
else
configurator_generic_dialog "RetroDECK Userdata Backup" "Something went wrong with the backup process. Please check the log $backup_log_file for more information."
log i "Error: Backup failed"
return 1
fi
) |
rd_zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Utility - Userdata Backup" \
--text="Compressing files into backup, please wait..."
else
if zip -rq9 "$zip_file" "${paths_to_backup[@]}" >> "$backup_log_file" 2>&1; then
# Rotate backups for the specific type
cd "$backups_folder" || return 1
ls -t *_${backup_type}.zip | tail -n +4 | xargs -r rm
final_size=$(du -h "$zip_file" | cut -f1)
log i "Backup completed successfully: $zip_file (Size: $final_size)"
log i "Older backups rotated, keeping latest 3 of type $backup_type"
if [[ ! -s "$backup_log_file" ]]; then # If the backup log file is empty, meaning zip threw no errors
rm -f "$backup_log_file"
fi
else
log i "Error: Backup failed"
return 1
fi
fi
}
make_name_pretty() {
@ -962,22 +1242,8 @@ quit_retrodeck() {
pkill -f "es-de"
# if steam sync is on do the magic
if [[ $(get_setting_value "$rd_conf" "steam_sync" retrodeck "options") == "true" ]]; then
(
source /app/libexec/steam_sync.sh
add_to_steam "$(ls "$rdhome/ES-DE/gamelists/")"
) |
rd_zenity --progress \
--title="Syncing with Steam" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--text="<span foreground='$purple'><b>\t\t\t\tSyncing favorite games with Steam</b></span>\n\n<b>NOTE: </b>This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \
--percentage=25 \
--pulsate \
--width=500 \
--height=150 \
--auto-close \
--auto-kill \
--no-cancel
if [[ $(get_setting_value "$rd_conf" "steam_sync" "retrodeck" "options") == "true" ]]; then
steam_sync
fi
log i "Shutting down RetroDECK's framework"
pkill -f "retrodeck"
@ -1128,3 +1394,58 @@ add_retrodeck_to_steam(){
log i "RetroDECK has been added to Steam"
}
repair_paths() {
# This function will verify that all folders defined in the [paths] section of retrodeck.cfg exist
# If a folder doesn't exist and is defined outside of rdhome, it will check in rdhome first and have the user browse for them manually if it isn't there either
# USAGE: repair_paths
invalid_path_found="false"
log i "Checking that all RetroDECK paths are valid"
while read -r config_line; do
local current_setting_name=$(get_setting_name "$config_line" "retrodeck")
if [[ ! $current_setting_name =~ (rdhome|sdcard) ]]; then # Ignore these locations
local current_setting_value=$(get_setting_value "$rd_conf" "$current_setting_name" "retrodeck" "paths")
if [[ ! -d "$current_setting_value" ]]; then # If the folder doesn't exist as defined
log i "$current_setting_name does not exist as defined, config is incorrect"
if [[ ! -d "$rdhome/${current_setting_value#*retrodeck/}" ]]; then # If the folder doesn't exist within defined rdhome path
if [[ ! -d "$sdcard/${current_setting_value#*retrodeck/}" ]]; then # If the folder doesn't exist within defined sdcard path
log i "$current_setting_name cannot be found at any expected location, having user locate it manually"
configurator_generic_dialog "RetroDECK Path Repair" "The RetroDECK $current_setting_name was not found in the expected location.\nThis may happen when the folder is moved manually.\n\nPlease browse to the current location of the $current_setting_name."
new_path=$(directory_browse "RetroDECK $current_setting_name location")
set_setting_value "$rd_conf" "$current_setting_name" "$new_path" retrodeck "paths"
invalid_path_found="true"
else # Folder does exist within defined sdcard path, update accordingly
log i "$current_setting_name found in $sdcard/retrodeck, correcting path config"
new_path="$sdcard/retrodeck/${current_setting_value#*retrodeck/}"
set_setting_value "$rd_conf" "$current_setting_name" "$new_path" retrodeck "paths"
invalid_path_found="true"
fi
else # Folder does exist within defined rdhome path, update accordingly
log i "$current_setting_name found in $rdhome, correcting path config"
new_path="$rdhome/${current_setting_value#*retrodeck/}"
set_setting_value "$rd_conf" "$current_setting_name" "$new_path" retrodeck "paths"
invalid_path_found="true"
fi
fi
fi
done < <(grep -v '^\s*$' $rd_conf | awk '/^\[paths\]/{f=1;next} /^\[/{f=0} f')
if [[ $invalid_path_found == "true" ]]; then
log i "One or more invalid paths repaired, fixing internal RetroDECK structures"
conf_read
dir_prep "$logs_folder" "$rd_logs_folder"
prepare_component "postmove" "all"
configurator_generic_dialog "RetroDECK Path Repair" "One or more incorrectly configured paths were repaired."
else
log i "All folders were found at their expected locations"
configurator_generic_dialog "RetroDECK Path Repair" "All RetroDECK folders were found at their expected locations."
fi
}
# Function to sanitize strings for filenames
sanitize() {
# Replace sequences of underscores with a single space
echo "$1" | sed -e 's/_\{2,\}/ /g' -e 's/_/ /g' -e 's/:/ -/g' -e 's/&/and/g' -e 's%/%and%g' -e 's/ / /g'
}

View file

@ -9,6 +9,58 @@ post_update() {
update_rd_conf
export CONFIGURATOR_GUI="zenity"
# Optional userdata backup prior to update
choice=$(rd_zenity --title "RetroDECK Update - Backup Userdata" --info --no-wrap --ok-label="No Backup" --extra-button"Backup Core Userdata" --extra-button="Backup Some Userdata" --extra-button="Backup All Userdata" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --text="Would you like to backup some or all of the RetroDECK userdata prior to update?\n\nIf you choose \"Backup Core Userdata\" only irreplaceable files (like saves, states and gamelists) will be backed up. If you choose \"Backup Some Userdata\" you will be given a choice of which folders to backup.\n\nIf you choose \"Backup All Userdata\" then ALL data (including ROMs and downloaded media) will be backed up.\nPLEASE NOTE: A full backup may take up a large amount of space, especially if you have a lot of scraped media.")
local rc=$?
if [[ $rc == "0" ]] && [[ -z "$choice" ]]; then # User selected No Backup button
log i "User chose to not backup prior to update."
else
case $choice in
"Backup Core Userdata" )
log i "User chose to backup core userdata prior to update."
backup_retrodeck_userdata "core"
;;
"Backup Some Userdata" )
log i "User chose to backup some userdata prior to update."
while read -r config_line; do
local current_setting_name=$(get_setting_name "$config_line" "retrodeck")
if [[ ! $current_setting_name =~ (rdhome|sdcard|backups_folder) ]]; then # Ignore these locations
log d "Adding $current_setting_name to compressible paths."
local current_setting_value=$(get_setting_value "$rd_conf" "$current_setting_name" "retrodeck" "paths")
compressible_paths=("${compressible_paths[@]}" "false" "$current_setting_name" "$current_setting_value")
fi
done < <(grep -v '^\s*$' $rd_conf | awk '/^\[paths\]/{f=1;next} /^\[/{f=0} f')
choice=$(rd_zenity \
--list --width=1200 --height=720 \
--checklist \
--separator="^" \
--print-column=3 \
--text="Please select folders to compress..." \
--column "Backup?" \
--column "Folder Name" \
--column "Path" \
"${compressible_paths[@]}")
choices=() # Expand choice string into passable array
IFS='^' read -ra choices <<< "$choice"
backup_retrodeck_userdata "custom" "${choices[@]}" # Expand array of choices into individual arguments
;;
"Backup All Userdata" )
log i "User chose to backup all userdata prior to update."
backup_retrodeck_userdata "complete"
;;
esac
fi
# Start of post_update actions
if [[ $(check_version_is_older_than "$version_being_updated" "0.5.0b") == "true" ]]; then # If updating from prior to save sorting change at 0.5.0b
log d "Version is older than 0.5.0b, executing save migration"
save_migration
@ -674,6 +726,29 @@ post_update() {
fi # end of 0.9.1b
if [[ $(check_version_is_older_than "$version_being_updated" "0.9.2b") == "true" ]]; then
# In version 0.9.2b, the following changes were made that required config file updates/reset or other changes to the filesystem:
# Steam Sync completely rebuilt into new manifest system. Favorites will need to be nuked and, if steam_sync is enabled will be rebuilt.
if [[ -d "$steamsync_folder" ]]; then # If Steam Sync has ever been run
steam-rom-manager nuke
steam_sync
if [[ "$(configurator_generic_question_dialog "RetroDECK 0.9.2b Steam Sync Reset" "In RetroDECK 0.9.2b we upgraded our Steam Sync feature and the shortcuts in Steam need to be rebuilt.\n\nAll of your ES-DE favorites are still unchanged.\nAny games you have favorited now will be recreated.\n\nIf you have added RetroDECK to Steam through our Configurator it will also be removed through this process.\nWould you like to add the RetroDECK shortcut again?")" == "true" ]]; then
(
# Add RetroDECK launcher to Steam
steam-rom-manager enable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager add >> "$srm_log" 2>&1
) |
rd_zenity --progress \
--title="RetroDECK Configurator: Add RetroDECK to Steam" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--text="Adding RetroDECK launcher to Steam, please wait..." \
--pulsate --width=500 --height=150 --auto-close --no-cancel
fi
fi
fi # end of 0.9.2b
# The following commands are run every time.
if [[ -d "/var/data/dolphin-emu/Load/DynamicInputTextures" ]]; then # Refresh installed textures if they have been enabled
@ -710,5 +785,7 @@ post_update() {
changelog_dialog "$version"
fi
unset CONFIGURATOR_GUI
log i "Upgrade process completed successfully."
}

View file

@ -138,8 +138,6 @@ prepare_component() {
jq '.environmentVariables.romsDirectory = "'$rdhome'/.sync"' "$srm_userdata/userSettings.json" > "$srm_userdata/tmp.json" && mv -f "$srm_userdata/tmp.json" "$srm_userdata/userSettings.json"
get_steam_user
populate_steamuser_srm
fi
if [[ "$component" =~ ^(retroarch|all)$ ]]; then
@ -561,8 +559,10 @@ prepare_component() {
if [[ "$component" =~ ^(pico8|pico-8|all)$ ]]; then
component_found="true"
if [[ ("$action" == "reset") || ("$action" == "postmove") ]]; then
if [[ -d "$roms_folder/pico8" ]]; then
dir_prep "$roms_folder/pico8" "$bios_folder/pico-8/carts" # Symlink default game location to RD roms for cleanliness (this location is overridden anyway by the --root_path launch argument anyway)
fi
dir_prep "$bios_folder/pico-8" "$HOME/.lexaloffle/pico-8" # Store binary and config files together. The .lexaloffle directory is a hard-coded location for the PICO-8 config file, cannot be changed
dir_prep "$roms_folder/pico8" "$bios_folder/pico-8/carts" # Symlink default game location to RD roms for cleanliness (this location is overridden anyway by the --root_path launch argument anyway)
dir_prep "$saves_folder/pico-8" "$bios_folder/pico-8/cdata" # PICO-8 saves folder
cp -fv "$config/pico-8/config.txt" "$bios_folder/pico-8/config.txt"
cp -fv "$config/pico-8/sdl_controllers.txt" "$bios_folder/pico-8/sdl_controllers.txt"

View file

@ -1,121 +1,167 @@
#!/bin/bash
# Function to sanitize strings for filenames
sanitize() {
# Replace sequences of underscores with a single space
echo "$1" | sed -e 's/_\{2,\}/ /g' -e 's/_/ /g' -e 's/:/ -/g' -e 's/&/and/g' -e 's%/%and%g' -e 's/ / /g'
}
steam_sync() {
add_to_steam() {
# This function looks for favorited games in all ES-DE gamelists and builds a manifest of any found.
# It then compares the new manifest to the existing one (if it exists) and runs an SRM sync if there are differences
# If all favorites were removed from ES-DE, it will remove all existing entries from Steam and then remove the favorites manifest entirely
# If there is no existing manifest, this is a first time sync and games are synced automatically
# USAGE: steam_sync
log "i" "Starting Steam Sync"
create_dir $steamsync_folder
create_dir $steamsync_folder_tmp
local srm_path="/var/config/steam-rom-manager/userData/userConfigurations.json"
if [ ! -f "$srm_path" ]; then
log "e" "Steam ROM Manager configuration not initialized! Initializing now."
prepare_component "reset" "steam-rom-manager"
fi
# Iterate through all gamelist.xml files in the folder structure
# Prepare fresh log file
echo > "$srm_log"
# Prepare new favorites manifest
echo "[]" > "${retrodeck_favorites_file}.new" # Initialize favorites JSON file
# Static definitions for all JSON objects
target="flatpak"
launch_command="run net.retrodeck.retrodeck"
startIn=""
for system_path in "$rdhome/ES-DE/gamelists/"*/; do
# Skip the CLEANUP folder
if [[ "$system_path" == *"/CLEANUP/"* ]]; then
continue
fi
# Skip folders with no gamelists
if [[ ! -f "${system_path}gamelist.xml" ]]; then
continue
fi
system=$(basename "$system_path") # Extract the folder name as the system name
gamelist="${system_path}gamelist.xml"
log d "Reading favorites for $system"
# Ensure gamelist.xml exists in the current folder
if [ -f "$gamelist" ]; then
while IFS= read -r line; do
# Detect the start of a <game> block
if [[ "$line" =~ \<game\> ]]; then
to_be_added=false # Reset the flag for a new block
path=""
name=""
system_favorites=$(xml sel -t -m "//game[favorite='true']" -v "path" -n "$gamelist")
while read -r game; do
if [[ -n "$game" ]]; then # Avoid empty lines created by xmlstarlet
local game="${game#./}" # Remove leading ./
if [[ -f "$roms_folder/$system/$game" ]]; then # Validate file exists and isn't a stale ES-DE entry for a removed file
# Construct launch options with the rom path in quotes, to handle spaces
local launchOptions="$launch_command -s $system \"$roms_folder/$system/$game\""
jq --arg title "${game%.*}" --arg target "$target" --arg launchOptions "$launchOptions" \
'. += [{"title": $title, "target": $target, "launchOptions": $launchOptions}]' "${retrodeck_favorites_file}.new" > "${retrodeck_favorites_file}.tmp" \
&& mv "${retrodeck_favorites_file}.tmp" "${retrodeck_favorites_file}.new"
fi
# Check for <favorite>true</favorite>
if [[ "$line" =~ \<favorite\>true\<\/favorite\> ]]; then
to_be_added=true
fi
# Extract the <path> and remove leading "./" if present
if [[ "$line" =~ \<path\>(.*)\<\/path\> ]]; then
path="${BASH_REMATCH[1]#./}"
fi
# Extract and sanitize <name>
if [[ "$line" =~ \<name\>(.*)\<\/name\> ]]; then
name=$(sanitize "${BASH_REMATCH[1]}")
fi
# Detect the end of a </game> block
if [[ "$line" =~ \<\/game\> ]]; then
# If the block is meaningful (marked as favorite), generate the launcher
if [ "$to_be_added" = true ] && [ -n "$path" ] && [ -n "$name" ]; then
local launcher="$steamsync_folder/${name}.sh"
local launcher_tmp="$steamsync_folder_tmp/${name}.sh"
# Create the launcher file
# Check if the launcher file does not already exist
if [ ! -e "$launcher_tmp" ]; then
log d "Creating launcher file: $launcher"
command="flatpak run net.retrodeck.retrodeck -s $system '$roms_folder/$system/$path'"
echo '#!/bin/bash' > "$launcher_tmp"
echo "$command" >> "$launcher_tmp"
chmod +x "$launcher_tmp"
else
log d "$(basename $launcher) desktop file already exists"
fi
fi
# Clean up variables for safety
to_be_added=false
path=""
name=""
fi
done < "$gamelist"
else
log "e" "Gamelist file not found for system: $system"
fi
fi
done <<< "$system_favorites"
done
# Remove the old Steam sync folder
rm -rf "$steamsync_folder"
# Move the temporary Steam sync folder to the final location
log d "Moving the temporary Steam sync folder to the final location"
mv "$steamsync_folder_tmp" "$steamsync_folder" && log d "\"$steamsync_folder_tmp\" -> \"$steamsync_folder\""
if [[ -f "$retrodeck_favorites_file" && -f "${retrodeck_favorites_file}.new" ]]; then
# Look for favorites removed between steam_sync runs, if any
removed_items=$(jq -n \
--slurpfile source "$retrodeck_favorites_file" \
--slurpfile target "${retrodeck_favorites_file}.new" \
'[$source[0][] | select(. as $item | ($target[0] | map(. == $item) | any | not))]')
fi
# Check if the Steam sync folder is empty
if [ -z "$(ls -A $steamsync_folder)" ]; then
# if empty, add the remove_from_steam function
log d "No games found, cleaning shortcut"
remove_from_steam
else
log d "Updating game list"
steam-rom-manager enable --names "RetroDECK Steam Sync"
steam-rom-manager add
# Check if there are any missing objects
if [[ "$(echo "$removed_items" | jq 'length')" -gt 0 ]]; then
log d "Some favorites were removed between sync, writing to $retrodeck_removed_favorites"
echo "$removed_items" > "$retrodeck_removed_favorites"
fi
# Decide if sync needs to happen
if [[ -f "$retrodeck_favorites_file" ]]; then # If an existing favorites manifest exists
if [[ ! "$(cat "${retrodeck_favorites_file}.new" | jq 'length')" -gt 0 ]]; then # If all favorites were removed from all gamelists, meaning new manifest is empty
log i "No favorites were found in current ES-DE gamelists, removing old entries"
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
(
# Remove old entries
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager remove >> "$srm_log" 2>&1
) |
rd_zenity --progress \
--title="Syncing with Steam" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--text="<span foreground='$purple'><b>\t\t\t\tRemoving unfavorited games from Steam</b></span>\n\n<b>NOTE: </b>This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \
--pulsate --width=500 --height=150 --auto-close --no-cancel
else
# Remove old entries
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager remove >> "$srm_log" 2>&1
fi
# Old manifest cleanup
rm "$retrodeck_favorites_file"
rm "${retrodeck_favorites_file}.new"
else # The new favorites manifest is not empty
if cmp -s "$retrodeck_favorites_file" "${retrodeck_favorites_file}.new"; then # See if the favorites manifests are the same, meaning there were no changes
log i "ES-DE favorites have not changed, no need to sync again"
rm "${retrodeck_favorites_file}.new"
else
log d "New and old manifests are different, running sync"
if [[ -f "$retrodeck_removed_favorites" ]]; then # If some favorites were removed between syncs
log d "Some favorites removed between syncs, removing unfavorited games"
# Load removed favorites as manifest and run SRM remove
mv "$retrodeck_removed_favorites" "$retrodeck_favorites_file"
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
(
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager remove >> "$srm_log" 2>&1
) |
rd_zenity --progress \
--title="Syncing with Steam" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--text="<span foreground='$purple'><b>\t\t\t\tRemoving unfavorited games from Steam</b></span>\n\n<b>NOTE: </b>This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \
--pulsate --width=500 --height=150 --auto-close --no-cancel
else
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager remove >> "$srm_log" 2>&1
fi
fi
# Load new favorites manifest as games to add during sync
mv "${retrodeck_favorites_file}.new" "$retrodeck_favorites_file"
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
(
# Add new favorites manifest
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager add >> "$srm_log" 2>&1
) |
rd_zenity --progress \
--title="Syncing with Steam" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--text="<span foreground='$purple'><b>\t\t\t\tSyncing favorite games with Steam</b></span>\n\n<b>NOTE: </b>This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \
--pulsate --width=500 --height=150 --auto-close --no-cancel
else
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager add >> "$srm_log" 2>&1
fi
fi
fi
elif [[ "$(cat "${retrodeck_favorites_file}.new" | jq 'length')" -gt 0 ]]; then # No existing favorites manifest was found, so check if new manifest has entries
log d "First time building favorites manifest, running sync"
mv "${retrodeck_favorites_file}.new" "$retrodeck_favorites_file"
if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then
(
# Add new favorites manifest
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager add >> "$srm_log" 2>&1
) |
rd_zenity --progress \
--title="Syncing with Steam" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--text="<span foreground='$purple'><b>\t\t\t\tSyncing favorite games with Steam</b></span>\n\n<b>NOTE: </b>This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \
--pulsate --width=500 --height=150 --auto-close --no-cancel
else
# Add new favorites manifest
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager add >> "$srm_log" 2>&1
fi
fi
}
# Function to remove the games from Steam, this is a workaround to make SRM remove the games as it cannot remove the games based on a empty folder
# So a dummy file must be in place to make SRM remove the other games
remove_from_steam() {
log d "Creating dummy game"
cat "" > "$steamsync_folder/CUL0.sh"
log d "Cleaning the shortcut"
steam-rom-manager enable --names "RetroDECK Steam Sync"
steam-rom-manager disable --names "RetroDECK Launcher"
steam-rom-manager remove
log d "Removing dummy game"
rm "$steamsync_folder/CUL0.sh"
steam-rom-manager enable --names "RetroDECK Launcher"
steam-rom-manager disable --names "RetroDECK Steam Sync"
}

View file

@ -86,7 +86,7 @@ modules:
# VERSION INITIALIZATION
# on main please update this with the version variable, eg: VERSION=0.8.0b
# on cooker will be VERSION=cooker-0.9.0b for example
VERSION=cooker-0.9.1b
VERSION=cooker-0.9.2b
git checkout ${GITHUB_REF_NAME}
mkdir -p ${FLATPAK_DEST}/retrodeck/

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1.88235,0,0,1.86861,-7.52941,-5.60584)">
<path d="M140,37.25C140,18.347 124.765,3 106,3L38,3C19.235,3 4,18.347 4,37.25L4,105.75C4,124.653 19.235,140 38,140L106,140C124.765,140 140,124.653 140,105.75L140,37.25Z" style="fill:rgb(17,17,17);"/>
</g>
<g transform="matrix(2.02105,0,0,2.02105,-13.4737,-13.4737)">
<g id="D" transform="matrix(-0.674885,8.26495e-17,-8.26495e-17,-0.674885,223.747,109.037)">
<path d="M172.54,-2.511C175.786,-5.757 179.378,-8.24 183.315,-9.96C187.251,-11.68 191.533,-12.54 196.16,-12.54L271.855,-12.54L271.855,6.901L196.16,6.901C194.44,6.901 192.823,7.222 191.309,7.864C189.795,8.506 188.475,9.39 187.348,10.517C186.222,11.643 185.337,12.964 184.695,14.478C184.053,15.992 183.732,17.609 183.732,19.329L183.732,96.355C183.732,97.954 184.084,99.498 184.786,100.988C185.489,102.478 186.416,103.798 187.566,104.949C188.717,106.1 190.037,107.027 191.527,107.729C193.017,108.432 194.562,108.783 196.16,108.783L271.855,108.783L271.855,128.224L196.16,128.224C193.859,128.224 191.624,127.982 189.456,127.498C187.288,127.013 185.204,126.329 183.206,125.444C181.207,124.56 179.311,123.5 177.518,122.265C175.726,121.029 174.066,119.673 172.54,118.195C169.366,115.118 166.901,111.575 165.145,107.566C163.389,103.556 162.51,99.226 162.51,94.574L162.51,21.11C162.51,16.458 163.37,12.17 165.09,8.246C166.811,4.321 169.294,0.736 172.54,-2.511Z" style="fill:white;fill-rule:nonzero;"/>
<svg width="100%" height="100%" viewBox="0 0 800 800" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(3.125,0,0,3.125,0,0)">
<g transform="matrix(1.88235,0,0,1.86861,-7.52941,-5.60584)">
<path d="M140,37.25C140,18.347 124.765,3 106,3L38,3C19.235,3 4,18.347 4,37.25L4,105.75C4,124.653 19.235,140 38,140L106,140C124.765,140 140,124.653 140,105.75L140,37.25Z" style="fill:rgb(17,17,17);"/>
</g>
<g id="Engine" transform="matrix(0.494792,-0,-0,0.494792,6.66667,6.66667)">
<use xlink:href="#_Image1" x="33.993" y="72.667" width="111px" height="111px"/>
<g id="Central-Icons" serif:id="Central Icons" transform="matrix(0.32,-0,-0,0.32,0,0)">
<use xlink:href="#_Image1" x="135.918" y="251.889" width="296px" height="296px"/>
</g>
<g id="D" transform="matrix(-1.36398,1.67039e-16,-1.67039e-16,-1.36398,438.73,206.895)">
<path d="M172.54,-2.511C175.786,-5.757 179.378,-8.24 183.315,-9.96C187.251,-11.68 191.533,-12.54 196.16,-12.54L271.855,-12.54L271.855,6.901L196.16,6.901C194.44,6.901 192.823,7.222 191.309,7.864C189.795,8.506 188.475,9.39 187.348,10.517C186.222,11.643 185.337,12.964 184.695,14.478C184.053,15.992 183.732,17.609 183.732,19.329L183.732,96.355C183.732,97.954 184.084,99.498 184.786,100.988C185.489,102.478 186.416,103.798 187.566,104.949C188.717,106.1 190.037,107.027 191.527,107.729C193.017,108.432 194.562,108.783 196.16,108.783L271.855,108.783L271.855,128.224L196.16,128.224C193.859,128.224 191.624,127.982 189.456,127.498C187.288,127.013 185.204,126.329 183.206,125.444C181.207,124.56 179.311,123.5 177.518,122.265C175.726,121.029 174.066,119.673 172.54,118.195C169.366,115.118 166.901,111.575 165.145,107.566C163.389,103.556 162.51,99.226 162.51,94.574L162.51,21.11C162.51,16.458 163.37,12.17 165.09,8.246C166.811,4.321 169.294,0.736 172.54,-2.511Z" style="fill:white;fill-rule:nonzero;"/>
</g>
</g>
<defs>
<image id="_Image1" width="111px" height="111px" xlink:href="data:image/png;base64,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"/>
<image id="_Image1" width="296px" height="296px" xlink:href="data:image/png;base64,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"/>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

18
res/icon-ponzu.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -109,6 +109,10 @@ while [[ $# -gt 0 ]]; do
cli_compress_all_games "$2"
shift 2
;;
--repair-paths)
repair_paths
exit 0
;;
--configurator)
sh /app/tools/configurator.sh
exit 0

View file

@ -76,6 +76,7 @@ rd_zenity --progress --no-cancel --pulsate --auto-close \
# - Update Notification
# - Add RetroDECK to Steam
# - M3U Multi-File Validator
# - Repair RetroDECK paths
# - Ponzu: Remove Yuzu
# - Ponzu: Remove Citra
# - Steam Sync
@ -108,7 +109,6 @@ rd_zenity --progress --no-cancel --pulsate --auto-close \
configurator_welcome_dialog() {
log i "Configurator: opening welcome dialog"
export CONFIGURATOR_GUI="zenity"
welcome_menu_options=(
"Settings" "Customize your RetroDECK experience with various presets and tweaks."
"Open Component" "Manually launch and configure settings for each emulator or component (for advanced users)."
@ -443,6 +443,7 @@ configurator_tools_dialog() {
"Update Notification" "Enable / Disable: Notifications for new RetroDECK versions."
"Add RetroDECK to Steam" "Add RetroDECK shortcut to Steam. Steam restart required."
"M3U Multi-File Validator" "Verify the proper structure of multi-file or multi-disc games."
"Repair RetroDECK Paths" "Repair RetroDECK folder path configs for unexpectedly missing folders."
)
if [[ $(get_setting_value "$rd_conf" "kiroi_ponzu" "retrodeck" "options") == "true" ]]; then
@ -460,26 +461,66 @@ configurator_tools_dialog() {
case $choice in
"Backup Userdata" )
log i "Configurator: opening \"$choice\" menu"
configurator_generic_dialog "RetroDECK Configurator - Backup Userdata" "This tool will compress important RetroDECK userdata (basically everything except the ROMs folder) into a zip file.\n\nThis process can take several minutes, and the resulting zip file can be found in the ~/retrodeck/backups folder."
(
backup_retrodeck_userdata
) |
rd_zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator Utility - Backup in Progress" \
--text="Backing up RetroDECK userdata, please wait..."
if [[ -f "$backups_folder/$(date +"%0m%0d")_retrodeck_userdata.zip" ]]; then
configurator_generic_dialog "RetroDECK Configurator - Backup Userdata" "The backup process is now complete."
configurator_generic_dialog "RetroDECK Configurator - Backup Userdata" "This tool will compress one or more RetroDECK userdata folders into a single zip file.\n\nThis process can take several minutes, and the resulting zip file can be found in the ~/retrodeck/backups folder."
choice=$(rd_zenity --title "RetroDECK Configurator Utility - Backup Userdata" --info --no-wrap --ok-label="Cancel" --extra-button"Backup Core Userdata" --extra-button="Backup Some Userdata" --extra-button="Backup All Userdata" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --text="Would you like to compress all RetroDECK userdata folders, or only some of them?\nThe \"Core Userdata\" includes irreplaceable files such as saves, states and gamelists.\n\n A complete \"All Userdata\" backup can take up A LOT of space if you have a large library.")
local rc=$?
if [[ $rc == "0" ]] && [[ -z "$choice" ]]; then # User selected Cancel button
configurator_tools_dialog
else
configurator_generic_dialog "RetroDECK Configurator - Backup Userdata" "The backup process could not be completed,\nplease check the logs folder for more information."
case $choice in
"Backup Core Userdata" )
log i "User chose to backup core userdata prior to update."
export CONFIGURATOR_GUI="zenity"
backup_retrodeck_userdata "core"
;;
"Backup Some Userdata" )
log i "User chose to backup custom userdata prior to update."
while read -r config_line; do
local current_setting_name=$(get_setting_name "$config_line" "retrodeck")
if [[ ! $current_setting_name =~ (rdhome|sdcard|backups_folder) ]]; then # Ignore these locations
log d "Adding $current_setting_name to compressible paths."
local current_setting_value=$(get_setting_value "$rd_conf" "$current_setting_name" "retrodeck" "paths")
compressible_paths=("${compressible_paths[@]}" "false" "$current_setting_name" "$current_setting_value")
fi
done < <(grep -v '^\s*$' $rd_conf | awk '/^\[paths\]/{f=1;next} /^\[/{f=0} f')
choice=$(rd_zenity \
--list --width=1200 --height=720 \
--checklist \
--separator="^" \
--print-column=3 \
--text="Please select folders to compress..." \
--column "Backup?" \
--column "Folder Name" \
--column "Path" \
"${compressible_paths[@]}")
choices=() # Expand choice string into passable array
IFS='^' read -ra choices <<< "$choice"
export CONFIGURATOR_GUI="zenity"
backup_retrodeck_userdata "custom" "${choices[@]}" # Expand array of choices into individual arguments
;;
"Backup All Userdata" )
log i "User chose to backup all userdata prior to update."
export CONFIGURATOR_GUI="zenity"
backup_retrodeck_userdata "complete"
;;
esac
configurator_tools_dialog
fi
configurator_welcome_dialog
;;
"BIOS Checker" )
log i "Configurator: opening \"$choice\" menu"
configurator_bios_checker
configurator_tools_dialog
;;
"Games Compressor" )
@ -542,12 +583,29 @@ configurator_tools_dialog() {
;;
"Add RetroDECK to Steam" )
add_retrodeck_to_steam
(
# Add RetroDECK launcher to Steam
steam-rom-manager enable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager add >> "$srm_log" 2>&1
) |
rd_zenity --progress \
--title="RetroDECK Configurator: Add RetroDECK to Steam" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--text="Adding RetroDECK launcher to Steam, please wait..." \
--pulsate --width=500 --height=150 --auto-close --no-cancel
configurator_tools_dialog
;;
"M3U Multi-File Validator" )
log i "Configurator: opening \"$choice\" menu"
configurator_check_multifile_game_structure
configurator_tools_dialog
;;
"Repair RetroDECK Paths" )
log i "Configurator: opening \"$choice\" menu"
repair_paths
configurator_tools_dialog
;;
"Ponzu: Remove Yuzu" )
@ -658,7 +716,7 @@ configurator_data_management_dialog() {
--list --width=1200 --height=720 --title "RetroDECK Configurator - RetroDECK: Clean Empty ROM Folders" \
--checklist --hide-column=3 --ok-label="Remove Selected" --extra-button="Remove All" \
--separator="," --print-column=2 \
--text="Choose which ROM folders to remove:" \
--text="Choose which empty ROM folders to remove:" \
--column "Remove?" \
--column "System" \
"${empty_rom_folders_list[@]}")
@ -715,26 +773,31 @@ configurator_compression_tool_dialog() {
"Compress Multiple Games: CHD" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "chd"
configurator_compression_tool_dialog
;;
"Compress Multiple Games: ZIP" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "zip"
configurator_compression_tool_dialog
;;
"Compress Multiple Games: RVZ" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "rvz"
configurator_compression_tool_dialog
;;
"Compress Multiple Games: All Formats" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "all"
configurator_compression_tool_dialog
;;
"Compress All Games" )
log i "Configurator: opening \"$choice\" menu"
configurator_compress_multiple_games_dialog "everything"
configurator_compression_tool_dialog
;;
"" ) # No selection made or Back button clicked
@ -755,7 +818,7 @@ configurator_compress_single_game_dialog() {
(
echo "# Compressing $(basename "$file") to $compatible_compression_format format" # This updates the Zenity dialog
log i "Compressing $(basename "$file") to $compatible_compression_format format"
compress_game "$compatible_compression_format" "$file" "$system"
compress_game "$compatible_compression_format" "$file" "$post_compression_cleanup" "$system"
) |
rd_zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
@ -775,120 +838,86 @@ configurator_compress_single_game_dialog() {
configurator_compress_multiple_games_dialog() {
log d "Starting to compress \"$1\""
local output_file="${godot_compression_compatible_games}"
[ -f "$output_file" ] && rm -f "$output_file"
touch "$output_file"
local compressible_games_list_file="${godot_compression_compatible_games}"
[ -f "$compressible_games_list_file" ] && rm -f "$compressible_games_list_file"
touch "$compressible_games_list_file"
## --- SEARCH PHASE WITH LOADING SCREEN ---
local progress_pipe
progress_pipe=$(mktemp -u)
mkfifo "$progress_pipe"
# Launch find_compatible_games in the background (its output goes to the file)
find_compatible_games "$1" > "$output_file" &
local finder_pid=$!
# Launch a background process that writes loading messages until the search completes.
(
while kill -0 "$finder_pid" 2>/dev/null; do
echo "# Loading: Searching for compatible games..."
sleep 1
done
echo "100"
) > "$progress_pipe" &
local progress_writer_pid=$!
find_compatible_games "$1" > "$compressible_games_list_file"
) |
rd_zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator - RetroDECK: Compression Tool" --text "RetroDECK is searching for compress1ble games, please wait..."
rd_zenity --progress --pulsate --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title="RetroDECK Configurator Utility - Searching for Compressable Games" \
--text="Searching for compressable games, please wait..." < "$progress_pipe"
wait "$finder_pid"
wait "$progress_writer_pid"
rm "$progress_pipe"
if [[ -s "$output_file" ]]; then
mapfile -t all_compressable_games < "$output_file"
log d "Found the following games to compress: ${all_compressable_games[*]}"
if [[ -s "$compressible_games_list_file" ]]; then
mapfile -t all_compressible_games < "$compressible_games_list_file"
log d "Found the following games to compress: ${all_compressible_games[*]}"
else
configurator_generic_dialog "RetroDECK Configurator - Compression Tool" "No compressable files were found."
return
configurator_generic_dialog "RetroDECK Configurator - Compression Tool" "No compressible files were found."
configurator_compression_tool_dialog
fi
local games_to_compress=()
if [[ "$1" != "everything" ]]; then
local checklist_entries=()
for line in "${all_compressable_games[@]}"; do
for line in "${all_compressible_games[@]}"; do
IFS="^" read -r game comp <<< "$line"
local short_game="${game#$roms_folder}"
checklist_entries+=( "TRUE" "$short_game" "$line" )
done
local choice
choice=$(rd_zenity \
local choice=$(rd_zenity \
--list --width=1200 --height=720 --title "RetroDECK Configurator - Compression Tool" \
--checklist --hide-column=3 --ok-label="Compress Selected" --extra-button="Compress All" \
--separator="," --print-column=3 \
--separator=$'\0' --print-column=3 \
--text="Choose which games to compress:" \
--column "Compress?" \
--column "Game" \
--column "Game Full Path" \
--column "Game Full Path and Compression Format" \
"${checklist_entries[@]}")
local rc=$?
log d "User choice: $choice"
if [[ $rc == 0 && -n "$choice" ]]; then
IFS="," read -ra games_to_compress <<< "$choice"
while IFS="^" read -r game comp; do # Split Zenity choice string into compatible pairs (game^format)
games_to_compress+=("$game"^"$comp")
done <<< "$choice"
elif [[ -n "$choice" ]]; then
games_to_compress=("${all_compressable_games[@]}")
games_to_compress=("${all_compressible_games[@]}")
else
return
configurator_compression_tool_dialog
fi
else
games_to_compress=("${all_compressable_games[@]}")
games_to_compress=("${all_compressible_games[@]}")
fi
local post_compression_cleanup=$(configurator_compression_cleanup_dialog)
local total_games=${#games_to_compress[@]}
local games_left=$total_games
## --- COMPRESSION PHASE WITH PROGRESS SCREEN ---
local comp_pipe
comp_pipe=$(mktemp -u)
mkfifo "$comp_pipe"
(
for game_line in "${games_to_compress[@]}"; do
IFS="^" read -r game compression_format <<< "$game_line"
local system
system=$(echo "$game" | grep -oE "$roms_folder/[^/]+" | grep -oE "[^/]+$")
log i "Compressing $(basename "$game") into $compression_format format"
for game_line in "${games_to_compress[@]}"; do
IFS="^" read -r game compression_format <<< "$game_line"
# Launch the compression in the background.
compress_game "$compression_format" "$game" "$system" &
local comp_pid=$!
local system
system=$(echo "$game" | grep -oE "$roms_folder/[^/]+" | grep -oE "[^/]+$")
log i "Compressing $(basename "$game") into $compression_format format"
# While the compression is in progress, write a status message every second.
while kill -0 "$comp_pid" 2>/dev/null; do
echo "# Compressing $(basename "$game") into $compression_format format"
sleep 1
done
# When finished, update the progress percentage.
local progress=$(( 100 - (( 100 / total_games ) * games_left) ))
echo "$progress"
games_left=$(( games_left - 1 ))
done
echo "100"
) > "$comp_pipe" &
local comp_pid_group=$!
echo "#Compressing $(basename "$game") into $compression_format format.\n\n$games_left games left to compress." # Update Zenity dialog text
compress_game "$compression_format" "$game" "$post_compression_cleanup" "$system"
games_left=$(( games_left - 1 ))
local progress=$(( 99 - (( 99 / total_games ) * games_left) ))
log d "progress: $progress"
echo "$progress" # Update Zenity dialog progress bar
done
echo "100" # Close Zenity progress dialog when finished
) |
rd_zenity --icon-name=net.retrodeck.retrodeck --progress --no-cancel --auto-close \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck/retrodeck.svg" \
--width="800" \
--title "RetroDECK Configurator Utility - Compression in Progress" < "$comp_pipe"
wait "$comp_pid_group"
rm "$comp_pipe"
--title "RetroDECK Configurator Utility - Compression in Progress"
configurator_generic_dialog "RetroDECK Configurator - Compression Tool" "The compression process is complete!"
configurator_compression_tool_dialog
@ -1066,8 +1095,6 @@ configurator_bios_checker() {
--title "RetroDECK Configurator Utility - BIOS Check in Progress" \
--text="This check will look for BIOS files that RetroDECK has identified as working.\n\nNot all BIOS files are required for games to work, please check the BIOS description for more information on its purpose.\n\nBIOS files not known to this tool could still function.\n\nSome more advanced emulators such as Ryujinx will have additional methods to verify that the BIOS files are in working order.\n\nRetroDECK is now checking your BIOS files, please wait...\n\n" \
--width=400 --height=100
configurator_welcome_dialog
}
configurator_reset_dialog() {
@ -1199,7 +1226,7 @@ configurator_steam_sync() {
if [ $? == 0 ] # User clicked "Yes"
then
disable_steam_sync
configurator_disable_steam_sync
else # User clicked "Cancel"
configurator_welcome_dialog
fi
@ -1211,15 +1238,17 @@ configurator_steam_sync() {
if [ $? == 0 ]
then
enable_steam_sync
configurator_enable_steam_sync
else
configurator_welcome_dialog
fi
fi
}
enable_steam_sync() {
configurator_enable_steam_sync() {
set_setting_value "$rd_conf" "steam_sync" "true" retrodeck "options"
export CONFIGURATOR_GUI="zenity"
steam_sync
zenity --icon-name=net.retrodeck.retrodeck --info --no-wrap --ok-label="OK" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator - RetroDECK Steam Syncronization" \
@ -1227,10 +1256,22 @@ enable_steam_sync() {
configurator_welcome_dialog
}
disable_steam_sync() {
configurator_disable_steam_sync() {
set_setting_value "$rd_conf" "steam_sync" "false" retrodeck "options"
source /app/libexec/steam_sync.sh
remove_from_steam
# Remove only synced favorites, leave RetroDECK shortcut if it exists
(
steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1
steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1
steam-rom-manager remove >> "$srm_log" 2>&1
) |
rd_zenity --progress \
--title="Removing RetroDECK Sync from Steam" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--text="Removing synced entries from Steam, please wait..." \
--pulsate --width=500 --height=150 --auto-close --no-cancel
if [[ -f "$retrodeck_favorites_file" ]]; then
rm -f "$retrodeck_favorites_file"
fi
zenity --icon-name=net.retrodeck.retrodeck --info --no-wrap --ok-label="OK" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \
--title "RetroDECK Configurator - RetroDECK Steam Syncronization" \
@ -1382,7 +1423,6 @@ configurator_usb_import_dialog() {
"Prepare USB device" )
log i "Configurator: opening \"$choice\" menu"
configurator_generic_dialog "RetroDeck Configurator - USB Import" "If you have an SD card installed that is not currently configured in RetroDECK it may show up in this list, but not be suitable for USB import.\n\nPlease select your desired drive carefully."
external_devices=()
@ -1392,6 +1432,7 @@ configurator_usb_import_dialog() {
done < <(df --output=size,target -h | grep "/run/media/" | grep -v "$sdcard" | awk '{$1=$1;print}')
if [[ "${#external_devices[@]}" -gt 0 ]]; then
configurator_generic_dialog "RetroDeck Configurator - USB Import" "If you have an SD card installed that is not currently configured in RetroDECK it may show up in this list, but not be suitable for USB import.\n\nPlease select your desired drive carefully."
choice=$(rd_zenity --list --title="RetroDECK Configurator Utility - USB Migration Tool" --cancel-label="Back" \
--window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" --width=1200 --height=720 \
--hide-column=3 --print-column=3 \
@ -1401,9 +1442,10 @@ configurator_usb_import_dialog() {
"${external_devices[@]}")
if [[ ! -z "$choice" ]]; then
create_dir "$choice/RetroDECK Import"
es-de --home "$choice/RetroDECK Import" --create-system-dirs
rm -rf "$choice/RetroDECK Import/ES-DE" # Cleanup unnecessary folder
create_dir "$choice/RetroDECK Import/BIOS"
# Prepare default BIOS folder subfolders
create_dir "$choice/RetroDECK Import/BIOS/np2kai"