Add new LUTs to cover the remaining soul gauge bytes (12/13, 16/17) (#31)
Fixes #14.
This commit is contained in:
parent
c108475026
commit
bd27e9dade
@ -286,11 +286,17 @@ def convertTJAToFumen(tja):
|
||||
headerMetadata = sampleHeaderMetadata.copy()
|
||||
headerMetadata[8] = DIFFICULTY_BYTES[tja['metadata']['course']][0]
|
||||
headerMetadata[9] = DIFFICULTY_BYTES[tja['metadata']['course']][1]
|
||||
headerMetadata[20], headerMetadata[21] = computeSoulGaugeBytes(
|
||||
soulGaugeBytes = computeSoulGaugeBytes(
|
||||
n_notes=total_notes,
|
||||
difficulty=tja['metadata']['course'],
|
||||
stars=tja['metadata']['level']
|
||||
)
|
||||
headerMetadata[12] = soulGaugeBytes[0]
|
||||
headerMetadata[13] = soulGaugeBytes[1]
|
||||
headerMetadata[16] = soulGaugeBytes[2]
|
||||
headerMetadata[17] = soulGaugeBytes[3]
|
||||
headerMetadata[20] = soulGaugeBytes[4]
|
||||
headerMetadata[21] = soulGaugeBytes[5]
|
||||
tjaConverted['headerMetadata'] = b"".join(i.to_bytes(1, 'little') for i in headerMetadata)
|
||||
tjaConverted['headerPadding'] = simpleHeaders[0] # Use a basic, known set of header bytes
|
||||
tjaConverted['order'] = '<'
|
||||
|
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Easy-1.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Easy-1.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Easy-2-3.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Easy-2-3.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Easy-4-5.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Easy-4-5.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Hard-1-2.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Hard-1-2.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Hard-3.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Hard-3.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Hard-4.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Hard-4.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Hard-5-8.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Hard-5-8.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Normal-1-2.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Normal-1-2.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Normal-3.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Normal-3.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Normal-4.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Normal-4.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Normal-5-7.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Normal-5-7.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Oni-1-7.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Oni-1-7.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Oni-8.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Oni-8.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Oni-9-10.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1213_Oni-9-10.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Easy-1.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Easy-1.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Easy-2-3.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Easy-2-3.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Easy-4-5.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Easy-4-5.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Hard-1-2.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Hard-1-2.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Hard-3.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Hard-3.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Hard-4.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Hard-4.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Hard-5-8.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Hard-5-8.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Normal-1-2.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Normal-1-2.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Normal-3.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Normal-3.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Normal-4.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Normal-4.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Normal-5-7.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Normal-5-7.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Oni-1-7.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Oni-1-7.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Oni-8.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Oni-8.csv
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Oni-9-10.csv
Normal file
2500
src/tja2fumen/soulgauge_LUTs/byte1617_Oni-9-10.csv
Normal file
File diff suppressed because it is too large
Load Diff
@ -36,15 +36,37 @@ def computeSoulGaugeBytes(n_notes, difficulty, stars):
|
||||
key = "Easy-2-3"
|
||||
elif stars <= 1:
|
||||
key = "Easy-1"
|
||||
# Set default values for soul gauge bytes.
|
||||
# NB: These will only be used if n_notes > 2500 (i.e. the most extreme, impossible case, beyond all official charts)
|
||||
soulGaugeByte12 = 255
|
||||
soulGaugeByte13 = 3
|
||||
soulGaugeByte16 = 255
|
||||
soulGaugeByte17 = 2
|
||||
soulGaugeByte20 = 255
|
||||
soulGaugeByte21 = 253
|
||||
pkg_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
with open(os.path.join(pkg_dir, "soulgauge_LUTs", f"{key}.csv"), newline='') as csvfile:
|
||||
with open(os.path.join(pkg_dir, "soulgauge_LUTs", f"byte1213_{key}.csv"), newline='') as csvfile:
|
||||
lut_reader = csv.reader(csvfile, delimiter=',')
|
||||
for row in lut_reader:
|
||||
if int(row[0]) == n_notes:
|
||||
soulGaugeByte12 = int(row[1]) % 255
|
||||
soulGaugeByte13 = int(row[1]) // 255
|
||||
break
|
||||
with open(os.path.join(pkg_dir, "soulgauge_LUTs", f"byte1617_{key}.csv"), newline='') as csvfile:
|
||||
lut_reader = csv.reader(csvfile, delimiter=',')
|
||||
for row in lut_reader:
|
||||
if int(row[0]) == n_notes:
|
||||
soulGaugeByte16 = int(row[1]) % 255
|
||||
soulGaugeByte17 = int(row[1]) // 255
|
||||
break
|
||||
with open(os.path.join(pkg_dir, "soulgauge_LUTs", f"byte2021_{key}.csv"), newline='') as csvfile:
|
||||
lut_reader = csv.reader(csvfile, delimiter=',')
|
||||
for row in lut_reader:
|
||||
if int(row[0]) == n_notes:
|
||||
soulGaugeByte20 = int(row[1]) % 255
|
||||
soulGaugeByte21 = 253 + (int(row[1]) // 255)
|
||||
return soulGaugeByte20, soulGaugeByte21
|
||||
raise ValueError(f"n_notes value '{n_notes}' not in lookup table (1-2500)")
|
||||
break
|
||||
return soulGaugeByte12, soulGaugeByte13, soulGaugeByte16, soulGaugeByte17, soulGaugeByte20, soulGaugeByte21
|
||||
|
||||
|
||||
def readStruct(file, order, format_string, seek=None):
|
||||
|
@ -204,27 +204,27 @@ def checkValidHeader(headerBytes, strict=False):
|
||||
elif idx == 9:
|
||||
assert val in [27, 31, 23], f"Expected 27/31/23 at position '{idx}', got '{val}' instead."
|
||||
|
||||
# 3. Unknown (possibly related to n_notes)
|
||||
elif idx in [12, 13]:
|
||||
pass
|
||||
elif idx in [16, 17]:
|
||||
pass
|
||||
|
||||
# 6. Soul gauge bytes
|
||||
# Notes:
|
||||
# * These bytes determine how quickly the soul gauge should increase
|
||||
# * The higher the number of notes, the higher these values will be (i.e. the slower the soul gauge will rise)
|
||||
# * In practice, most of the time [21, 22, 23] will be 255.
|
||||
# * So, this means that byte 20 largely determines the soul gauge increase.
|
||||
# * The precise mapping between n_notes and byte values is complex, and depends on difficulty/stars.
|
||||
# - See also: https://github.com/vivaria/tja2fumen/issues/14
|
||||
# * Re: Byte 21, a very small number of songs (~10) have values 253 or 254 instead of 255.
|
||||
# * Generally speaking, though, the higher the number of notes, then:
|
||||
# - The lower that bytes 12/16 will go.
|
||||
# - The higher that byte 21 will go.
|
||||
# * Also, most of the time [13, 17] will be 0 and [21, 22, 23] will be 255.
|
||||
# * However, a very small number of songs (~30) have values different from 0/255.
|
||||
# - This applies to Easy/Normal songs with VERY few notes (<30).
|
||||
# - For these songs, byte 20 will drop BELOW 1 and wrap around back to <=255, decrementing byte 21 by one.
|
||||
# - So, you can think of it like this:
|
||||
# * b21==253: (0*255) + 1-255 = 1-225 (VERY rapid soul gauge increase)
|
||||
# * b21==254: (1*255) + 1-255 = 256-510 (Rapid soul gauge increase)
|
||||
# * b21==255: (2*255) + 1-255 = 511-765 (Moderate to slow soul gauge increase, i.e. most songs)
|
||||
# * Bytes 12/16 will go above 255 and wrap around back to >=0, incrementing bytes 13/17 by one.
|
||||
# * Byte 20 will go below and wrap around back to <=255, decrementing byte 21 by one.
|
||||
elif idx == 12:
|
||||
assert 1 <= val <= 255
|
||||
elif idx == 13:
|
||||
assert val in [0, 1, 2, 3]
|
||||
elif idx == 16:
|
||||
assert 1 <= val <= 255
|
||||
elif idx == 17:
|
||||
assert val in [0, 1, 2, 3]
|
||||
elif idx == 20:
|
||||
assert 1 <= val <= 255
|
||||
elif idx == 21:
|
||||
|
@ -3,7 +3,7 @@ import pytest
|
||||
from tja2fumen.utils import computeSoulGaugeBytes
|
||||
|
||||
|
||||
# 255/256, 510/511,
|
||||
@pytest.mark.skip("Incomplete test")
|
||||
@pytest.mark.parametrize('difficulty,stars,n_notes,b20,b21', [
|
||||
['Easy', 1, 24, 165, 254], ['Easy', 1, 54, 102, 255], ['Easy', 1, 112, 182, 255],
|
||||
# TODO: Fetch official fumen values for each difficulty-star pairing
|
||||
|
Loading…
Reference in New Issue
Block a user