From b8a6ffa486bb334a138935faa3772c8d78b10cd2 Mon Sep 17 00:00:00 2001 From: Scan Date: Sun, 8 Sep 2024 15:58:27 -0400 Subject: [PATCH] Rework s3p_to_2dx, add args for IIDX 31 to ep_bm2dxnix (now named bm2dnix), update readme --- s3p_to_2dx | 140 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 29 deletions(-) diff --git a/s3p_to_2dx b/s3p_to_2dx index f9c46ae..b51fa14 100755 --- a/s3p_to_2dx +++ b/s3p_to_2dx @@ -1,38 +1,119 @@ #!/bin/bash -# Set the directory containing sound files -# This is usually ./sound if youre running the script out of the games data directory -SOUND_DIR="please-set-this" +# Set the directory containing sound files, typically found in /data/sound in the games "contents" +SOUND_DIR="" -# Extract .ifs file and descend into its directory -# Sound data doesn't need to be repacked into .ifs - easier for the sake of managing future updates -extract_cleanup_ifs() { - local ifs_file="$1" - echo "Extracting $ifs_file..." - ifstools "$ifs_file" || { echo "Failed to extract $ifs_file"; return 1; } - local extracted_dir="${ifs_file%.*}_ifs" - [ -d "$extracted_dir" ] && cd "$extracted_dir" || { echo "Directory $extracted_dir not found"; return 1; } +# Set alternative paths to external binaries (s3p_extract, 2dxBuild (apart of 2dxTools), ifstools, and ffmpeg) +# Otherwise, default to /usr/bin +S3P_EXTRACT_BIN="${S3P_EXTRACT_BIN:-s3p_extract}" +BUILD_2DX_BIN="${TWO_DX_BUILD_BIN:-2dxBuild}" +IFSTOOLS_BIN="${IFSTOOLS_BIN:-ifstools}" +FFMPEG_BIN="${FFMPEG_BIN:-ffmpeg}" + +# Print basic usage if required args are missing +usage() { + echo "Usage: $0 [-s ] [-e ] [-b ] [-i ] [-f ]" + exit 1 } +# Options for sound directory and custom paths +while getopts ":s:e:b:i:f:" opt; do + case $opt in + s) SOUND_DIR="$OPTARG" ;; + e) S3P_EXTRACT_BIN="$OPTARG" ;; + b) BUILD_2DX_BIN="$OPTARG" ;; + i) IFSTOOLS_BIN="$OPTARG" ;; + f) FFMPEG_BIN="$OPTARG" ;; + *) usage ;; + esac +done -# Extract and convert .s3p files -extract_convert_s3p() { - local s3p_file="$1" - echo "Processing $s3p_file..." - s3p_extract "$s3p_file" || { echo "Failed to extract $s3p_file"; return 1; } - local s3p_out_dir="${s3p_file}.out" - [ -d "$s3p_out_dir" ] && cd "$s3p_out_dir" || { echo "Directory $s3p_out_dir not found"; return 1; } +# Check if $SOUND_DIR is set +if [ -z "$SOUND_DIR" ]; then + echo "Error: SOUND_DIR is not set. Use -s to specify the sound directory." + usage +fi - for wma_file in *.wma; do - [ -e "$wma_file" ] || continue - echo -ne "Converting $wma_file..."\\r - ffmpeg -loglevel error -i "$wma_file" -acodec adpcm_ms -b:a 256k "${wma_file%.*}.wav" && rm -f "$wma_file" # Writes to log instead +# Extract .ifs file and descend into its directory +extract_ifs() { + local ifs_file="$1" + echo "Extracting $ifs_file..." + + # Ensure the path is correct by making it absolute if necessary + if [[ "$ifs_file" != /* ]]; then + ifs_file="$ifs_file" + fi + + "IFSTOOLS_BIN" --super-disable "$ifs_file" || { echo "Failed to extract $ifs_file"; return 1; } # super-disable arg required for processing p0 .ifs without their parent .ifs +} + +# ifstools outputs its files into a nested directory, with its parent dir being the song id, with the _ifs or -p0_ifs suffix +# This needs to be cleaned up before contents are moved into $SOUND_DIR, which is why this silly function exists +cleanup_ifs() { + for dir in *_ifs *-p0_ifs; do + if [ -d "$dir" ]; then + if [[ "$dir" == *"-p0_ifs" ]]; then + + # If the directory ends with "-p0_ifs", strip the "_ifs" suffix but retain the "-p0" when moving to $SOUND_DIR + # -p0.ifs are children to full .ifs files and appear to be chart updates (black another/leggendaria/etc?) + # Need to exist as their own ifs file or directory + + base_name=$(basename "$dir" _ifs) + inner_base_name="${base_name%-p0}" + inner_dir="$dir/$inner_base_name" + move_dir="$SOUND_DIR/$base_name" # Keeps the -p0 when moving + + else + # Otherwise, strip just _ifs for standard ifs files + base_name=$(basename "$dir" _ifs) + inner_dir="$dir/$base_name" + move_dir="$SOUND_DIR/$base_name" # Moves normally without -p0, since these are full song containers + fi + + # Check if the inner directory exists + if [ -d "$inner_dir" ]; then + echo "Moving $inner_dir to $move_dir" + + # Move the inner directory to $SOUND_DIR with the correct naming + mv "$inner_dir" "$move_dir" + + # Remove the now empty parent directory + rmdir "$dir" + else + echo "Inner directory $inner_dir not found in $dir" + fi + fi done } -# Repack .wav files into .2dx +# Extracts and converts .s3p files +extract_convert_s3p() { + local s3p_file="$1" + echo "Processing $s3p_file..." + + # Check if the directory contains .2dx files while ignoring preview files (_pre.2dx) + if find . -maxdepth 1 -type f -name "*.2dx" ! -name "*_pre.2dx" | grep -q .; then + echo "Directory contains .2dx (excluding preview files) - skipping." + return 0 + fi + + # Proceed with extraction + "S3P_EXTRACT_BIN" "$s3p_file" || { echo "Failed to extract $s3p_file"; return 1; } + local s3p_out_dir="${s3p_file}.out" + [ -d "$s3p_out_dir" ] && cd "$s3p_out_dir" || { echo "Directory $s3p_out_dir not found"; return 1; } + + # Convert .wma files to .wav + for wma_file in *.wma; do + [ -e "$wma_file" ] || continue + echo -ne "Converting $wma_file..."\\r + "FFMPEG_BIN" -loglevel error -i "$wma_file" -acodec adpcm_ms -b:a 256k "${wma_file%.*}.wav" && rm -f "$wma_file" + # Remove loglevel argument if you want to see what ffmpeg is doing + done +} + +# Repacks .wav files into .2dx repack_to_2dx() { - echo "Repacking files to .2dx..." + echo "Repacking song/chart data to .2dx..." # Get the current working directory name dir_name=$(basename "$OLDPWD") @@ -40,23 +121,24 @@ repack_to_2dx() { # Remove the ".out" suffix from the directory name if it exists output_name="${dir_name%.out}" - 2dxBuild "$output_name".2dx || { echo "Failed to repack files"; return 1; } + "BUILD_2DX_BIN" "$output_name".2dx || { echo "Failed to repack files"; return 1; } mv "$output_name".2dx .. cd .. rm -rf *s3p* } -# Iterate through directories and .ifs in $SOUND_DIR +# Iterates through directories and .ifs in $SOUND_DIR process_sound_files() { if [ ! -d "$SOUND_DIR" ]; then echo "Directory $SOUND_DIR does not exist." exit 1 fi - # Unpack.ifs files into directories + # Unpack.ifs files into directories, do not repack into .ifs - easier for the sake of managing future updates for ifs_file in "$SOUND_DIR"/*.ifs; do - echo "Processing IFS file: $ifs_file" - (cd "$SOUND_DIR" && extract_cleanup_ifs "$ifs_file") + echo "Processing .ifs file: $ifs_file" + (extract_ifs "$ifs_file") + cleanup_ifs done # Convert all directories