tja2fumen.py
: Add convertTJAToFumen
function
Thie is a first draft with many TODOs.
This commit is contained in:
parent
8b07fb77d0
commit
185ed46361
@ -2,6 +2,8 @@ import os
|
||||
import sys
|
||||
import struct
|
||||
import argparse
|
||||
from copy import deepcopy
|
||||
from parsetja import parseTJA
|
||||
|
||||
tja2fumen_version = "v0.1"
|
||||
|
||||
@ -416,6 +418,109 @@ def checkMismatchedBytes(file1, file2):
|
||||
return incorrect_bytes
|
||||
|
||||
|
||||
TJA_NOTE_TYPES = {
|
||||
'1': 'Don',
|
||||
'2': 'Ka',
|
||||
'3': 'DON',
|
||||
'4': 'KA',
|
||||
'5': 'Drumroll',
|
||||
'6': 'DRUMROLL',
|
||||
'7': 'Balloon',
|
||||
'8': 'EndDRB',
|
||||
'9': 'Kusudama',
|
||||
'A': 'DON', # hands
|
||||
'B': 'KA', # hands
|
||||
}
|
||||
|
||||
# Filler metadata that the `writeFumen` function expects
|
||||
default_note = {'type': '', 'pos': 0.0, 'item': 0, 'padding': 0.0,
|
||||
'scoreInit': 0, 'scoreDiff': 0, 'durationPadding': 0.0}
|
||||
default_branch = {'length': 0, 'padding': 0, 'speed': 1.0}
|
||||
default_measure = {
|
||||
'bpm': 0.0,
|
||||
'fumenOffset': 0.0,
|
||||
'gogo': False,
|
||||
'hidden': False,
|
||||
'padding1': 0,
|
||||
'branchInfo': [-1, -1, -1, -1, -1, -1],
|
||||
'padding2': 0,
|
||||
'normal': deepcopy(default_branch),
|
||||
'advanced': deepcopy(default_branch),
|
||||
'master': deepcopy(default_branch)
|
||||
}
|
||||
|
||||
|
||||
def convertTJAToFumen(fumen, tja):
|
||||
# Fumen offset for the first measure that has a barline
|
||||
fumenOffset1 = float(tja['metadata']['offset']) * -1000
|
||||
|
||||
# Variables that will change over time due to events
|
||||
currentBPM = 0.0
|
||||
currentGogo = False
|
||||
currentHidden = False
|
||||
currentBranch = 'normal' # TODO: Program in branch support
|
||||
|
||||
# Parse TJA measures to create converted TJA -> Fumen file
|
||||
tjaConverted = { 'measures': [] }
|
||||
for i, measureTJA in enumerate(tja['measures']):
|
||||
measureFumenExample = fumen['measures'][i+9]
|
||||
measureFumen = deepcopy(default_measure)
|
||||
|
||||
# TODO Event: GOGOTIME
|
||||
|
||||
# TODO Event: HIDDEN
|
||||
|
||||
# TODO Event: BARLINE
|
||||
|
||||
# TODO Event: MEASURE
|
||||
|
||||
# Event: BPMCHANGE
|
||||
# TODO: Handle TJA measure being broken up into multiple Fumen measures due to mid-measure BPM changes
|
||||
midMeasureBPM = [(0, currentBPM)]
|
||||
for event in measureTJA['events']:
|
||||
if event['name'] == 'bpm':
|
||||
currentBPM = float(event['value'])
|
||||
if event['position'] == 0:
|
||||
midMeasureBPM[0] = (0, currentBPM,)
|
||||
else:
|
||||
midMeasureBPM.append((event['position'], currentBPM))
|
||||
if len(midMeasureBPM) > 1:
|
||||
test = None
|
||||
measureFumen['bpm'] = currentBPM
|
||||
|
||||
# TODO: `measureFumen['fumenOffset']
|
||||
# Will need to account for BARLINEON and BARLINEOFF.
|
||||
# Some examples that line up with actual fumen data:
|
||||
# fumenOffset0 = (fumenOffset1 - measureLength)
|
||||
# fumenOffset2 = (fumenOffset1 + measureLength)
|
||||
measureLength = 240_000 / currentBPM
|
||||
# measureFumen['fumenOffset'] = prev['fumenOffset'] + measureLength
|
||||
|
||||
# Create note dictionaries based on TJA measure data (containing 0's plus 1/2/3/4/etc. for notes)
|
||||
note_counter = 0
|
||||
for i, note_value in enumerate(measureTJA['data']):
|
||||
if note_value != '0':
|
||||
note = deepcopy(default_note)
|
||||
note['pos'] = measureLength * (i / len(measureTJA['data']))
|
||||
note['type'] = TJA_NOTE_TYPES[note_value] # TODO: Handle BALLOON/DRUMROLL
|
||||
note['scoreInit'] = tja['scoreInit'] # Probably not fully accurate
|
||||
note['scoreDiff'] = tja['scoreDiff'] # Probably not fully accurate
|
||||
measureFumen[currentBranch][note_counter] = note
|
||||
note_counter += 1
|
||||
measureFumen[currentBranch]['length'] = note_counter
|
||||
|
||||
# Append the measure to the tja's list of measures
|
||||
tjaConverted['measures'].append(measureFumen)
|
||||
|
||||
tjaConverted['headerUnknown'] = b'x\00' * 80
|
||||
tjaConverted['order'] = '<'
|
||||
tjaConverted['length'] = len(tjaConverted['measures'])
|
||||
tjaConverted['unknownMetadata'] = 0
|
||||
tjaConverted['branches'] = False
|
||||
|
||||
return tjaConverted
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="tja2fumen {0}".format(tja2fumen_version)
|
||||
@ -483,12 +588,28 @@ if __name__ == "__main__":
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
else:
|
||||
arguments = parser.parse_args()
|
||||
inputFile = getattr(arguments, "file_m.bin")
|
||||
parsedSong = readFumen(inputFile, arguments.order, arguments.debug)
|
||||
outputName = inputFile.name.split('.')[0] + "_rebuilt.bin"
|
||||
outputFile = open(outputName, "wb")
|
||||
writeFumen(outputFile, parsedSong)
|
||||
# Read output file back in to validate that the rewritten song is a perfect match
|
||||
inputFileOut = open(outputName, "rb")
|
||||
print(checkMismatchedBytes(inputFile.name, outputFile.name))
|
||||
# arguments = parser.parse_args()
|
||||
arguments = {
|
||||
"input_fumen": "./roku/ia6cho_m.bin", # NB: Contains only oni chart
|
||||
"input_tja": "./roku/Rokuchounen to Ichiya Monogatari.tja", # NB: Contains 5 charts
|
||||
}
|
||||
# Parse fumen
|
||||
inputFile = open(arguments["input_fumen"], "rb")
|
||||
parsedSongFumen = readFumen(inputFile)
|
||||
|
||||
# Steps to validate the `writeFumen` function to make sure it reproduces correct output
|
||||
validate = False
|
||||
if validate:
|
||||
outputName = inputFile.name.split('.')[0] + "_rebuilt.bin"
|
||||
outputFile = open(outputName, "wb")
|
||||
writeFumen(outputFile, parsedSongFumen)
|
||||
# Read output file back in to validate that the rewritten song is a perfect match
|
||||
print(False if checkMismatchedBytes(inputFile.name, outputFile.name) else True)
|
||||
|
||||
# Parse tja
|
||||
inputFile = open(arguments["input_tja"], "r", encoding="utf-8-sig")
|
||||
parsedSongsTJA = parseTJA(inputFile)
|
||||
|
||||
# Try converting the Oni TJA chart to match the Oni fumen
|
||||
convertedTJA = convertTJAToFumen(parsedSongFumen, parsedSongsTJA['Oni'])
|
||||
# writeFumen(outputFile, convertedTJA)
|
||||
|
Loading…
x
Reference in New Issue
Block a user