1
0
mirror of synced 2025-02-16 10:42:33 +01:00

tja2fumen.py: Refactor readStruct and provide documentation

This commit is contained in:
Viv 2023-06-02 16:33:41 -04:00
parent 8c707a50d2
commit 9fe0fceced

View File

@ -34,18 +34,12 @@ def readFumen(fumenFile, byteOrder=None, debug=False):
song = {} song = {}
def readStruct(fmt, seek=None):
if seek:
file.seek(seek)
return struct.unpack(order + fmt, file.read(struct.calcsize(order + fmt)))
if byteOrder: if byteOrder:
order = ">" if byteOrder == "big" else "<" order = ">" if byteOrder == "big" else "<"
totalMeasures = readStruct("I", 0x200)[0] totalMeasures = readStruct(file, order, format_string="I", seek=0x200)[0]
else: else:
order = "" measuresBig = readStruct(file, order="", format_string=">I", seek=0x200)[0]
measuresBig = readStruct(">I", 0x200)[0] measuresLittle = readStruct(file, order="", format_string="<I", seek=0x200)[0]
measuresLittle = readStruct("<I", 0x200)[0]
if measuresBig < measuresLittle: if measuresBig < measuresLittle:
order = ">" order = ">"
totalMeasures = measuresBig totalMeasures = measuresBig
@ -53,7 +47,7 @@ def readFumen(fumenFile, byteOrder=None, debug=False):
order = "<" order = "<"
totalMeasures = measuresLittle totalMeasures = measuresLittle
hasBranches = getBool(readStruct("B", 0x1b0)[0]) hasBranches = getBool(readStruct(file, order, format_string="B", seek=0x1b0)[0])
song["branches"] = hasBranches song["branches"] = hasBranches
if debug: if debug:
debugPrint("Total measures: {0}, {1} branches, {2}-endian".format( debugPrint("Total measures: {0}, {1} branches, {2}-endian".format(
@ -66,7 +60,7 @@ def readFumen(fumenFile, byteOrder=None, debug=False):
for measureNumber in range(totalMeasures): for measureNumber in range(totalMeasures):
measure = {} measure = {}
# measureStruct: bpm 4, offset 4, gogo 1, hidden 1, dummy 2, branchInfo 4 * 6, dummy 4 # measureStruct: bpm 4, offset 4, gogo 1, hidden 1, dummy 2, branchInfo 4 * 6, dummy 4
measureStruct = readStruct("ffBBHiiiiiii") measureStruct = readStruct(file, order, format_string="ffBBHiiiiiii")
measure["bpm"] = measureStruct[0] measure["bpm"] = measureStruct[0]
measure["fumenOffset"] = measureStruct[1] measure["fumenOffset"] = measureStruct[1]
if measureNumber == 0: if measureNumber == 0:
@ -81,7 +75,7 @@ def readFumen(fumenFile, byteOrder=None, debug=False):
for branchNumber in range(3): for branchNumber in range(3):
branch = {} branch = {}
# branchStruct: totalNotes 2, dummy 2, speed 4 # branchStruct: totalNotes 2, dummy 2, speed 4
branchStruct = readStruct("HHf") branchStruct = readStruct(file, order, format_string="HHf")
totalNotes = branchStruct[0] totalNotes = branchStruct[0]
branch["speed"] = branchStruct[2] branch["speed"] = branchStruct[2]
@ -111,7 +105,7 @@ def readFumen(fumenFile, byteOrder=None, debug=False):
note = {} note = {}
# noteStruct: type 4, pos 4, item 4, dummy 4, init 2, diff 2, duration 4 # noteStruct: type 4, pos 4, item 4, dummy 4, init 2, diff 2, duration 4
noteStruct = readStruct("ififHHf") noteStruct = readStruct(file, order, format_string="ififHHf")
noteType = noteStruct[0] noteType = noteStruct[0]
if noteType not in noteTypes: if noteType not in noteTypes:
@ -157,6 +151,35 @@ def readFumen(fumenFile, byteOrder=None, debug=False):
return song return song
def readStruct(file, order, format_string, seek=None):
"""
Interpret bytes as packed binary data.
Arguments:
- file: The fumen's file object (presumably in 'rb' mode).
- order: '<' or '>' (little or big endian).
- format_string: String made up of format characters that describes the data layout.
Full list of available format characters:
(https://docs.python.org/3/library/struct.html#format-characters)
However, this script uses only the following format characters:
- B: unsigned char (1 byte)
- H: unsigned short (2 bytes)
- I: unsigned int (4 bytes)
- i: int (4 bytes)
- f: float (4 bytes)
- seek: The position of the read pointer to be used within the file.
Return values:
- interpreted_string: A string containing interpreted byte values,
based on the specified 'fmt' format characters.
"""
if seek:
file.seek(seek)
byte_string = file.read(struct.calcsize(order + format_string))
interpreted_string = struct.unpack(order + format_string, byte_string)
return interpreted_string
def shortHex(number): def shortHex(number):
return hex(number)[2:] return hex(number)[2:]