almost match act_ball_b

This commit is contained in:
roeming
2025-07-17 18:09:15 -04:00
parent b18509dfce
commit 858263c66d
6 changed files with 2219 additions and 1 deletions
+19
View File
@@ -25370,9 +25370,28 @@ modules:
- symbol: act_ant_v
binary: assets/act_ant_v.bin
header: assets/act_ant_v.inc
header_type: none
custom_type: vtx
- symbol: glider_v
binary: assets/glider_v.bin
header: assets/glider_v.inc
header_type: none
custom_type: vtx
- symbol: act_ball_b_pal
binary: assets/act_ball_b_pal.bin
header: assets/act_ball_b_pal.inc
header_type: none
custom_type: pal16
- symbol: act_ball_b_1_tex
binary: assets/act_ball_b_1_tex.bin
header: assets/act_ball_b_1_tex.inc
header_type: raw
- symbol: act_ball_b_v
binary: assets/act_ball_b_v.bin
header: assets/act_ball_b_v.inc
header_type: none
custom_type: vtx
+7 -1
View File
@@ -3678,10 +3678,16 @@ data/scene/broker_shop.c:
data/scene/buggy.c:
.data start:0x0009FBC0 end:0x0009FC28
data/dataobject/dataobject_9FC28:
data/model/act_ball_b.c:
.data start:0x0009FC28 end:0x0009FFD8
data/dataobject/dataobject_9FFD8:
.data start:0x0009FFD8 end:0x000A0738
data/dataobject/dataobject_A0738:
.data start:0x000A0738 end:0x000A1120
data/dataobject/dataobject_A1120:
.data start:0x000A1120 end:0x000A1B78
data/npc/model/mdl/bea_1.c:
+1
View File
@@ -2634,6 +2634,7 @@ config.libs = [
Object(Matching, "data/model/act_ant.c"),
Object(Matching, "data/model/act_ant_anim.c"),
Object(Matching, "data/model/glider.c"),
Object(Matching, "data/model/act_ball_b.c"),
],
),
]
+66
View File
@@ -0,0 +1,66 @@
#include "libforest/gbi_extensions.h"
#include "PR/gbi.h"
#include "evw_anime.h"
u16 act_ball_b_pal[] ATTRIBUTE_ALIGN(32)= {
#include "assets/act_ball_b_pal.inc"
};
u8 act_ball_b_1_tex[] ATTRIBUTE_ALIGN(32)= {
#include "assets/act_ball_b_1_tex.inc"
};
Vtx act_ball_b_v[] = {
#include "assets/act_ball_b_v.inc"
};
Gfx act_ball_b_model[] = {
/* d7000002 ffffffff */ gsSPTexture(65535, 65535, 0, G_TX_RENDERTILE, G_ON),
/* e7000000 00000000 */ gsDPPipeSync(),
/* e200001c c8113078 */ gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2),
/* fc127e60 fffff3f8 */ gsDPSetCombineLERP(TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0, PRIMITIVE, 0, COMBINED, 0, 0, 0, 0, COMBINED),
/* e3001001 00008000 */ gsDPSetTextureLUT(G_TT_RGBA16),
/* fd100000 00000000 */ gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, act_ball_b_pal),
/* e8000000 00000000 */ gsDPTileSync(),
/* f50001f0 07000000 */ gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_4b, 0, 496, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD),
/* e6000000 00000000 */ gsDPLoadSync(),
/* f0000000 0703c000 */ gsDPLoadTLUTCmd(G_TX_LOADTILE, 15),
/* e7000000 00000000 */ gsDPPipeSync(),
/* fd500000 00000000 */ gsDPSetTextureImage(G_IM_FMT_CI, G_IM_SIZ_16b, 1, act_ball_b_1_tex),
/* f5500000 07050140 */ gsDPSetTile(G_IM_FMT_CI, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_MIRROR | G_TX_WRAP, 4, G_TX_NOLOD, G_TX_MIRROR | G_TX_WRAP, 4, G_TX_NOLOD),
/* e6000000 00000000 */ gsDPLoadSync(),
/* f3000000 0703f800 */ gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 63, 2048),
/* e7000000 00000000 */ gsDPPipeSync(),
/* f5400200 00f50140 */ gsDPSetTile(G_IM_FMT_CI, G_IM_SIZ_4b, 1, 0, G_TX_RENDERTILE, 15, G_TX_MIRROR | G_TX_WRAP, 4, G_TX_NOLOD, G_TX_MIRROR | G_TX_WRAP, 4, G_TX_NOLOD),
/* f2000000 0003c03c */ gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, 60, 60),
/* fa000080 ffffffff */ gsDPSetPrimColor(0, 128, 255, 255, 255, 255),
/* d9000000 00230405 */ gsSPLoadGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH),
/* 0101a034 00000000 */ gsSPVertex(act_ball_b_v, 26, 0),
/* 06000204 00020604 */ gsSP2Triangles(0, 1, 2, 0, 1, 3, 2, 0),
/* 06020806 00020a08 */ gsSP2Triangles(1, 4, 3, 0, 1, 5, 4, 0),
/* 06080c06 00080e0c */ gsSP2Triangles(4, 6, 3, 0, 4, 7, 6, 0),
/* 060c0406 000c1004 */ gsSP2Triangles(6, 2, 3, 0, 6, 8, 2, 0),
/* 06121416 00141816 */ gsSP2Triangles(9, 10, 11, 0, 10, 12, 11, 0),
/* 06141a18 00141c1a */ gsSP2Triangles(10, 13, 12, 0, 10, 14, 13, 0),
/* 061a1e18 001a201e */ gsSP2Triangles(13, 15, 12, 0, 13, 16, 15, 0),
/* 061e1618 001e2216 */ gsSP2Triangles(15, 11, 12, 0, 15, 17, 11, 0),
/* 060a0224 00022624 */ gsSP2Triangles(5, 1, 18, 0, 1, 19, 18, 0),
/* 06022826 00020028 */ gsSP2Triangles(1, 20, 19, 0, 1, 0, 20, 0),
/* 06281e26 0028221e */ gsSP2Triangles(20, 15, 19, 0, 20, 17, 15, 0),
/* 061e2426 001e2024 */ gsSP2Triangles(15, 18, 19, 0, 15, 16, 18, 0),
/* 060e082a 00082c2a */ gsSP2Triangles(7, 4, 21, 0, 4, 22, 21, 0),
/* 0608242c 00080a24 */ gsSP2Triangles(4, 18, 22, 0, 4, 5, 18, 0),
/* 06241a2c 0024201a */ gsSP2Triangles(18, 13, 22, 0, 18, 16, 13, 0),
/* 061a2a2c 001a1c2a */ gsSP2Triangles(13, 21, 22, 0, 13, 14, 21, 0),
/* 06100c2e 000c302e */ gsSP2Triangles(8, 6, 23, 0, 6, 24, 23, 0),
/* 060c2a30 000c0e2a */ gsSP2Triangles(6, 21, 24, 0, 6, 7, 21, 0),
/* 062a1430 002a1c14 */ gsSP2Triangles(21, 10, 24, 0, 21, 14, 10, 0),
/* 06142e30 0014122e */ gsSP2Triangles(10, 23, 24, 0, 10, 9, 23, 0),
/* 06000428 00043228 */ gsSP2Triangles(0, 2, 20, 0, 2, 25, 20, 0),
/* 06042e32 0004102e */ gsSP2Triangles(2, 23, 25, 0, 2, 8, 23, 0),
/* 062e1632 002e1216 */ gsSP2Triangles(23, 11, 25, 0, 23, 9, 11, 0),
/* 06162832 00162228 */ gsSP2Triangles(11, 20, 25, 0, 11, 17, 20, 0),
/* df000000 00000000 */ gsSPEndDisplayList()
};
+308
View File
@@ -0,0 +1,308 @@
from argparse import ArgumentParser
from gfxdis import convert_binary_to_gfx
from dataclasses import dataclass
import struct
@dataclass
class EVW_REF:
symbol_name: str
symbol_type: str
@dataclass
class EVW_ANIME_result:
formatted_str: str
referenced_objects: list[EVW_REF]
def anim_type_conv(anim_type: int):
return {
0: "EVW_ANIME_TYPE_SCROLL1",
1: "EVW_ANIME_TYPE_SCROLL2",
2: "EVW_ANIME_TYPE_COLREG_MANUAL",
3: "EVW_ANIME_TYPE_COLREG_LINEAR",
4: "EVW_ANIME_TYPE_COLREG_NONLINEAR",
5: "EVW_ANIME_TYPE_TEXANIME",
}.get(anim_type, str(anim_type))
def parse_evw_anime_data(buff: bytes, symbols: list[str]) -> EVW_ANIME_result:
BUFF_SIZE = 8
assert ((len(buff) % BUFF_SIZE) == 0)
found_syms = []
out_data = ""
i = 0
while True:
b = buff[i:i+BUFF_SIZE]
i += BUFF_SIZE
if len(b) < BUFF_SIZE:
break
(segment, anim_type) = struct.unpack(">bxhxxxx", b)
anim_type = anim_type_conv(anim_type)
this_symbol_name = symbols.pop(0)
vals = (segment, anim_type, this_symbol_name)
out_data += f"\t{{ {', '.join([str(x) for x in vals])} }},\n"
found_syms.append(EVW_REF(this_symbol_name, anim_type))
return EVW_ANIME_result(out_data, found_syms)
def parse_evw_anime_col_prim(buff: bytes, symbols: list[str]):
BUFF_SIZE = 5
assert ((len(buff) % BUFF_SIZE) == 0)
out_data = ""
i = 0
while True:
b = buff[i:i+BUFF_SIZE]
i += BUFF_SIZE
if len(b) < BUFF_SIZE:
break
vals = struct.unpack(">BBBBB", b)
out_data += f"\t{{ {', '.join([str(x) for x in vals])} }},\n"
return EVW_ANIME_result(out_data, [])
def parse_evw_anime_col_env(buff: bytes, symbols: list[str]):
BUFF_SIZE = 4
assert ((len(buff) % BUFF_SIZE) == 0)
out_data = ""
i = 0
while True:
b = buff[i:i+BUFF_SIZE]
i += BUFF_SIZE
if len(b) < BUFF_SIZE:
break
vals = struct.unpack(">BBBB", b)
out_data += f"\t{{ {', '.join([str(x) for x in vals])} }},\n"
return EVW_ANIME_result(out_data, [])
def parse_evw_anime_colreg(buff: bytes, symbols: list[str]):
BUFF_SIZE = 0x10
assert ((len(buff) % BUFF_SIZE) == 0)
found_syms = []
out_data = ""
i = 0
while True:
b = buff[i:i+BUFF_SIZE]
i += BUFF_SIZE
if len(b) < BUFF_SIZE:
break
(frame_count, key_count) = struct.unpack(">HHxxxxxxxxxxxx", b)
prim_colors = symbols.pop(0)
env_colors = symbols.pop(0)
keyframes = symbols.pop(0)
vals = (frame_count, key_count, prim_colors, env_colors, keyframes)
out_data += f"\t{{ {', '.join([str(x) for x in vals])} }},\n"
found_syms.append(EVW_REF(prim_colors, "EVW_ANIME_COL_PRIM"))
found_syms.append(EVW_REF(env_colors, "EVW_ANIME_COL_ENV"))
found_syms.append(EVW_REF(keyframes, "u16"))
return EVW_ANIME_result(out_data, found_syms)
def parse_evw_anime_scroll(buff: bytes, symbols: list[str]):
BUFF_SIZE = 4
assert ((len(buff) % BUFF_SIZE) == 0)
found_syms = []
out_data = ""
i = 0
while True:
b = buff[i:i+BUFF_SIZE]
i += BUFF_SIZE
if len(b) < BUFF_SIZE:
break
vals = struct.unpack(">bbBB", b)
out_data += f"\t{{ {', '.join([str(x) for x in vals])} }},\n"
return EVW_ANIME_result(out_data, found_syms)
def parse_evw_texanime(buff: bytes, symbols: list[str]):
BUFF_SIZE = 0x10
assert ((len(buff) % BUFF_SIZE) == 0)
found_syms = []
out_data = ""
i = 0
while True:
b = buff[i:i+BUFF_SIZE]
i += BUFF_SIZE
if len(b) < BUFF_SIZE:
break
(frame_count, key_count) = struct.unpack(">HHxxxxxxxxxxxx", b)
texture_tbl = symbols.pop(0)
animation_pattern = symbols.pop(0)
keyframes = symbols.pop(0)
vals = (frame_count, key_count, texture_tbl,
animation_pattern, keyframes)
out_data += f"\t{{ {', '.join([str(x) for x in vals])} }},\n"
found_syms.append(EVW_REF(texture_tbl, "VOID*_LIST"))
found_syms.append(EVW_REF(animation_pattern, "u8"))
found_syms.append(EVW_REF(keyframes, "u16"))
return EVW_ANIME_result(out_data, found_syms)
def lookup_bins_and_symbols(lines: list[str], name: str):
out_bin = bytearray()
out_symbols = []
begin_ind = 0
end_ind = 0
for i, line in enumerate(lines):
if line.startswith(f".obj {name}"):
begin_ind = i
if line.startswith(f".endobj {name}"):
end_ind = i
data_lines = lines[begin_ind+1:end_ind]
for line in data_lines:
data = line.split(".4byte ")[1]
try:
out_bin.extend(int(data, 16).to_bytes(4, 'big'))
except Exception as e:
out_bin.extend(b'\0\0\0\0')
out_symbols.append(data)
return out_bin, out_symbols
def convert_source_to_gfx_c_source(src_file, dest_path):
with open(src_file) as f:
lines = f.read().split("\n")
includes = ["libforest/gbi_extensions.h", "PR/gbi.h", "evw_anime.h"]
header = "\n".join([f'#include "{x}"' for x in includes]) + "\n"
# found_objs = []
found_types = []
all_objs = []
for line in lines:
if line.startswith(".obj"):
this_obj = line.split(" ")[1].strip(",")
all_objs.append(this_obj)
if this_obj.endswith("_v"):
found_types.append((this_obj, "Vtx"))
elif "_model" in this_obj:
found_types.append((this_obj, "Gfx"))
elif this_obj.endswith("evw_anime"):
found_types.append((this_obj, "EVW_ANIME_DATA"))
elif this_obj.endswith("_pal"):
found_types.append((this_obj, "PAL"))
elif this_obj.endswith("_tex"):
found_types.append((this_obj, "TEX"))
# we now have a list of all objects, and we have a partial mapping of what type they could have
# what we want to do is go through all the objects we know, and get the out-data
# there are some objs that will add to this list, we can queue them onto the list
converted_types = {}
# we now have a list of objects+type
while len(found_types) > 0:
obj_name, type = found_types.pop()
if obj_name in converted_types:
continue
if type == "Vtx":
data = f'#include "assets/{obj_name}.inc"'
converted_types[obj_name] = (type, data, "")
elif type == "Gfx":
data = convert_binary_to_gfx(
*lookup_bins_and_symbols(lines, obj_name))
converted_types[obj_name] = (type, data, "")
elif type == "PAL":
data = f'#include "assets/{obj_name}.inc"'
converted_types[obj_name] = ("u16", data, "ATTRIBUTE_ALIGN(32)")
elif type == "TEX":
data = f'#include "assets/{obj_name}.inc"'
converted_types[obj_name] = ("u8", data, "ATTRIBUTE_ALIGN(32)")
elif type == "EVW_ANIME_DATA":
res = parse_evw_anime_data(
*lookup_bins_and_symbols(lines, obj_name))
data = res.formatted_str
converted_types[obj_name] = (type, data, "")
for ref in res.referenced_objects:
found_types.insert(
0, (ref.symbol_name, ref.symbol_type))
elif type in ["EVW_ANIME_TYPE_SCROLL1", "EVW_ANIME_TYPE_SCROLL2"]:
res = parse_evw_anime_scroll(
*lookup_bins_and_symbols(lines, obj_name))
data = res.formatted_str
converted_types[obj_name] = ("EVW_ANIME_SCROLL", data, "")
for ref in res.referenced_objects:
found_types.insert(
0, (ref.symbol_name, ref.symbol_type))
elif type == "EVW_ANIME_TYPE_COLREG_MANUAL":
res = parse_evw_anime_colreg(
*lookup_bins_and_symbols(lines, obj_name))
data = res.formatted_str
converted_types[obj_name] = (type, data, "")
for ref in res.referenced_objects:
found_types.insert(
0, (ref.symbol_name, ref.symbol_type))
elif type == "EVW_ANIME_TYPE_COLREG_LINEAR":
res = parse_evw_anime_colreg(
*lookup_bins_and_symbols(lines, obj_name))
data = res.formatted_str
converted_types[obj_name] = (type, data, "")
for ref in res.referenced_objects:
found_types.insert(
0, (ref.symbol_name, ref.symbol_type))
elif type == "EVW_ANIME_TYPE_COLREG_NONLINEAR":
res = parse_evw_anime_colreg(
*lookup_bins_and_symbols(lines, obj_name))
data = res.formatted_str
converted_types[obj_name] = (type, data, "")
for ref in res.referenced_objects:
found_types.insert(
0, (ref.symbol_name, ref.symbol_type))
elif type == "EVW_ANIME_TYPE_TEXANIME":
res = parse_evw_texanime(
*lookup_bins_and_symbols(lines, obj_name))
data = res.formatted_str
converted_types[obj_name] = (type, data, "")
for ref in res.referenced_objects:
found_types.insert(
0, (ref.symbol_name, ref.symbol_type))
elif type == "EVW_ANIME_COL_PRIM":
res = parse_evw_anime_col_prim(
*lookup_bins_and_symbols(lines, obj_name))
data = res.formatted_str
converted_types[obj_name] = (type, data, "")
for ref in res.referenced_objects:
found_types.insert(
0, (ref.symbol_name, ref.symbol_type))
elif type == "EVW_ANIME_COL_ENV":
res = parse_evw_anime_col_env(
*lookup_bins_and_symbols(lines, obj_name))
data = res.formatted_str
converted_types[obj_name] = (type, data, "")
for ref in res.referenced_objects:
found_types.insert(
0, (ref.symbol_name, ref.symbol_type))
elif type == "u16":
assert (False)
elif type == "u8":
assert (False)
out = header + "\n\n"
for obj in all_objs:
this_type, out_data, align = converted_types.get(
obj, (None, None, None))
out += f"{this_type} {obj}[] {align}= {{ \n{out_data}\n}};\n\n"
# print(out)
with open(dest_path, "w") as f:
f.write(out)
def main():
parser = ArgumentParser(
description="Converts a binary file into gfx calls"
)
parser.add_argument("src_path", type=str, help="Binary source file path")
parser.add_argument("dest_path", type=str,
help="Destination C include file path")
args = parser.parse_args()
convert_source_to_gfx_c_source(args.src_path, args.dest_path)
if __name__ == "__main__":
main()
File diff suppressed because it is too large Load Diff