2023-05-12 20:26:09 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
compress_game() {
|
|
|
|
# Function for compressing one or more files to .chd format
|
2024-02-22 19:48:43 +00:00
|
|
|
# USAGE: compress_game $format $full_path_to_input_file $system(optional)
|
2023-05-12 20:26:09 +00:00
|
|
|
local file="$2"
|
|
|
|
local filename_no_path=$(basename "$file")
|
|
|
|
local filename_no_extension="${filename_no_path%.*}"
|
2025-02-06 07:13:30 +00:00
|
|
|
local filename_extension="${filename_no_path##*.}"
|
2025-02-13 07:35:42 +00:00
|
|
|
local source_file=$(dirname "$(realpath "$file")")"/""$(basename "$file")"
|
2023-05-12 20:26:09 +00:00
|
|
|
local dest_file=$(dirname "$(realpath "$file")")"/""$filename_no_extension"
|
|
|
|
|
|
|
|
if [[ "$1" == "chd" ]]; then
|
2024-03-19 19:04:01 +00:00
|
|
|
case "$3" in # Check platform-specific compression options
|
|
|
|
"psp" )
|
|
|
|
/app/bin/chdman createdvd --hunksize 2048 -i "$source_file" -o "$dest_file".chd -c zstd
|
|
|
|
;;
|
|
|
|
"ps2" )
|
2025-02-06 07:13:30 +00:00
|
|
|
if [[ "$filename_extension" == "cue" ]]; then
|
|
|
|
/app/bin/chdman createcd -i "$source_file" -o "$dest_file".chd
|
|
|
|
else
|
|
|
|
/app/bin/chdman createdvd -i "$source_file" -o "$dest_file".chd -c zstd
|
|
|
|
fi
|
2024-03-19 19:04:01 +00:00
|
|
|
;;
|
|
|
|
* )
|
2024-03-19 18:53:23 +00:00
|
|
|
/app/bin/chdman createcd -i "$source_file" -o "$dest_file".chd
|
2024-03-19 19:04:01 +00:00
|
|
|
;;
|
|
|
|
esac
|
2023-05-12 20:26:09 +00:00
|
|
|
elif [[ "$1" == "zip" ]]; then
|
|
|
|
zip -jq9 "$dest_file".zip "$source_file"
|
|
|
|
elif [[ "$1" == "rvz" ]]; then
|
|
|
|
dolphin-tool convert -f rvz -b 131072 -c zstd -l 5 -i "$source_file" -o "$dest_file.rvz"
|
|
|
|
fi
|
2024-05-30 15:35:42 +00:00
|
|
|
|
|
|
|
if [[ $post_compression_cleanup == "true" ]]; then # Remove file(s) if requested
|
2024-06-27 12:52:41 +00:00
|
|
|
if [[ -f "${file%.*}.$1" ]]; then
|
2024-05-30 15:35:42 +00:00
|
|
|
log i "Performing post-compression file cleanup"
|
|
|
|
if [[ "$file" == *".cue" ]]; then
|
|
|
|
local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
|
|
|
|
local file_path=$(dirname "$(realpath "$file")")
|
|
|
|
while IFS= read -r line
|
|
|
|
do
|
|
|
|
log i "Removing file $file_path/$line"
|
|
|
|
rm -f "$file_path/$line"
|
|
|
|
done < <(printf '%s\n' "$cue_bin_files")
|
2024-06-27 12:53:12 +00:00
|
|
|
log i "Removing file $(realpath "$file")"
|
2024-12-05 18:43:27 +00:00
|
|
|
rm -f "$(realpath "$file")"
|
2024-05-30 15:35:42 +00:00
|
|
|
else
|
2024-06-27 12:53:12 +00:00
|
|
|
log i "Removing file $(realpath "$file")"
|
2024-05-30 15:35:42 +00:00
|
|
|
rm -f "$(realpath "$file")"
|
|
|
|
fi
|
|
|
|
else
|
2024-06-27 12:52:41 +00:00
|
|
|
log i "Compressed file ${file%.*}.$1 not found, skipping original file deletion"
|
2024-05-30 15:35:42 +00:00
|
|
|
fi
|
|
|
|
fi
|
2023-05-12 20:26:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
find_compatible_compression_format() {
|
|
|
|
# This function will determine what compression format, if any, the file and system are compatible with
|
|
|
|
# USAGE: find_compatible_compression_format "$file"
|
|
|
|
local normalized_filename=$(echo "$1" | tr '[:upper:]' '[:lower:]')
|
|
|
|
local system=$(echo "$1" | grep -oE "$roms_folder/[^/]+" | grep -oE "[^/]+$")
|
|
|
|
|
2024-08-15 14:42:40 +00:00
|
|
|
# Extract the relevant lists from the JSON file
|
|
|
|
local chd_systems=$(jq -r '.compression_targets.chd[]' $features)
|
|
|
|
local rvz_systems=$(jq -r '.compression_targets.rvz[]' $features)
|
|
|
|
local zip_systems=$(jq -r '.compression_targets.zip[]' $features)
|
|
|
|
local zip_compressable_extensions=$(jq -r '.zip_compressable_extensions[]' $features)
|
|
|
|
|
|
|
|
if [[ $(validate_for_chd "$1") == "true" ]] && echo "$chd_systems" | grep -q "\b$system\b"; then
|
2023-05-12 20:26:09 +00:00
|
|
|
echo "chd"
|
2024-08-15 14:42:40 +00:00
|
|
|
elif echo "$zip_compressable_extensions" | grep -qF ".${normalized_filename##*.}" && echo "$zip_systems" | grep -q "\b$system\b"; then
|
2023-05-12 20:26:09 +00:00
|
|
|
echo "zip"
|
2024-08-15 14:42:40 +00:00
|
|
|
elif echo "$normalized_filename" | grep -qE '\.iso|\.gcm' && echo "$rvz_systems" | grep -q "\b$system\b"; then
|
2023-05-12 20:26:09 +00:00
|
|
|
echo "rvz"
|
2024-08-15 14:42:40 +00:00
|
|
|
elif echo "$normalized_filename" | grep -qE '\.iso' && echo "$chd_systems" | grep -q "\b$system\b"; then
|
2024-02-27 14:09:05 +00:00
|
|
|
echo "cso"
|
2023-05-12 20:26:09 +00:00
|
|
|
else
|
|
|
|
# If no compatible format can be found for the input file
|
|
|
|
echo "none"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2024-08-15 14:42:40 +00:00
|
|
|
|
2023-05-12 20:26:09 +00:00
|
|
|
validate_for_chd() {
|
|
|
|
# Function for validating chd compression candidates, and compresses if validation passes. Supports .cue, .iso and .gdi formats ONLY
|
|
|
|
# USAGE: validate_for_chd $input_file
|
|
|
|
|
|
|
|
local file="$1"
|
|
|
|
local normalized_filename=$(echo "$file" | tr '[:upper:]' '[:lower:]')
|
|
|
|
local file_validated="false"
|
2024-04-08 13:34:21 +00:00
|
|
|
log i "Validating file: $file"
|
2023-05-12 20:26:09 +00:00
|
|
|
if echo "$normalized_filename" | grep -qE '\.iso|\.cue|\.gdi'; then
|
2024-04-08 13:34:21 +00:00
|
|
|
log i ".cue/.iso/.gdi file detected"
|
2023-05-12 20:26:09 +00:00
|
|
|
local file_path=$(dirname "$(realpath "$file")")
|
|
|
|
local file_base_name=$(basename "$file")
|
|
|
|
local file_name=${file_base_name%.*}
|
|
|
|
if [[ "$normalized_filename" == *".cue" ]]; then # Validate .cue file
|
|
|
|
if [[ ! "$file_path" == *"dreamcast"* ]]; then # .bin/.cue compression may not work for Dreamcast, only GDI or ISO # TODO: verify
|
2024-04-08 13:34:21 +00:00
|
|
|
log i "Validating .cue associated .bin files"
|
2023-05-12 20:26:09 +00:00
|
|
|
local cue_bin_files=$(grep -o -P "(?<=FILE \").*(?=\".*$)" "$file")
|
2024-04-08 13:34:21 +00:00
|
|
|
log i "Associated bin files read:"
|
2024-05-14 17:26:52 +00:00
|
|
|
log i "$(printf '%s\n' "$cue_bin_files")"
|
2023-05-12 20:26:09 +00:00
|
|
|
if [[ ! -z "$cue_bin_files" ]]; then
|
|
|
|
while IFS= read -r line
|
|
|
|
do
|
2024-04-08 13:34:21 +00:00
|
|
|
log i "Looking for $file_path/$line"
|
2023-05-12 20:26:09 +00:00
|
|
|
if [[ -f "$file_path/$line" ]]; then
|
2024-04-08 13:34:21 +00:00
|
|
|
log i ".bin file found at $file_path/$line"
|
2023-05-12 20:26:09 +00:00
|
|
|
file_validated="true"
|
|
|
|
else
|
2024-04-08 13:34:21 +00:00
|
|
|
log e ".bin file NOT found at $file_path/$line"
|
|
|
|
log e ".cue file could not be validated. Please verify your .cue file contains the correct corresponding .bin file information and retry."
|
2023-05-12 20:26:09 +00:00
|
|
|
file_validated="false"
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done < <(printf '%s\n' "$cue_bin_files")
|
|
|
|
fi
|
|
|
|
else
|
2024-04-08 13:34:21 +00:00
|
|
|
log w ".cue files not compatible with CHD compression"
|
2023-05-12 20:26:09 +00:00
|
|
|
fi
|
|
|
|
echo $file_validated
|
|
|
|
else # If file is a .iso or .gdi
|
|
|
|
file_validated="true"
|
|
|
|
echo $file_validated
|
|
|
|
fi
|
|
|
|
else
|
2024-04-08 13:34:21 +00:00
|
|
|
log w "File type not recognized. Supported file types are .cue, .gdi and .iso"
|
2023-05-12 20:26:09 +00:00
|
|
|
echo $file_validated
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2024-05-30 16:17:28 +00:00
|
|
|
find_compatible_games() {
|
2025-02-13 07:59:24 +00:00
|
|
|
# Supported parameters:
|
|
|
|
# "everything" - All games found (regardless of format)
|
|
|
|
# "all" - Only user-chosen games (later selected via checklist)
|
|
|
|
# "chd", "zip", "rvz" - Only games matching that compression type
|
|
|
|
|
|
|
|
log d "Started find_compatible_games with parameter: $1"
|
|
|
|
local output_file="${godot_compression_compatible_games}"
|
|
|
|
[ -f "$output_file" ] && rm -f "$output_file"
|
|
|
|
touch "$output_file"
|
|
|
|
|
|
|
|
local target_selection="$1"
|
|
|
|
local compression_format
|
2024-05-30 16:17:28 +00:00
|
|
|
if [[ "$1" == "everything" ]]; then
|
2025-02-13 07:59:24 +00:00
|
|
|
compression_format="all"
|
2024-05-30 16:17:28 +00:00
|
|
|
else
|
2025-02-13 07:59:24 +00:00
|
|
|
compression_format="$1"
|
2024-05-30 16:17:28 +00:00
|
|
|
fi
|
|
|
|
|
2025-02-13 07:59:24 +00:00
|
|
|
local compressable_systems_list
|
|
|
|
if [[ "$compression_format" == "all" ]]; then
|
|
|
|
compressable_systems_list=$(jq -r '.compression_targets | to_entries[] | .value[]' "$features")
|
2025-02-13 07:35:42 +00:00
|
|
|
log d "compressable_systems_list: $compressable_systems_list"
|
2024-05-30 16:17:28 +00:00
|
|
|
else
|
2025-02-13 07:59:24 +00:00
|
|
|
compressable_systems_list=$(jq -r '.compression_targets["'"$compression_format"'"][]' "$features")
|
2025-02-13 07:35:42 +00:00
|
|
|
log d "compressable_systems_list: $compressable_systems_list"
|
2024-05-30 16:17:28 +00:00
|
|
|
fi
|
|
|
|
|
2025-02-13 07:59:24 +00:00
|
|
|
log d "Finding compatible games for compression ($1)"
|
2025-02-13 07:35:42 +00:00
|
|
|
log d "compression_targets: $compression_targets"
|
|
|
|
|
2025-02-13 07:59:24 +00:00
|
|
|
while IFS= read -r system; do
|
2025-02-13 07:35:42 +00:00
|
|
|
log d "Checking system: $system"
|
2025-02-13 07:59:24 +00:00
|
|
|
local compression_candidates
|
2024-05-30 16:17:28 +00:00
|
|
|
compression_candidates=$(find "$roms_folder/$system" -type f -not -iname "*.txt")
|
2025-02-13 07:59:24 +00:00
|
|
|
if [[ -n "$compression_candidates" ]]; then
|
|
|
|
while IFS= read -r game; do
|
2025-02-13 07:35:42 +00:00
|
|
|
log d "Checking game: $game"
|
2025-02-13 07:59:24 +00:00
|
|
|
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
|
|
|
|
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
|
|
|
|
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
|
|
|
|
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
|
|
|
|
log d "Game $game is compatible with $compatible_compression_format compression"
|
|
|
|
echo "${game}^${compatible_compression_format}" >> "$output_file"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
2024-05-30 16:17:28 +00:00
|
|
|
done < <(printf '%s\n' "$compression_candidates")
|
|
|
|
fi
|
|
|
|
done < <(printf '%s\n' "$compressable_systems_list")
|
2025-02-13 07:35:42 +00:00
|
|
|
|
2025-02-13 07:59:24 +00:00
|
|
|
log d "Compatible games have been written to $output_file"
|
|
|
|
cat "$output_file"
|
2024-05-30 16:17:28 +00:00
|
|
|
}
|
|
|
|
|
2023-05-12 20:26:09 +00:00
|
|
|
cli_compress_single_game() {
|
|
|
|
# This function will compress a single file passed from the CLI arguments
|
|
|
|
# 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
|
2024-02-22 19:48:43 +00:00
|
|
|
local system=$(echo "$file" | grep -oE "$roms_folder/[^/]+" | grep -oE "[^/]+$")
|
2023-05-12 20:26:09 +00:00
|
|
|
local compatible_compression_format=$(find_compatible_compression_format "$file")
|
|
|
|
if [[ ! $compatible_compression_format == "none" ]]; then
|
2024-04-08 13:34:21 +00:00
|
|
|
log i "$(basename "$file") can be compressed to $compatible_compression_format"
|
2024-02-22 19:48:43 +00:00
|
|
|
compress_game "$compatible_compression_format" "$file" "$system"
|
2023-05-12 20:26:09 +00:00
|
|
|
else
|
2024-04-08 13:34:21 +00:00
|
|
|
log w "$(basename "$file") does not have any compatible compression formats."
|
2023-05-12 20:26:09 +00:00
|
|
|
fi
|
|
|
|
else
|
2024-04-08 13:34:21 +00:00
|
|
|
log w "File not found, please specify the full path to the file to be compressed."
|
2023-05-12 20:26:09 +00:00
|
|
|
fi
|
|
|
|
else
|
2024-04-08 13:34:21 +00:00
|
|
|
log i "Please use this command format \"--compress-one <path to file to compress>\""
|
2023-05-12 20:26:09 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
cli_compress_all_games() {
|
|
|
|
if echo "$1" | grep -qE 'chd|rvz|zip'; then
|
|
|
|
local compression_format="$1"
|
|
|
|
elif [[ "$1" == "all" ]]; then
|
|
|
|
local compression_format="all"
|
|
|
|
else
|
|
|
|
echo "Please enter a supported compression format. Options are \"chd\", \"rvz\", \"zip\" or \"all\""
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
local compressable_game=""
|
|
|
|
local all_compressable_games=()
|
|
|
|
if [[ $compression_format == "all" ]]; then
|
2025-02-13 07:35:42 +00:00
|
|
|
local compressable_systems_list=$(jq -r '.compression_targets | to_entries[] | .value[]' $features)
|
2023-05-12 20:26:09 +00:00
|
|
|
else
|
2025-02-13 07:35:42 +00:00
|
|
|
local compressable_systems_list=$(jq -r '.compression_targets["'"$compression_format"'"][]' $features)
|
2023-05-12 20:26:09 +00:00
|
|
|
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
|
2024-04-08 13:34:21 +00:00
|
|
|
log i "Checking files for $system"
|
2023-05-12 20:26:09 +00:00
|
|
|
while IFS= read -r file
|
|
|
|
do
|
|
|
|
local compatible_compression_format=$(find_compatible_compression_format "$file")
|
|
|
|
if [[ ! "$compatible_compression_format" == "none" ]]; then
|
2024-04-08 13:34:21 +00:00
|
|
|
log i "$(basename "$file") can be compressed to $compatible_compression_format"
|
2024-02-22 19:48:43 +00:00
|
|
|
compress_game "$compatible_compression_format" "$file" "$system"
|
2023-05-12 20:26:09 +00:00
|
|
|
else
|
2024-04-08 13:34:21 +00:00
|
|
|
log w "No compatible compression format found for $(basename "$file")"
|
2023-05-12 20:26:09 +00:00
|
|
|
fi
|
|
|
|
done < <(printf '%s\n' "$compression_candidates")
|
|
|
|
else
|
2024-04-08 13:34:21 +00:00
|
|
|
log w "No compatible files found for compression in $system"
|
2023-05-12 20:26:09 +00:00
|
|
|
fi
|
|
|
|
done < <(printf '%s\n' "$compressable_systems_list")
|
|
|
|
}
|