86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
import argparse
|
|
from decimal import Decimal
|
|
import sys
|
|
from typing import Union
|
|
|
|
import simfile
|
|
from simfile.dir import SimfilePack
|
|
|
|
|
|
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:
|
|
# 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
|
|
for simfile_dir in SimfilePack(args.pack).simfile_dirs():
|
|
|
|
# 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)
|