simfile-scripts/change_sync_bias.py

108 lines
3.4 KiB
Python
Raw Normal View History

2022-08-20 17:50:04 -07:00
R"""
Add or subtract the standard ITG sync bias (9 milliseconds)
to all of the sync offsets in a pack.
This script updates the offsets of both SM and SSC simfiles,
including any SSC charts with their own timing data.
If you actually intend to use this script in practice,
you may want to keep track of which packs you've already adjusted
using a text file in each pack directory or some other system.
Usage examples:
# Convert a pack from "null sync" to "ITG sync"
python change_sync_bias.py +9 "C:\StepMania\Songs\My Pack"
# Convert a pack from "ITG sync" to "null sync"
python change_sync_bias.py -9 "C:\StepMania\Songs\My Pack"
"""
2022-07-28 21:15:00 -07:00
import argparse
from decimal import Decimal
import sys
from typing import Union
import simfile
2022-08-20 17:50:04 -07:00
import simfile.dir
2022-07-28 21:15:00 -07:00
class ChangeSyncBiasArgs:
"""Stores the command-line arguments for this script."""
pack: str
itg_to_null: bool
null_to_itg: bool
def argparser():
"""Get an ArgumentParser instance for this command-line script."""
parser = argparse.ArgumentParser(prefix_chars="-+")
parser.add_argument("pack", type=str, help="path to the pack to modify")
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
"-9", "--itg-to-null", action="store_true", help="subtract 9ms from offsets"
)
group.add_argument(
"+9", "--null-to-itg", action="store_true", help="add 9ms to offsets"
)
return parser
def adjust_offset(
obj: Union[simfile.types.Simfile, simfile.ssc.SSCChart],
delta: Decimal,
):
"""Add the delta to the simfile or SSC chart's offset, if present."""
if obj.offset is not None:
obj.offset = str(Decimal(obj.offset) + delta)
def change_sync_bias(simfile_path: str, args: ChangeSyncBiasArgs):
"""
Add or subtract 9 milliseconds to the simfile's offset,
as well as any SSC charts with their own timing data.
This saves the updated simfile to its original location
and writes a backup copy with a ~ appended to the filename.
"""
# Map the +9 or -9 arg to the actual offset delta.
#
# We don't have to check both itg_to_null and null_to_itg
# because the mutually exclusive & required argument group
# ensures that exactly one of them will be True.
delta = Decimal("-0.009" if args.itg_to_null else "+0.009")
# You could specify output_filename here to write the updated file elsewhere
with simfile.mutate(
input_filename=f"{simfile_path}",
backup_filename=f"{simfile_path}~",
) as sf:
2022-08-20 17:50:04 -07:00
print(f"Processing {simfile_path}")
2022-07-28 21:15:00 -07:00
# Always adjust the simfile's offset
adjust_offset(sf, delta)
# Additionally try to adjust SSC charts' offsets.
# This won't do anything unless the chart has its own timing data.
if isinstance(sf, simfile.ssc.SSCSimfile):
for chart in sf.charts:
adjust_offset(chart, delta)
def main(argv):
# Parse command-line arguments
args = argparser().parse_args(argv[1:], namespace=ChangeSyncBiasArgs())
# Iterate over SimfileDirectory objects from the pack
# so that we can easily get the .sm and/or .ssc paths
2022-08-20 17:50:04 -07:00
for simfile_dir in simfile.dir.SimfilePack(args.pack).simfile_dirs():
2022-07-28 21:15:00 -07:00
# Try to update whichever formats exist
for simfile_path in [simfile_dir.sm_path, simfile_dir.ssc_path]:
if simfile_path:
change_sync_bias(simfile_path, args)
if __name__ == "__main__":
main(sys.argv)