1
0
mirror of synced 2025-02-26 06:39:00 +01:00

Attempt to handle remaining header bytes

This commit is contained in:
Viv 2023-06-02 16:33:48 -04:00
parent 62e4be1b81
commit 1f3bf163b9
3 changed files with 37 additions and 4 deletions

View File

@ -69,11 +69,13 @@ byte_strings = {
simpleHeaders = [b * 36 for b in [byte_strings['431'], byte_strings['V1'], byte_strings['V2']]]
# This sample header for the "unknown header bytes" is built from the investigations in utils/validateHeaderMetadata
# However, it's missing song-specific metadata from bytes 12, 16, 20, and (perhaps optionally), 76, 77 and 78.
# Create a sample header pre-filled with known bytes
unknownHeaderSample = [0] * 80
# The following bytes are hardcoded by tja2fumen.exe (implying they have little/no effect on how the song is parsed)
unknownHeaderSample[4] = 16
unknownHeaderSample[5] = 39
unknownHeaderSample[12] = 10
unknownHeaderSample[16] = 8
unknownHeaderSample[21] = 255
unknownHeaderSample[22] = 255
unknownHeaderSample[23] = 255
@ -89,3 +91,15 @@ unknownHeaderSample[60] = 1
unknownHeaderSample[64] = 30
unknownHeaderSample[68] = 30
unknownHeaderSample[72] = 20
unknownHeaderSample[76] = 78
unknownHeaderSample[77] = 97
unknownHeaderSample[78] = 188
DIFFICULTY_BYTES = {
'Easy': [112, 23],
'Normal': [88, 27],
'Hard': [88, 27],
'Oni': [64, 31],
'Ura': [64, 31],
'Edit': [64, 31]
}

View File

@ -1,6 +1,7 @@
from copy import deepcopy
from constants import TJA_NOTE_TYPES, unknownHeaderSample
from utils import computeSoulGaugeByte
from constants import TJA_NOTE_TYPES, DIFFICULTY_BYTES, unknownHeaderSample
# Filler metadata that the `writeFumen` function expects
default_note = {'type': '', 'pos': 0.0, 'item': 0, 'padding': 0.0,
@ -101,6 +102,7 @@ def convertTJAToFumen(fumen, tja):
currentBranch = 'normal' # TODO: Program in branch support
tja['measures'] = preprocessTJAMeasures(tja)
currentDrumroll = None
total_notes = 0
# Parse TJA measures to create converted TJA -> Fumen file
tjaConverted = {'measures': []}
@ -172,9 +174,11 @@ def convertTJAToFumen(fumen, tja):
note['hits'] = tja['metadata']['balloon'].pop(0)
note['hitsPadding'] = 0
currentDrumroll = note
total_notes -= 1
if note['type'] in ["Drumroll", "DRUMROLL"]:
note['drumrollBytes'] = b'\x00\x00\x00\x00\x00\x00\x00\x00'
currentDrumroll = note
total_notes -= 1
measureFumen[currentBranch][note_counter] = note
note_counter += 1
measureFumen[currentBranch]['length'] = note_counter
@ -192,7 +196,14 @@ def convertTJAToFumen(fumen, tja):
else:
currentDrumroll['duration'] += measureDurationBase
tjaConverted['headerUnknown'] = b"".join(i.to_bytes(1, 'little') for i in unknownHeaderSample)
total_notes += note_counter
# Take a stock header metadata sample and add song-specific metadata
headerMetadata = unknownHeaderSample
headerMetadata[8] = DIFFICULTY_BYTES[tja['metadata']['course']][0]
headerMetadata[9] = DIFFICULTY_BYTES[tja['metadata']['course']][1]
headerMetadata[20] = computeSoulGaugeByte(total_notes)
tjaConverted['headerUnknown'] = b"".join(i.to_bytes(1, 'little') for i in headerMetadata)
tjaConverted['order'] = '<'
tjaConverted['length'] = len(tjaConverted['measures'])
tjaConverted['unknownMetadata'] = 0

View File

@ -1,5 +1,6 @@
import sys
import struct
import math
from constants import simpleHeaders, byte_strings
@ -190,6 +191,13 @@ def validateHeaderMetadata(headerBytes):
assert val == 0, f"Expected 0 at position '{idx}', got '{val}' instead."
def computeSoulGaugeByte(n_notes):
# I don't think this is fully accurate. It doesn't work for non-Oni songs, and it's usually off by a bit.
A = -85.548628
B = 44.780199
return round(A+B*math.log(n_notes))
def readStruct(file, order, format_string, seek=None):
"""
Interpret bytes as packed binary data.