diff --git a/include/imgfx.h b/include/imgfx.h new file mode 100644 index 0000000000..b833d0ad50 --- /dev/null +++ b/include/imgfx.h @@ -0,0 +1,23 @@ +#ifndef _IMGFX_H_ +#define _IMGFX_H_ + +#include "PR/gbi.h" + +// 'compressed' vertex data for animated image fx keyframes +typedef struct ImgFXVtx { + /* 0x00 */ s16 ob[3]; + /* 0x06 */ u8 tc[2]; + /* 0x08 */ s8 cn[3]; + /* 0x0B */ char unk_0B; +} ImgFXVtx; // size = 0x0C + +typedef struct ImgFXAnimHeader { + /* 0x00 */ ImgFXVtx* keyframesOffset; + /* 0x04 */ Gfx* gfxOffset; // Gfx for creating mesh from vertices + /* 0x08 */ u16 vtxCount; // conserved across keyframes + /* 0x0A */ u16 gfxCount; + /* 0x0C */ u16 keyframesCount; + /* 0x0E */ u16 flags; +} ImgFXAnimHeader; // size = 0x10 + +#endif /* _IMGFX_H_ */ diff --git a/src/d0a70_len_4fe0.c b/src/imgfx.c similarity index 96% rename from src/d0a70_len_4fe0.c rename to src/imgfx.c index b3e80e7049..bc44849e96 100644 --- a/src/d0a70_len_4fe0.c +++ b/src/imgfx.c @@ -1,10 +1,11 @@ #include "common.h" #include "ld_addrs.h" #include "sprite.h" +#include "imgfx.h" #if VERSION_IQUE // TODO: remove if section is split in iQue release -extern Addr imgfx_gfx_data_ROM_START; +extern Addr imgfx_data_ROM_START; #endif typedef union ImgFXIntVars { @@ -98,15 +99,6 @@ typedef struct ImgFXCacheEntry { /* 0x06 */ char unk_06[0x2]; } ImgFXCacheEntry; // size = 0x8 -typedef struct ImgFXAnimHeader { - /* 0x00 */ s32 keyframesOffset; - /* 0x04 */ Gfx* gfxOffset; // Gfx for creating mesh from vertices - /* 0x08 */ u16 vtxCount; // conserved across keyframes - /* 0x0A */ u16 gfxCount; - /* 0x0C */ u16 keyframesCount; - /* 0x0E */ u16 flags; -} ImgFXAnimHeader; // size = 0x10 - enum ImgFXAnimFlags { IMGFX_ANIM_FLAG_ABSOLUTE_COORDS = 1, // image-relative (in percent) when unset }; @@ -117,14 +109,6 @@ typedef struct ImgFXRenderMode { /* 0x8 */ u8 flags; // only checks TRUE so far. some kind of switch? } ImgFXRenderMode; // size = 0xC -// 'compressed' vertex data for animated image fx keyframes -typedef struct ImgFXVtx { - /* 0x00 */ s16 ob[3]; - /* 0x06 */ u8 tc[2]; - /* 0x08 */ s8 cn[3]; - /* 0x0B */ char unk_0B; -} ImgFXVtx; // size = 0x0C - typedef ImgFXState ImgFXInstanceList[MAX_IMGFX_INSTANCES]; extern HeapNode heap_spriteHead; @@ -194,28 +178,49 @@ ImgFXRenderMode ImgFXRenderModes[] = { [IMGFX_RENDER_UNUSED] { 0x00441208, 0x00111208, 0 }, }; -// all relative to imgfx_gfx_data_ROM_START -s32 ImgFXAnimOffsets[] = { - [IMGFX_ANIM_SHOCK] 0x14358, - [IMGFX_ANIM_SHIVER] 0x18200, - [IMGFX_ANIM_VERTICAL_PIPE_CURL] 0x1A858, - [IMGFX_ANIM_HORIZONTAL_PIPE_CURL] 0x1E830, - [IMGFX_ANIM_STARTLE] 0x29458, - [IMGFX_ANIM_FLUTTER_DOWN] 0x314E0, - [IMGFX_ANIM_UNFURL] 0x33498, - [IMGFX_ANIM_GET_IN_BED] 0x38988, - [IMGFX_ANIM_SPIRIT_CAPTURE] 0x39228, - [IMGFX_ANIM_UNUSED_1] 0x5B7A8, - [IMGFX_ANIM_UNUSED_2] 0x7CF10, - [IMGFX_ANIM_UNUSED_3] 0x86490, - [IMGFX_ANIM_TUTANKOOPA_GATHER] 0x96258, - [IMGFX_ANIM_TUTANKOOPA_SWIRL_2] 0xA1820, - [IMGFX_ANIM_TUTANKOOPA_SWIRL_1] 0xACDE8, - [IMGFX_ANIM_SHUFFLE_CARDS] 0xBBF68, - [IMGFX_ANIM_FLIP_CARD_1] 0xC0490, - [IMGFX_ANIM_FLIP_CARD_2] 0xC49B8, - [IMGFX_ANIM_FLIP_CARD_3] 0xC6150, - [IMGFX_ANIM_CYMBAL_CRUSH] 0xCA380, +extern Addr shock_header; +extern Addr shiver_header; +extern Addr vertical_pipe_curl_header; +extern Addr horizontal_pipe_curl_header; +extern Addr startle_header; +extern Addr flutter_down_header; +extern Addr unfurl_header; +extern Addr get_in_bed_header; +extern Addr spirit_capture_header; +extern Addr unused_1_header; +extern Addr unused_2_header; +extern Addr unused_3_header; +extern Addr tutankoopa_gather_header; +extern Addr tutankoopa_swirl_2_header; +extern Addr tutankoopa_swirl_1_header; +extern Addr shuffle_cards_header; +extern Addr flip_card_1_header; +extern Addr flip_card_2_header; +extern Addr flip_card_3_header; +extern Addr cymbal_crush_header; + +// all relative to imgfx_data_ROM_START +u8* ImgFXAnimOffsets[] = { + [IMGFX_ANIM_SHOCK] shock_header, + [IMGFX_ANIM_SHIVER] shiver_header, + [IMGFX_ANIM_VERTICAL_PIPE_CURL] vertical_pipe_curl_header, + [IMGFX_ANIM_HORIZONTAL_PIPE_CURL] horizontal_pipe_curl_header, + [IMGFX_ANIM_STARTLE] startle_header, + [IMGFX_ANIM_FLUTTER_DOWN] flutter_down_header, + [IMGFX_ANIM_UNFURL] unfurl_header, + [IMGFX_ANIM_GET_IN_BED] get_in_bed_header, + [IMGFX_ANIM_SPIRIT_CAPTURE] spirit_capture_header, + [IMGFX_ANIM_UNUSED_1] unused_1_header, + [IMGFX_ANIM_UNUSED_2] unused_2_header, + [IMGFX_ANIM_UNUSED_3] unused_3_header, + [IMGFX_ANIM_TUTANKOOPA_GATHER] tutankoopa_gather_header, + [IMGFX_ANIM_TUTANKOOPA_SWIRL_2] tutankoopa_swirl_2_header, + [IMGFX_ANIM_TUTANKOOPA_SWIRL_1] tutankoopa_swirl_1_header, + [IMGFX_ANIM_SHUFFLE_CARDS] shuffle_cards_header, + [IMGFX_ANIM_FLIP_CARD_1] flip_card_1_header, + [IMGFX_ANIM_FLIP_CARD_2] flip_card_2_header, + [IMGFX_ANIM_FLIP_CARD_3] flip_card_3_header, + [IMGFX_ANIM_CYMBAL_CRUSH] cymbal_crush_header, }; extern ImgFXCacheEntry ImgFXDataCache[8]; @@ -1051,7 +1056,7 @@ void imgfx_appendGfx_mesh(ImgFXState* state, Matrix4f mtx) { case IMGFX_RENDER_OVERLAY_RGBA: // color: texture // alpha: texture * prim - gDPSetCombineLERP(gMainGfxPos++, + gDPSetCombineLERP(gMainGfxPos++, 0, 0, 0, TEXEL0, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, TEXEL0, TEXEL0, 0, PRIMITIVE, 0); gDPSetPrimColor(gMainGfxPos++, 0, 0, 0, 0, 0, state->ints.overlay.alpha); @@ -1215,7 +1220,7 @@ void imgfx_mesh_make_grid(ImgFXState* state) { } ImgFXAnimHeader* imgfx_load_anim(ImgFXState* state) { - u8* romStart = ImgFXAnimOffsets[state->ints.anim.type] + imgfx_gfx_data_ROM_START; + u8* romStart = (s32) ImgFXAnimOffsets[state->ints.anim.type] + imgfx_data_ROM_START; ImgFXAnimHeader* anim = &ImgFXAnimHeaders[state->arrayIdx]; if (state->curAnimOffset != romStart) { @@ -1249,7 +1254,7 @@ ImgFXAnimHeader* imgfx_load_anim(ImgFXState* state) { state->gfxBufs[0] = heap_malloc(anim->gfxCount * sizeof(Gfx)); state->gfxBufs[1] = heap_malloc(anim->gfxCount * sizeof(Gfx)); - romStart = imgfx_gfx_data_ROM_START + (s32)anim->gfxOffset; + romStart = imgfx_data_ROM_START + (s32)anim->gfxOffset; romEnd = romStart + anim->gfxCount * sizeof(Gfx); dma_copy(romStart, romEnd, state->gfxBufs[0]); dma_copy(romStart, romEnd, state->gfxBufs[1]); @@ -1271,7 +1276,7 @@ ImgFXAnimHeader* imgfx_load_anim(ImgFXState* state) { // ImgFXVtx structs are 0xC bytes while Vtx are 0x10, so we need a (4/3) scaling factor // to compute a new, equivalent Vtx[i] address for an existing ImgFXVtx[i] address. // Unfortunately, using sizeof here does not match. - gfxBuffer[j-1].words.w1 = ((((s32) gfxBuffer[j-1].words.w1 - anim->keyframesOffset) / 3) * 4) + + gfxBuffer[j-1].words.w1 = ((((s32) gfxBuffer[j-1].words.w1 - (s32) anim->keyframesOffset) / 3) * 4) + (s32) state->vtxBufs[i]; } } while (cmd != G_ENDDL); @@ -1331,11 +1336,11 @@ void imgfx_mesh_anim_update(ImgFXState* state) { // find the current + next keyframe vertex data curKeyframe = heap_malloc(header->vtxCount * sizeof(ImgFXVtx)); - romStart = (u8*)((s32)imgfx_gfx_data_ROM_START + header->keyframesOffset + curKeyIdx * header->vtxCount * sizeof(ImgFXVtx)); + romStart = (u8*)((s32)imgfx_data_ROM_START + (s32) header->keyframesOffset + curKeyIdx * header->vtxCount * sizeof(ImgFXVtx)); dma_copy(romStart, romStart + header->vtxCount * sizeof(ImgFXVtx), curKeyframe); if (keyframeInterval > 1) { nextKeyframe = heap_malloc(header->vtxCount * sizeof(*nextKeyframe)); - romStart = (u8*)((s32)imgfx_gfx_data_ROM_START + header->keyframesOffset + nextKeyIdx * header->vtxCount * sizeof(ImgFXVtx)); + romStart = (u8*)((s32)imgfx_data_ROM_START + (s32) header->keyframesOffset + nextKeyIdx * header->vtxCount * sizeof(ImgFXVtx)); dma_copy(romStart, romStart + header->vtxCount * sizeof(ImgFXVtx), nextKeyframe); } diff --git a/tools/build/configure.py b/tools/build/configure.py index 1e77beaa09..9665e418c3 100755 --- a/tools/build/configure.py +++ b/tools/build/configure.py @@ -217,6 +217,8 @@ def write_ninja_rules(ninja: ninja_syntax.Writer, cpp: str, extra_cppflags: str, ninja.rule("pm_sprite_shading_profiles", command=f"$python {BUILD_TOOLS}/sprite/sprite_shading_profiles.py $in $out $header_path") + ninja.rule("pm_imgfx_data", command=f"$python {BUILD_TOOLS}/imgfx/imgfx_data.py $in $out") + with Path("tools/permuter_settings.toml").open("w") as f: f.write(f"compiler_command = \"{cc} {CPPFLAGS.replace('$version', 'us')} {cflags} -DPERMUTER -fforce-addr\"\n") f.write(f"assembler_command = \"{cross}as -EB -march=vr4300 -mtune=vr4300 -Iinclude\"\n") @@ -257,7 +259,7 @@ class Configure: if assets: modes.extend(["bin", "yay0", "img", "vtx", "vtx_common", "gfx", "gfx_common", "pm_map_data", "pm_msg", "pm_npc_sprites", "pm_charset","pm_charset_palettes", "pm_effect_loads", "pm_effect_shims", - "pm_sprite_shading_profiles"]) + "pm_sprite_shading_profiles", "pm_imgfx_data"]) if code: modes.extend(["code", "c", "data", "rodata"]) @@ -366,12 +368,12 @@ class Configure: order_only.append("generated_headers_" + self.version) ninja.build( - object_strs, # $out - task, - self.resolve_src_paths(src_paths), # $in - variables={ "version": self.version, **variables }, + outputs=object_strs, # $out + rule=task, + inputs=self.resolve_src_paths(src_paths), # $in implicit=implicit, order_only=order_only, + variables={ "version": self.version, **variables }, implicit_outputs=implicit_outputs ) @@ -688,6 +690,15 @@ class Configure: "header_path": header_path, }) build(entry.object_path, [entry.object_path.with_suffix("")], "bin") + elif seg.type == "pm_imgfx_data": + c_file_path = Path(f"assets/{self.version}") / "imgfx" / (seg.name + ".c") + build(c_file_path, entry.src_paths, "pm_imgfx_data") + + build(entry.object_path, [c_file_path], "cc" if not modern_gcc else "cc_modern", variables={ + "cflags": "", + "cppflags": f"-DVERSION_{self.version.upper()}", + "encoding": "CP932", # similar to SHIFT-JIS, but includes backslash and tilde + }) elif seg.type == "linker" or seg.type == "linker_offset": pass else: diff --git a/tools/build/imgfx/__init__.py b/tools/build/imgfx/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/build/imgfx/imgfx_data.py b/tools/build/imgfx/imgfx_data.py new file mode 100644 index 0000000000..70d208559e --- /dev/null +++ b/tools/build/imgfx/imgfx_data.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python3 + +from dataclasses import dataclass +import argparse +import json +from pathlib import Path +from typing import Any, List +import yaml as yaml_loader + +@dataclass +class Vertex: + idx: int + x: int + y: int + z: int + u: int + v: int + r: int + g: int + b: int + a: int + + def toJSON(self): + return " { \"pos\": [" + f"{self.x}, {self.y}, {self.z}" + "], \"uv\": [" + f"{self.u}, {self.v}" + "], \"rgba\": [" + f"{self.r}, {self.g}, {self.b}, {self.a}" + "] }" + +@dataclass +class Triangle: + i: int + j: int + k: int + + def toJSON(self): + return f" [{self.i}, {self.j}, {self.k}]" + +@dataclass +class Anim: + name: str + offset: int + vtx_offset: int + gfx_offset: int + vtx_count: int + gfx_count: int + keyframes: int + flags: int + + frames: List[List[Vertex]] + triangles: List[Triangle] + + def toJSON(self): + framestr = ",\n".join([" [\n" + ",\n".join([v.toJSON() for v in frame]) + "\n ]" for i, frame in enumerate(self.frames)]) + trianglestr = ",\n".join([t.toJSON() for t in self.triangles]) + + ret = "{\n" + ret += " \"flags\": " + str(self.flags) + ",\n" + ret += " \"frames\": [\n" + framestr + "],\n" + ret += " \"triangles\": [\n" + trianglestr + "]\n" + ret += "}" + + return ret + + @staticmethod + def fromJSON(name: str, data: Any) -> "Anim": + flags = data["flags"] + frames = [[Vertex(idx, *vtx["pos"], *vtx["uv"], *vtx["rgba"]) for idx, vtx in enumerate(frame)] for frame in data["frames"]] + triangles = [Triangle(*t) for t in data["triangles"]] + + return Anim( + name=name, + offset=0, + vtx_offset=0, + gfx_offset=0, + vtx_count=0, + gfx_count=0, + keyframes=len(frames), + flags=flags, + frames=frames, + triangles=triangles + ) + +def build(inputs: List[Path], output: Path): + with open(output, "w") as f: + f.write("/* NOTE: This file is autogenerated, do not edit */\n\n") + f.write("#include \"PR/gbi.h\"\n") + f.write("#include \"macros.h\"\n") + f.write("#include \"imgfx.h\"\n\n") + + for input in inputs: + with open(input, "r") as fin: + in_json = json.load(fin) + + anim = Anim.fromJSON(input.name[:-5], in_json) + + vtx_name = f"{anim.name}_keyframes" + gfx_name = f"{anim.name}_gfx" + + # this has padding before it..maybe a file split? + if anim.name == "unused_1": + f.write(f"s32 padding_{anim.name}[] = {{ 0, 0 }};\n\n") + + # vtx + f.write(f"ImgFXVtx {vtx_name}[{len(anim.frames)}][{len(anim.frames[0])}] = {{\n") + for frame in anim.frames: + f.write(" {\n") + for vtx in frame: + f.write(f" {{ {{{vtx.x}, {vtx.y}, {vtx.z}}}, {{{vtx.u}, {vtx.v}}}, {{{vtx.r}, {vtx.g}, {vtx.b}}}, {vtx.a} }},\n") + f.write(" },\n") + f.write("};\n\n") + + # gfx + f.write(f"Gfx {gfx_name}[] = {{\n") + + # TODO hard-coded + cur_tri = 0 + just_chunked = False + chunk_text = "" + max_t1 = 0 + max_t2 = 0 + min_t = 0 + sub_num = 0 + old_max_t = 0 + while cur_tri < len(anim.triangles): + # Vertex command every 16 triangles + t1 = anim.triangles[cur_tri] + t2 = anim.triangles[cur_tri + 1] if cur_tri + 1 < len(anim.triangles) else None + + t1x = t1.i - sub_num + t1y = t1.j - sub_num + t1z = t1.k - sub_num + max_t1 = max(max_t1, t1x, t1y, t1z) + t2x = 0 if t2 is None else t2.i - sub_num + t2y = 0 if t2 is None else t2.j - sub_num + t2z = 0 if t2 is None else t2.k - sub_num + max_t2 = max(max_t2, t2x, t2y, t2z) + min_t = min(min_t, t1x, t1y, t1z, t2x, t2y, t2z) + + # We need a new chunk + if max_t1 >= 32 and not just_chunked: + chunk_text = f" gsSPVertex((u8*){vtx_name} + 0xC * {sub_num}, {min(32, max_t1 + 1)}, 0),\n" + chunk_text + just_chunked = True + f.write(chunk_text) + chunk_text = "" + sub_num += old_max_t - min_t + 1 + min_t = 32 + max_t1 = 0 + max_t2 = 0 + continue + + just_chunked = False + if max_t2 >= 32 or t2 is None: + chunk_text += f" gsSP1Triangle({t1x}, {t1y}, {t1z}, 0),\n" + cur_tri += 1 + old_max_t = max_t1 + else: + chunk_text += f" gsSP2Triangles({t1x}, {t1y}, {t1z}, 0, {t2x}, {t2y}, {t2z}, 0),\n" + cur_tri += 2 + old_max_t = max(max_t1, max_t2) + + # Dump final chunk + chunk_text = f" gsSPVertex((u8*){vtx_name} + 0xC * {sub_num}, {max(max_t1, max_t2) + 1}, 0),\n" + chunk_text + f.write(chunk_text) + f.write(" gsSPEndDisplayList(),\n") + f.write("};\n\n") + + # header + f.write(f"ImgFXAnimHeader {anim.name}_header = {{\n") + f.write(f" .keyframesOffset = {vtx_name}[0],\n") + f.write(f" .gfxOffset = {gfx_name},\n") + f.write(f" .vtxCount = ARRAY_COUNT({vtx_name}[0]),\n") + f.write(f" .gfxCount = ARRAY_COUNT({gfx_name}),\n") + f.write(f" .keyframesCount = ARRAY_COUNT({vtx_name}),\n") + f.write(f" .flags = {anim.flags},\n") + f.write("};\n\n") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="ImgFX animation c file builder") + parser.add_argument("inputs", type=Path, help="json files to build, passed in order", nargs="+") + parser.add_argument("output", type=Path, help="Output c file path") + args = parser.parse_args() + + build(args.inputs, args.output) diff --git a/tools/splat_ext/pm_imgfx_data.py b/tools/splat_ext/pm_imgfx_data.py new file mode 100644 index 0000000000..f7b2d84644 --- /dev/null +++ b/tools/splat_ext/pm_imgfx_data.py @@ -0,0 +1,107 @@ +import os +import struct +import sys +from pathlib import Path +import yaml as yaml_loader +from typing import List, Tuple + +TOOLS_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.append(str(Path(TOOLS_DIR) / "build/imgfx")) +from imgfx_data import Anim, Triangle, Vertex + +from segtypes.n64.segment import N64Segment +from util import log, options + + +class N64SegPm_imgfx_data(N64Segment): + anims: List[Anim] = [] + + OUT_DIR: Path = options.opts.asset_path / "imgfx" + + def scan(self, rom_bytes): + data = rom_bytes[self.rom_start:self.rom_end] + + for name, offset in self.yaml.get("animations"): + pos = offset + + # Animations start with vtx data which is followed by gfx data and ends with the header at `offset` + vtx_offset, gfx_offset, vtx_count, gfx_count, keyframes, flags = struct.unpack(">IIHHHH", data[pos:pos+16]) + + frames: List[List[Vertex]] = [] + + pos = vtx_offset + for i in range(keyframes): + frame: List[Vertex] = [] + + for j in range(vtx_count): + x, y, z, u, v, r, g, b, a = struct.unpack(">hhhBBbbbB", data[pos:pos+12]) + pos += 12 + frame.append(Vertex(j, x, y, z, u, v, r, g, b, a)) + + frames.append(frame) + + triangles: List[Triangle] = [] + vtx_buf: List[int] = [] + + # Align to 8 bytes + pos = (pos + 7) & ~(8 - 1) + assert(pos == gfx_offset) + + def unpack_tri(word: int, vtx_buf: List[int]) -> Tuple[int, int, int]: + i = (word >> 16) & 0xFF + j = (word >> 8) & 0xFF + k = word & 0xFF + + i = vtx_buf[int(i / 2)] + j = vtx_buf[int(j / 2)] + k = vtx_buf[int(k / 2)] + + return (i, j, k) + + for i in range(gfx_count): + w0, w1 = struct.unpack(">II", data[pos:pos+8]) + pos += 8 + + op = (w0 >> 24) & 0xFF + + if op == 1: # G_VTX + num = w0 >> 12 & 0xFF + end = int((w0 & 0xFF) / 2) + src_idx = int((w1 - vtx_offset) / 12) + start = end - num + + for j in range(num): + to_place_pos = start + j + while len(vtx_buf) <= to_place_pos: + vtx_buf.append(0) + vtx_buf[to_place_pos] = src_idx + j + elif op == 5: # G_TRI1 + triangles.append(Triangle(*unpack_tri(w0, vtx_buf))) + elif op == 6: # G_TRI2 + triangles.append(Triangle(*unpack_tri(w0, vtx_buf))) + triangles.append(Triangle(*unpack_tri(w1, vtx_buf))) + elif op == 0xDF: # G_ENDDL + pass + else: + log.error(f"Unknown op: {op}") + + self.anims.append(Anim(name, offset, vtx_offset, gfx_offset, vtx_count, gfx_count, keyframes, flags, frames, triangles)) + + + def split(self, rom_bytes): + self.OUT_DIR.mkdir(parents=True, exist_ok=True) + for anim in self.anims: + with open(f"{self.OUT_DIR}/{anim.name}.json", "w") as f: + f.write(anim.toJSON()) + + def get_linker_entries(self): + from segtypes.linker_entry import LinkerEntry + + return [ + LinkerEntry( + self, + [self.OUT_DIR / f"{anim.name}.json" for anim in self.anims], + options.opts.asset_path / "imgfx" / f"{self.name}.c", + self.get_linker_section(), + ) + ] diff --git a/ver/ique/splat.yaml b/ver/ique/splat.yaml index ac283bef25..afb551730c 100644 --- a/ver/ique/splat.yaml +++ b/ver/ique/splat.yaml @@ -409,7 +409,7 @@ segments: - [0xC4010, c, C50A0] - [0xCC0F0, c, cd180_len_38f0] - [0xCDDB0, c, CEE40] - - [0xCF9E0, c, d0a70_len_4fe0] + - [0xCF9E0, c, imgfx] - [0xD49C0, c, hud_element] - [0xDA990, c, dba20_len_350] - [0xDACE0, c, trigger] @@ -438,27 +438,14 @@ segments: - [0xE3DE0, vtx, vtx/stencil2] - [0xE3F60] - [0xE4400, .data, CEE40] - - [0xE4480, .data, d0a70_len_4fe0] + - [0xE4480, .data, imgfx] - [0xE4630, .data, hud_element] - [0xE4790, .data, dc470_len_14c0] - [0xE47B0, .data, audio/ambience] - [0xE47C0, .data, windows] - [0xE4940, .data, audio/sfx] - [0xE4D60, .data, audio/e0b30_len_b80] - - [0xE4DB0, .rodata, a5dd0_len_114e0] - - [0xE54D0, .rodata, B4580] - - [0xE5720, .rodata, entity_model] - - [0xE59E0, .rodata, msg] - - [0xE60B0, .rodata, C50A0] - - [0xE6510, .rodata, cd180_len_38f0] - - [0xE65F0, .rodata, CEE40] - - [0xE6620, .rodata, d0a70_len_4fe0] - - [0xE67B0, .rodata, hud_element] - - [0xE6890, .rodata, dc470_len_14c0] - - [0xE68B0, .rodata, windows] - - [0xE68C0, .rodata, audio/sfx] - - [0xE6900, .rodata, audio/e0b30_len_b80] - - [0xE6920] + - [0xE4DB0] - name: evt dir: evt type: code diff --git a/ver/ique/undefined_syms.txt b/ver/ique/undefined_syms.txt index 01615b0712..87895633be 100644 --- a/ver/ique/undefined_syms.txt +++ b/ver/ique/undefined_syms.txt @@ -1143,7 +1143,27 @@ entity_sbk_omo_ROM_START = 0x00e78190; entity_jan_iwa_ROM_END = 0x00e78190; entity_default_ROM_START = 0x00e73f70; entity_default_ROM_END = 0x00e76170; -imgfx_gfx_data_ROM_START = 0x00294870; +imgfx_data_ROM_START = 0x00294870; +shock_header = 0x14358; +shiver_header = 0x18200; +vertical_pipe_curl_header = 0x1A858; +horizontal_pipe_curl_header = 0x1E830; +startle_header = 0x29458; +flutter_down_header = 0x314E0; +unfurl_header = 0x33498; +get_in_bed_header = 0x38988; +spirit_capture_header = 0x39228; +unused_1_header = 0x5B7A8; +unused_2_header = 0x7CF10; +unused_3_header = 0x86490; +tutankoopa_gather_header = 0x96258; +tutankoopa_swirl_2_header = 0xA1820; +tutankoopa_swirl_1_header = 0xACDE8; +shuffle_cards_header = 0xBBF68; +flip_card_1_header = 0xC0490; +flip_card_2_header = 0xC49B8; +flip_card_3_header = 0xC6150; +cymbal_crush_header = 0xCA380; sort_items = 0x800e5aac; suggest_player_anim_always_forward = 0x800de358; add_item = 0x800e5954; diff --git a/ver/us/splat.yaml b/ver/us/splat.yaml index a194fee99b..a9ae0339a2 100644 --- a/ver/us/splat.yaml +++ b/ver/us/splat.yaml @@ -832,7 +832,7 @@ segments: - [0xC50A0, c, C50A0] - [0xCD180, c, cd180_len_38f0] - [0xCEE40, c, CEE40] - - [0xD0A70, c, d0a70_len_4fe0] + - [0xD0A70, c, imgfx] - [0xD5A50, c, hud_element] - [0xDBA20, c, dba20_len_350] - [0xDBD70, c, trigger] @@ -861,7 +861,7 @@ segments: - [0xE4E70, vtx, vtx/stencil2] - [0xE4FF0] - [0xE5490, .data, CEE40] - - [0xE5510, .data, d0a70_len_4fe0] + - [0xE5510, .data, imgfx] - [0xE56C0, .data, hud_element] - [0xE5820, .data, dc470_len_14c0] - [0xE5840, .data, audio/ambience] @@ -2596,7 +2596,31 @@ segments: - [0x2435F0, ia8, title/tape, 128, 128] - [0x2475F0, ci8, title/bowser_silhouette, 128, 128] - [0x24B5F0, palette, title/bowser_silhouette] - - [0x24B7F0, bin, imgfx_gfx_data] # TODO extract into better format? + - start: 0x24B7F0 + type: pm_imgfx_data + name: imgfx_data + vram: 0 + animations: + - ["shock", 0x14358] + - ["shiver", 0x18200] + - ["vertical_pipe_curl", 0x1A858] + - ["horizontal_pipe_curl", 0x1E830] + - ["startle", 0x29458] + - ["flutter_down", 0x314E0] + - ["unfurl", 0x33498] + - ["get_in_bed", 0x38988] + - ["spirit_capture", 0x39228] + - ["unused_1", 0x5B7A8] + - ["unused_2", 0x7CF10] + - ["unused_3", 0x86490] + - ["tutankoopa_gather", 0x96258] + - ["tutankoopa_swirl_2", 0xA1820] + - ["tutankoopa_swirl_1", 0xACDE8] + - ["shuffle_cards", 0xBBF68] + - ["flip_card_1", 0xC0490] + - ["flip_card_2", 0xC49B8] + - ["flip_card_3", 0xC6150] + - ["cymbal_crush", 0xCA380] - [0x315B80, pm_sprite_shading_profiles, sprite_shading_profiles] - type: code start: 0x3169F0