#!/usr/bin/env sh set -eu repo_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) gc_root=${1:-"$repo_dir/GC"} output_dir=${2:-"$repo_dir/dist/PSP/GAME/OpenRoller"} # Curated for ASCII titles, available BGM/jackets, the decoded one-mesh TUMO # layout, and the PSP-1000 per-stage object/memory budgets. songs="10pt8tion oshama bonetrousle shadow planet departure journey spacearc altale analysis acid2 agentcrisis aou-flower adr 7days satis mikumiku syositu2 world2 rollingirl2 uraomote unknown redial tellyour umiyuri karakuri dappo echo vampire pa3" cmake -S "$repo_dir" -B "$repo_dir/build" cmake --build "$repo_dir/build" --target openroller-psp-pack openroller-psp-catalog "$repo_dir/tools/build_psp.sh" mkdir -p "$output_dir/songs" # A catalog build supersedes the old one-song fallback payload. rm -f "$output_dir/stage.orps" "$output_dir/audio.mp3" "$output_dir/shot.mp3" cp "$repo_dir/psp/EBOOT.PBP" "$output_dir/EBOOT.PBP" mkdir -p "$output_dir/sounds" ffmpeg -y -hide_banner -loglevel error -i "$gc_root/data/sound/SE_ARRANGE.wav" \ -filter:a "volume=0.87" -ar 44100 -ac 2 -f s16le "$output_dir/sounds/adlib.pcm" ffmpeg -y -hide_banner -loglevel error -i "$gc_root/data/sound/TAP_SE1.wav" \ -filter:a "volume=0.80" -ar 44100 -ac 2 -f s16le "$output_dir/sounds/tap1.pcm" ffmpeg -y -hide_banner -loglevel error -i "$gc_root/data/sound/TAP_SE2.wav" \ -filter:a "volume=0.77" -ar 44100 -ac 2 -f s16le "$output_dir/sounds/tap2.pcm" manifest=$(mktemp) trap 'rm -f "$manifest"' EXIT HUP INT TERM "$repo_dir/build/openroller-psp-catalog" \ "$gc_root/data/boot/stage_param.dat" "$output_dir/catalog.orpc" $songs > "$manifest" tab=$(printf '\t') while IFS="$tab" read -r token image difficulty chart bgm_file shot_file bgm_volume shot_volume <&3; do song_dir="$output_dir/songs/$token" mkdir -p "$song_dir" rm -f "$song_dir/audio.mp3" "$song_dir/shot.mp3" "$repo_dir/build/openroller-psp-pack" \ "$gc_root/data/stage/$chart.dat" "$song_dir/$difficulty.orps" bgm_audio="$gc_root/data/stage/sound/$bgm_file" shot_audio="$gc_root/data/stage/sound/$shot_file" if [ ! -f "$bgm_audio" ]; then echo "$token/$difficulty: missing BGM $bgm_audio" >&2 exit 1 fi if [ ! -f "$shot_audio" ]; then echo "$token/$difficulty: missing SHOT $shot_audio" >&2 exit 1 fi # Real PSP-1000 hardware stutters when sceMp3 is asked to decode both # authored stems while rendering a stage. Pre-mix them once and feed the # runtime a single stream. The limiter has latency compensation enabled, # so it does not move chart timing. rm -f "$song_dir/${difficulty}_shot.mp3" ffmpeg -y -hide_banner -loglevel error \ -i "$bgm_audio" -i "$shot_audio" \ -filter_complex \ "[0:a]volume=$bgm_volume/100[bgm];[1:a]volume=$shot_volume/100[shot];[bgm][shot]amix=inputs=2:duration=longest:normalize=0,alimiter=limit=0.95:attack=5:release=50:level=0:latency=1[mix]" \ -map "[mix]" -ar 44100 -ac 2 -c:a libmp3lame -b:a 128k \ -write_xing 0 -id3v2_version 0 "$song_dir/${difficulty}_bgm.mp3" jacket="$gc_root/data/stage/2d/eng/${image}_menu.dds" [ -f "$jacket" ] || jacket="$gc_root/data/stage/2d/${image}_menu.dds" if [ ! -f "$jacket" ]; then echo "$token: missing jacket $jacket" >&2 exit 1 fi if [ ! -f "$song_dir/jacket.orpj" ]; then "$repo_dir/tools/pack_psp_jacket.py" "$jacket" "$song_dir/jacket.orpj" fi done 3< "$manifest" echo "Prepared 30-song PSP library with single-stream per-chart mixes: $output_dir"