Compare commits

..

No commits in common. "b8a6ffa486bb334a138935faa3772c8d78b10cd2" and "97237611c1abbe8613982f519763e1761f47e335" have entirely different histories.

3 changed files with 59 additions and 143 deletions

View File

@ -1,19 +1,15 @@
# bm2dnix Helper Scripts # bm2dnix Helper Scripts
This repo may seem erratic with no documentation whatsoever. This is a collection of python & shell scripts to assist with the following: This repo may seem erratic with no documentation whatsoever.
- Wineprefix setup This is because resources listed here are part of a bigger private repository.
- 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. This script can be run on game updates/deltas, or directly in the games sound directory. Helper script to convert .s3p .wma containers to .2dx .wav containers. Needed for songs in 25+ to play properly without *disable-fx* patches applied.
Dependencies: Dependencies (must to be registered to /usr/bin):
- bash - bash
- ffmpeg - ffmpeg
- [ifstools](https://github.com/mon/ifstools) - [ifstools](https://github.com/mon/ifstools)
@ -21,18 +17,13 @@ Dependencies:
- [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:
- This script assumes external dependencies are registered to $PATH by default - Define your sound directory in `SOUND_DIR`
- Binary directories must be specified in command-line arguments otherwise `./s3p_to_2dx`
- `./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,21 +161,14 @@ args_iidx22() {
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}")
} }
args_iidx25() { 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_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_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)
@ -204,27 +197,28 @@ 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_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)
[ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
} }
args_iidx30() { args_iidx26() {
# 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_maint[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_maint[@]}")
} }
args_iidx31() { args_iidx25() {
# pipewire supported, only tested in LDJ, TDJ still being tested # 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_maint[@]}") [ "$_G_url" != "dummy" ] || _G_args+=("${_C_net_dummy_local[@]}")
} }
gen_args() { gen_args() {
@ -327,7 +321,7 @@ gen_base() {
# Apply environment # Apply environment
cd "$styledir" || abort "INVALID PATH" cd "$styledir" || abort "INVALID PATH"
_G_ep+=(--exec "$_G_exec" --uniqueid "$patchid" --prefix "$_G_root/steamapps/compatdata/$_C_pfxname" --steam-dir "$_G_root") # Remove application of steam runtime _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")
} }
sanity_check() { sanity_check() {

View File

@ -1,119 +1,51 @@
#!/bin/bash #!/bin/bash
# Set the directory containing sound files, typically found in /data/sound in the games "contents" # Set the directory containing sound files
SOUND_DIR="" # This is usually ./sound if youre running the script out of the games data directory
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; }
# Ensure the path is correct by making it absolute if necessary local extracted_dir="${ifs_file%.*}_ifs"
if [[ "$ifs_file" != /* ]]; then [ -d "$extracted_dir" ] && cd "$extracted_dir" || { echo "Directory $extracted_dir not found"; return 1; }
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 # Repack .ifs file and move it output to parent directory
# This needs to be cleaned up before contents are moved into $SOUND_DIR, which is why this silly function exists repack_to_ifs() {
cleanup_ifs() { local ifs_dir=
for dir in *_ifs *-p0_ifs; do echo "Repacking $ifs_dir to $output_name..."
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 # Get the current working directory name
# -p0.ifs are children to full .ifs files and appear to be chart updates (black another/leggendaria/etc?) dir_name=$(basename "$OLDPWD")
# Need to exist as their own ifs file or directory
base_name=$(basename "$dir" _ifs) # Remove the "_ifs" suffix from the directory name if it exists
inner_base_name="${base_name%-p0}" output_name="${dir_name%_ifs}"
inner_dir="$dir/$inner_base_name"
move_dir="$SOUND_DIR/$base_name" # Keeps the -p0 when moving
else ifstools "$output_name" || { echo "Failed to repack $dir_name"; return 1; }
# Otherwise, strip just _ifs for standard ifs files mv "$output_name".ifs ..
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
} }
# Extracts and converts .s3p files # Extract and convert .s3p files
extract_convert_s3p() { extract_convert_s3p() {
local s3p_file="$1" local s3p_file="$1"
echo "Processing $s3p_file..." echo "Processing $s3p_file..."
s3p_extract "$s3p_file" || { echo "Failed to extract $s3p_file"; return 1; }
# 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" local s3p_out_dir="${s3p_file}.out"
[ -d "$s3p_out_dir" ] && cd "$s3p_out_dir" || { echo "Directory $s3p_out_dir not found"; return 1; } [ -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 for wma_file in *.wma; do
[ -e "$wma_file" ] || continue [ -e "$wma_file" ] || continue
echo -ne "Converting $wma_file..."\\r echo "Converting $wma_file..."
"FFMPEG_BIN" -loglevel error -i "$wma_file" -acodec adpcm_ms -b:a 256k "${wma_file%.*}.wav" && rm -f "$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 loglevel argument if you want to see what ffmpeg is doing
done done
} }
# Repacks .wav files into .2dx # Repack .wav files into .2dx
repack_to_2dx() { repack_to_2dx() {
echo "Repacking song/chart data to .2dx..." echo "Repacking files to .2dx format..."
# Get the current working directory name # Get the current working directory name
dir_name=$(basename "$OLDPWD") dir_name=$(basename "$OLDPWD")
@ -121,31 +53,30 @@ 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}"
"BUILD_2DX_BIN" "$output_name".2dx || { echo "Failed to repack files"; return 1; } 2dxBuild "$output_name".2dx || { echo "Failed to repack files"; return 1; }
mv "$output_name".2dx .. mv "$output_name".2dx ..
cd .. cd ..
rm -rf *s3p* rm -rf *s3p* # This is kinda risky but whatever lol
} }
# Iterates through directories and .ifs in $SOUND_DIR # Iterate 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
# Unpack.ifs files into directories, do not repack into .ifs - easier for the sake of managing future updates # Process directories for songs not contained in .ifs
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