Skip to content

Commit bf7ebf2

Browse files
committed
More research on uvs
1 parent 8f833b4 commit bf7ebf2

1 file changed

Lines changed: 65 additions & 15 deletions

File tree

src/modules/uvsExtractor.py

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,109 @@
44
from pathlib import Path
55
from typing import BinaryIO
66

7+
from pyBjson.string_hash import get_JOAAT_hash
8+
79
def readString(f: BinaryIO) -> bytes:
810
string = b""
911
char = f.read(1)
12+
if len(char) != 1:
13+
raise Exception("End of file")
1014
while char != b'\0':
1115
string += char
1216
char = f.read(1)
17+
if len(char) != 1:
18+
raise Exception("End of file")
1319
return string
1420

1521
def readU16(f: BinaryIO) -> int:
1622
binary = f.read(2)
23+
if len(binary) != 2:
24+
raise Exception("End of file")
1725
num = int.from_bytes(binary, "little", signed=False)
1826
return num
1927

2028
def readU32(f: BinaryIO) -> int:
2129
binary = f.read(4)
30+
if len(binary) != 4:
31+
raise Exception("End of file")
2232
num = int.from_bytes(binary, "little", signed=False)
2333
return num
2434

2535
def readFloat(f: BinaryIO) -> float:
2636
num = struct.unpack("<f", f.read(4))[0]
2737
return num
2838

29-
def exportUVs(fp: str | Path, out_path: str | Path):
39+
def searchHash(elements: list[dict], hashval: int) -> str|None:
40+
for element in elements:
41+
if element["hash"] == hashval:
42+
return element["name"]
43+
return None
44+
45+
def exportUVs(fp: str | Path, out_path: str | Path, verbose: bool = False):
3046
if isinstance(fp, str):
3147
fp = Path(fp).absolute()
3248
if isinstance(out_path, str):
3349
out_path = Path(out_path).absolute()
3450
with open(fp, "rb") as f:
35-
header_1 = readU32(f)
36-
header_2 = readU32(f)
37-
header_3 = readU32(f)
51+
header_1 = readU32(f) # Total amount of elements not repeated
52+
header_2 = readU32(f) # Amount of elements including repeated
53+
header_3 = readU32(f) # Length of all strings
54+
if verbose:
55+
print(f"Header 1: {header_1}")
56+
print(f"Header 2: {header_2}")
57+
print(f"Header 3: {header_3}")
3858

39-
string_ids = []
59+
string_ids: list[str] = []
4060
for i in range(header_2):
4161
string_ids.append(readString(f).decode("utf-8"))
62+
f.seek(0x04 * 3 + header_3) # (Header) + (Length) = Start of UVs data
4263

4364
uvs_data = {}
65+
hashvals = []
4466
for i in range(header_2):
45-
uv_1 = readFloat(f)
46-
uv_2 = readFloat(f)
47-
uv_3 = readFloat(f)
48-
uv_4 = readFloat(f)
49-
w = readU16(f)
50-
h = readU16(f)
51-
unknown1 = readU32(f)
52-
unknown2 = readU32(f)
67+
uv_1 = readFloat(f) # u1 [0-1]
68+
uv_2 = readFloat(f) # v1 [0-1]
69+
uv_3 = readFloat(f) # u2 [0-1]
70+
uv_4 = readFloat(f) # v2 [0-1]
71+
w = readU16(f) # Texture width
72+
h = readU16(f) # Texture height
73+
unknown1 = readU32(f) # Idk
74+
unknown2 = readU32(f) # Could be some kind of binary value ?
5375
strip = string_ids[i].split("/")[-1]
54-
uvs_data[strip] = {"uv": [int(uv_1 * w / 1), int(uv_2 * h / 1), int(uv_3 * w / 1), int(uv_4 * h / 1)]}
76+
if verbose:
77+
print(string_ids[i])
78+
print(f"Unknown 1: {hex(unknown1)}")
79+
print(format(unknown2, "032b"))
80+
uvs_data[strip] = {"uv": [int(uv_1 * w), int(uv_2 * h), int(uv_3 * w), int(uv_4 * h)]}
5581
uvs_data[strip]["tileSize"] = uvs_data[strip]["uv"][2] - uvs_data[strip]["uv"][0]
82+
if verbose:
83+
print(uvs_data[strip])
84+
hashvals.append({"name": strip, "hash": get_JOAAT_hash(strip.lower().encode("utf-8"))})
85+
86+
matched = 0
87+
# This last section seems like an index section
88+
for i in range(header_1):
89+
unknown3 = readU32(f) # Maybe a hash used to sort data ?
90+
unknown4 = readU32(f) # Looks like some repetition value ?
91+
unknown5 = readU32(f) # Looks like an index ?
92+
if verbose:
93+
str_id = searchHash(hashvals, unknown3)
94+
if str_id != None:
95+
print(str_id)
96+
matched += 1
97+
print(unknown3, unknown4, unknown5)
98+
99+
if verbose:
100+
print(f"Strings that matched: {matched}")
101+
print(f"Elements in output: {len(uvs_data)}")
102+
print(f"Header 1: {header_1}")
103+
print(f"Header 2: {header_2}")
104+
print(f"Header 3: {header_3}")
105+
print(f"Final position: {hex(f.tell())}")
56106

57107
with open(out_path, "w") as o:
58108
json.dump(uvs_data, o, indent=4)
59109

60110
if __name__ == "__main__":
61111
os.chdir(os.path.dirname(__file__))
62-
exportUVs("./atlas.items.vanilla.uvs", ".")
112+
exportUVs("./atlas.items.vanilla.uvs", "./atlas.items.vanilla.uvs.json", verbose=True)

0 commit comments

Comments
 (0)