Compare commits

..

3 Commits

3 changed files with 151 additions and 67 deletions

View File

@ -1,15 +1,19 @@
# bm2dnix Helper Scripts # bm2dnix Helper Scripts
This repo may seem erratic with no documentation whatsoever. This repo may seem erratic with no documentation whatsoever. This is a collection of python & shell scripts to assist with the following:
This is because resources listed here are part of a bigger private repository. - Wineprefix setup
- Proton patches/setup
- Automated configuration & launching for various titles (for running titles with varying requirements)
- Converting Wine stack traces for debugging
- Wrappers for special Wineprefix environments *(no longer maintained)*
## s3p_to_2dx ## s3p_to_2dx
*This script is currently in its proof of concept stage. Please examine it before trying to run it, I reccommend copying your sound data elsewhere and running the script in there.* *This script is currently in its proof of concept stage. Please examine it before trying to run it, I reccommend copying your sound data elsewhere and running the script in there.*
Helper script to convert .s3p .wma containers to .2dx .wav containers. Needed for songs in 25+ to play properly without *disable-fx* patches applied. Helper script to convert .s3p .wma containers to .2dx .wav containers. Needed for songs in 25+ to play properly without *disable-fx* patches applied. This script can be run on game updates/deltas, or directly in the games sound directory.
Dependencies (must to be registered to /usr/bin): Dependencies:
- bash - bash
- ffmpeg - ffmpeg
- [ifstools](https://github.com/mon/ifstools) - [ifstools](https://github.com/mon/ifstools)
@ -17,13 +21,18 @@ Dependencies (must to be registered to /usr/bin):
- [s3p_extract](https://github.com/mon/s3p_extract) (Thank you mon/xyen!) - [s3p_extract](https://github.com/mon/s3p_extract) (Thank you mon/xyen!)
Usage: Usage:
- Define your sound directory in `SOUND_DIR` - This script assumes external dependencies are registered to $PATH by default
`./s3p_to_2dx` - Binary directories must be specified in command-line arguments otherwise
- `./s3p_to_2dx -s </path/to/sound/dir> -e </path/to/s3p_extract> -b </path/to/2dxBuild> -i </path/to/ifstools> -f </path/to/ffmpeg>`
## bm2dnix
This tool supports launching IIDX by chainloading bm2dnix -> ep_protonnix -> proton/proton-ge -> spicetools. This script expects things to be located in Steam directories
Usage:
- See the help command for examples and usage
- `bm2dnix --help`
## etc ## etc
You don't have to use anything from this repo to get games running as these are just there to make process feel more seamless. You don't have to use anything from this repo to get games running as these are just there to make process feel more seamless.
That being said part of a guide listed at pages may be harder to follow without any system integration whatsoever, therefore this repository exists, providing the minimal wrappers setup that should work with guide provided.
If it doesn't, create a new issue here, as some wrappers here may be outdated.

View File

@ -161,14 +161,21 @@ args_iidx22() {
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}")
} }
args_iidx30() { args_iidx25() {
# pipewire supported, fullscreen partially? working subscreen # pipewire supported, fullscreen breaks on window unfocus
_G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce) _G_args+=("${_C_audio_dummy_pipewire[@]}")
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter) [ "$_G_video" != "stable" ] || _G_args+=(-w)
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}")
}
args_iidx26() {
# pipewire supported, fullscreen breaks on window unfocus
_G_args+=("${_C_audio_dummy_pipewire[@]}")
[ "$_G_video" != "stable" ] || _G_args+=(-w)
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
} }
args_iidx29() { args_iidx27() {
# pipewire supported, fullscreen working subscreen # pipewire supported, fullscreen working subscreen
_G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce) _G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce)
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter) [ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
@ -197,28 +204,27 @@ args_iidx28() {
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter) [ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
fi fi
} }
args_iidx27() { args_iidx29() {
# pipewire supported, fullscreen working subscreen # pipewire supported, fullscreen working subscreen
_G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce) _G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce)
[ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter) [ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
} }
args_iidx26() { args_iidx30() {
# pipewire supported, fullscreen breaks on window unfocus # pipewire supported, fullscreen partially? working subscreen
_G_args+=("${_C_audio_dummy_pipewire[@]}") _G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce)
[ "$_G_video" != "stable" ] || _G_args+=(-w) [ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
} }
args_iidx25() { args_iidx31() {
# pipewire supported, fullscreen breaks on window unfocus # pipewire supported, only tested in LDJ, TDJ still being tested
_G_args+=("${_C_audio_dummy_pipewire[@]}") _G_args+=("${_C_audio_dummy_pipewire[@]}" "${_C_lightning_model[@]}" -nolegacy -touchemuforce)
[ "$_G_video" != "stable" ] || _G_args+=(-w) [ "$_G_video" != "stable" ] || _G_args+=(-graphics-force-single-adapter)
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
} }
gen_args() { gen_args() {
@ -321,7 +327,7 @@ gen_base() {
# Apply environment # Apply environment
cd "$styledir" || abort "INVALID PATH" cd "$styledir" || abort "INVALID PATH"
_G_ep+=(--exec "$_G_exec" --uniqueid "$patchid" --runtime "$_G_root/steamapps/common/$_C_rtname" --prefix "$_G_root/steamapps/compatdata/$_C_pfxname" --steam-dir "$_G_root") _G_ep+=(--exec "$_G_exec" --uniqueid "$patchid" --prefix "$_G_root/steamapps/compatdata/$_C_pfxname" --steam-dir "$_G_root") # Remove application of steam runtime
} }
sanity_check() { sanity_check() {

View File

@ -1,51 +1,119 @@
#!/bin/bash #!/bin/bash
# Set the directory containing sound files # Set the directory containing sound files, typically found in /data/sound in the games "contents"
# This is usually ./sound if youre running the script out of the games data directory SOUND_DIR=""
SOUND_DIR="please-set-this"
# 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 </path/to/sound/dir>] [-e </path/to/s3p_extract>] [-b </path/to/2dxBuild>] [-i </path/to/ifstools>] [-f </path/to/ffmpeg>]"
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
# 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
# Extract .ifs file and descend into its directory # Extract .ifs file and descend into its directory
extract_ifs() { extract_ifs() {
local ifs_file="$1" local ifs_file="$1"
echo "Extracting $ifs_file..." echo "Extracting $ifs_file..."
ifstools "$ifs_file" || { echo "Failed to extract $ifs_file"; return 1; }
local extracted_dir="${ifs_file%.*}_ifs" # Ensure the path is correct by making it absolute if necessary
[ -d "$extracted_dir" ] && cd "$extracted_dir" || { echo "Directory $extracted_dir not found"; return 1; } 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
} }
# Repack .ifs file and move it output to parent directory # ifstools outputs its files into a nested directory, with its parent dir being the song id, with the _ifs or -p0_ifs suffix
repack_to_ifs() { # This needs to be cleaned up before contents are moved into $SOUND_DIR, which is why this silly function exists
local ifs_dir= cleanup_ifs() {
echo "Repacking $ifs_dir to $output_name..." for dir in *_ifs *-p0_ifs; do
if [ -d "$dir" ]; then
if [[ "$dir" == *"-p0_ifs" ]]; then
# Get the current working directory name # If the directory ends with "-p0_ifs", strip the "_ifs" suffix but retain the "-p0" when moving to $SOUND_DIR
dir_name=$(basename "$OLDPWD") # -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
# Remove the "_ifs" suffix from the directory name if it exists base_name=$(basename "$dir" _ifs)
output_name="${dir_name%_ifs}" inner_base_name="${base_name%-p0}"
inner_dir="$dir/$inner_base_name"
move_dir="$SOUND_DIR/$base_name" # Keeps the -p0 when moving
ifstools "$output_name" || { echo "Failed to repack $dir_name"; return 1; } else
mv "$output_name".ifs .. # 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
# Extract and convert .s3p files # Check if the inner directory exists
extract_convert_s3p() { if [ -d "$inner_dir" ]; then
local s3p_file="$1" echo "Moving $inner_dir to $move_dir"
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; }
for wma_file in *.wma; do # Move the inner directory to $SOUND_DIR with the correct naming
[ -e "$wma_file" ] || continue mv "$inner_dir" "$move_dir"
echo "Converting $wma_file..."
ffmpeg -loglevel error -i "$wma_file" -acodec adpcm_ms -b:a 256k "${wma_file%.*}.wav" && rm -f "$wma_file" # Write to /dev/null instead maybe? ffmpeg is loud asf # Remove the now empty parent directory
rmdir "$dir"
else
echo "Inner directory $inner_dir not found in $dir"
fi
fi
done 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() { repack_to_2dx() {
echo "Repacking files to .2dx format..." echo "Repacking song/chart data to .2dx..."
# Get the current working directory name # Get the current working directory name
dir_name=$(basename "$OLDPWD") dir_name=$(basename "$OLDPWD")
@ -53,30 +121,31 @@ repack_to_2dx() {
# Remove the ".out" suffix from the directory name if it exists # Remove the ".out" suffix from the directory name if it exists
output_name="${dir_name%.out}" 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 .. mv "$output_name".2dx ..
cd .. cd ..
rm -rf *s3p* # This is kinda risky but whatever lol rm -rf *s3p*
} }
# Iterate through directories and .ifs in $SOUND_DIR # Iterates through directories and .ifs in $SOUND_DIR
process_sound_files() { process_sound_files() {
if [ ! -d "$SOUND_DIR" ]; then if [ ! -d "$SOUND_DIR" ]; then
echo "Directory $SOUND_DIR does not exist." echo "Directory $SOUND_DIR does not exist."
exit 1 exit 1
fi fi
# Process directories for songs not contained in .ifs # 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"
(extract_ifs "$ifs_file")
cleanup_ifs
done
# Convert all directories
for dir in "$SOUND_DIR"/*/; do for dir in "$SOUND_DIR"/*/; do
echo "Processing directory: $dir" echo "Processing directory: $dir"
(cd "$dir" && extract_convert_s3p *.s3p && repack_to_2dx) (cd "$dir" && extract_convert_s3p *.s3p && repack_to_2dx)
done done
# Process .ifs files for songs contained in .ifs
for ifs_file in "$SOUND_DIR"/*.ifs; do
echo "Processing IFS file: $ifs_file"
(cd "$SOUND_DIR" && extract_ifs "$ifs_file" && extract_convert_s3p *.s3p && repack_to_2dx && repack_to_ifs)
done
} }
# Execute the main function # Execute the main function