From 50d0bbe0876f213dd6ad3441230b988a6c145c25 Mon Sep 17 00:00:00 2001 From: kyleburnette Date: Wed, 7 Apr 2021 15:08:19 -0700 Subject: [PATCH] dm_sa OK (#88) * initial dm_sa work * more dmsa work * dm_sa OK * Changed char arrays in header to be UNK_TYPE1 * Made all of roz's suggested changes * merge --- include/z64actor.h | 10 +++ linker_scripts/code_script.txt | 5 +- linker_scripts/object_script.txt | 4 + src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c | 103 +++++++++++++++++++--- src/overlays/actors/ovl_Dm_Sa/z_dm_sa.h | 12 ++- src/overlays/actors/ovl_En_Rsn/z_en_rsn.c | 13 +-- tables/functions.txt | 2 +- tools/gen_mips_to_c_context.py | 78 +++++++++------- 8 files changed, 165 insertions(+), 62 deletions(-) diff --git a/include/z64actor.h b/include/z64actor.h index 1c90b274e8..58781a0575 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -338,6 +339,15 @@ typedef enum { /* 0x0B */ ACTORCAT_CHEST } ActorType; +typedef struct { + /* 0x00 */ AnimationHeader* animation; + /* 0x04 */ f32 playSpeed; + /* 0x08 */ f32 startFrame; + /* 0x0C */ f32 frameCount; + /* 0x10 */ u8 mode; + /* 0x14 */ f32 morphFrames; +} ActorAnimationEntry; + typedef enum { /* 0x000 */ ACTOR_PLAYER, /* 0x001 */ ACTOR_EN_TEST, diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index 3c70e2e230..1e079687af 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -2465,7 +2465,6 @@ SECTIONS build/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.o(.text) build/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.o(.data) build/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.o(.rodata) - build/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.o(.rodata) build/src/overlays/actors/ovl_Obj_Hana/z_obj_hana_overlay.o(.ovl) } SegmentEnd = .; @@ -4342,9 +4341,9 @@ SECTIONS ovl_Dm_Sa : AT(RomLocation) { build/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.o(.text) - build/asm/overlays/ovl_Dm_Sa_data.o(.data) + build/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.o(.data) build/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.o(.rodata) - build/asm/overlays/ovl_Dm_Sa_rodata.o(.rodata) + build/src/overlays/actors/ovl_Dm_Sa/z_dm_sa_overlay.o(.ovl) } SegmentEnd = .; SegmentSize = SegmentEnd - SegmentStart; diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index e8cc659234..6f5e676a17 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -123,6 +123,10 @@ D_0600A490 = 0x0600A490; D_06000040 = 0x06000040; D_060024F0 = 0x060024F0; +/* z_dm_sa */ +D_06013328 = 0x06013328; +D_0600CC94 = 0x0600CC94; + /* bg_ikana_shutter */ D_06000F28 = 0x06000F28; D_06000CE8 = 0x06000CE8; diff --git a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c index ac53f53c54..e659b0bab6 100644 --- a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c +++ b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c @@ -9,7 +9,8 @@ void DmSa_Destroy(Actor* thisx, GlobalContext* globalCtx); void DmSa_Update(Actor* thisx, GlobalContext* globalCtx); void DmSa_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void DmSa_DoNothing(DmSa* this, GlobalContext* globalCtx); + const ActorInit Dm_Sa_InitVars = { ACTOR_DM_SA, ACTORCAT_ITEMACTION, @@ -19,28 +20,102 @@ const ActorInit Dm_Sa_InitVars = { (ActorFunc)DmSa_Init, (ActorFunc)DmSa_Destroy, (ActorFunc)DmSa_Update, - (ActorFunc)DmSa_Draw + (ActorFunc)DmSa_Draw, }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/func_80A2E960.asm") +extern SkeletonHeader D_06013328; +extern AnimationHeader D_0600CC94; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/DmSa_Init.asm") +static ActorAnimationEntry D_80A2ED00[] = { { &D_0600CC94, 1.0f, 0, -1.0f, 0, 0 } }; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/DmSa_Destroy.asm") +void func_80A2E960(SkelAnime* arg0, ActorAnimationEntry* animations, u16 index) { + f32 frameCount; + animations += index; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/func_80A2EABC.asm") + if (animations->frameCount < 0.0f) { + frameCount = SkelAnime_GetFrameCount(animations->animation); + } else { + frameCount = animations->frameCount; + } + SkelAnime_ChangeAnim(arg0, animations->animation, animations->playSpeed, animations->startFrame, frameCount, + animations->mode, animations->morphFrames); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/DmSa_Update.asm") +void DmSa_Init(Actor* thisx, GlobalContext* globalCtx) { + DmSa* this = THIS; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/func_80A2EB10.asm") + this->unk2E0 = 0; + this->alpha = 0xFF; + this->actor.targetArrowOffset = 3000.0f; + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f); + SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_06013328, NULL, 0, 0, 0); + func_80A2E960(&this->skelAnime, &D_80A2ED00, 0); + Actor_SetScale(&this->actor, 0.01f); + this->actionFunc = DmSa_DoNothing; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/func_80A2EB2C.asm") +void DmSa_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/func_80A2EB44.asm") +void DmSa_DoNothing(DmSa* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/func_80A2EB58.asm") +void DmSa_Update(Actor* thisx, GlobalContext* globalCtx) { + DmSa* this = THIS; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/func_80A2EBB0.asm") + SkelAnime_FrameUpdateMatrix(&this->skelAnime); + this->alpha += 0; + this->actionFunc(this, globalCtx); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Dm_Sa_0x80A2E960/DmSa_Draw.asm") +s32 func_80A2EB10(s32 arg0, s32 arg1, s32 arg2, s32 arg3) { + return 0; +} + +void func_80A2EB2C(s32 arg0, s32 arg1, s32 arg2, s32 arg3) { +} + +void func_80A2EB44(s32 arg0, s32 arg1, s32 arg2) { +} + +Gfx* func_80A2EB58(GraphicsContext* gfxCtx, u32 alpha) { + Gfx* dList; + Gfx* dListHead; + + dList = dListHead = GRAPH_ALLOC(gfxCtx, sizeof(Gfx) * 2); //! @bug this does not allocate enough for 3 Gfx commands + gDPSetRenderMode(dListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2); + gDPSetEnvColor(dListHead++, 0, 0, 0, alpha); + gSPEndDisplayList(dListHead++); + + return dList; +} + +Gfx* func_80A2EBB0(GraphicsContext* gfxCtx, u32 alpha) { + Gfx* dList; + Gfx* dListHead; + + dList = dListHead = GRAPH_ALLOC(gfxCtx, sizeof(Gfx) * 2); + gDPSetEnvColor(dListHead++, 0, 0, 0, alpha); + gSPEndDisplayList(dListHead++); + + return dList; +} + +void DmSa_Draw(Actor* thisx, GlobalContext* globalCtx) { + DmSa* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->alpha < 0xFF) { + gSPSegment(POLY_OPA_DISP++, 0x0C, func_80A2EB58(globalCtx->state.gfxCtx, this->alpha)); + } else { + gSPSegment(POLY_OPA_DISP++, 0x0C, func_80A2EBB0(globalCtx->state.gfxCtx, this->alpha)); + } + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, + func_80A2EB10, func_80A2EB2C, func_80A2EB44, this); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.h b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.h index c8f020c9a2..2b543deb68 100644 --- a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.h +++ b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.h @@ -5,9 +5,19 @@ struct DmSa; +typedef void (*DmSaActionFunc)(struct DmSa*, GlobalContext*); + typedef struct DmSa { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x1B0]; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ UNK_TYPE1 unk194[0x108]; + /* 0x290 */ DmSaActionFunc actionFunc; + /* 0x294 */ UNK_TYPE1 unk294[0x20]; + /* 0x2B4 */ s32 unk2B4; + /* 0x2B8 */ UNK_TYPE1 unk2B8[0x28]; + /* 0x2E0 */ u16 unk2E0; + /* 0x2E2 */ UNK_TYPE1 unk2E2[0xE]; + /* 0x2F0 */ u32 alpha; } DmSa; // size = 0x2F4 extern const ActorInit Dm_Sa_InitVars; diff --git a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c index 3c1c82589e..6707b30bad 100644 --- a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c +++ b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c @@ -11,15 +11,6 @@ void EnRsn_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80C25D84(EnRsn* this, GlobalContext* globalCtx); -typedef struct { - /* 0x00 */ AnimationHeader* animation; - /* 0x04 */ f32 playbackSpeed; - /* 0x08 */ f32 unk_08; - /* 0x0C */ f32 frameCount; - /* 0x10 */ u8 unk_10; - /* 0x14 */ f32 transitionRate; -} EnRsn_AnimationStruct; // size = 0x18 - const ActorInit En_Rsn_InitVars = { ACTOR_EN_RSN, ACTORCAT_NPC, @@ -37,10 +28,10 @@ extern AnimationHeader D_06009120; extern AnimationHeader D_0600788C; extern Gfx D_06005458[]; -static EnRsn_AnimationStruct animation = { &D_0600788C, 1.0f, 0.0f, 0.0f, 0x00, 0.0f }; +static ActorAnimationEntry animations[] = {{ &D_0600788C, 1.0f, 0.0f, 0.0f, 0x00, 0.0f }}; void func_80C25D40(EnRsn* this) { - func_800BDC5C(&this->skelAnime, &animation, 0); + func_800BDC5C(&this->skelAnime, &animations, 0); this->actionFunc = func_80C25D84; } diff --git a/tables/functions.txt b/tables/functions.txt index 67c2c31b9f..e928e407e0 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -10129,7 +10129,7 @@ 0x80A2E960:("func_80A2E960",), 0x80A2E9FC:("DmSa_Init",), 0x80A2EAAC:("DmSa_Destroy",), - 0x80A2EABC:("func_80A2EABC",), + 0x80A2EABC:("DmSa_DoNothing",), 0x80A2EACC:("DmSa_Update",), 0x80A2EB10:("func_80A2EB10",), 0x80A2EB2C:("func_80A2EB2C",), diff --git a/tools/gen_mips_to_c_context.py b/tools/gen_mips_to_c_context.py index efcc5a1160..5d89bc6c5d 100755 --- a/tools/gen_mips_to_c_context.py +++ b/tools/gen_mips_to_c_context.py @@ -1,22 +1,34 @@ #!/usr/bin/python3 -# This script is based on it's OoT decomp variant - import os import sys import subprocess -import re +import argparse import shlex +from pathlib import Path script_dir = os.path.dirname(os.path.realpath(__file__)) root_dir = script_dir + "/../" -build_dir = root_dir + "build/" src_dir = root_dir + "src/" +def get_c_dir(dirname): + for root, dirs, files in os.walk(src_dir): + for directory in dirs: + if directory == dirname: + return os.path.join(root, directory) + + +def get_c_file(directory): + for root, dirs, files in os.walk(directory): + for file in files: + if file.endswith(".c") and "data" not in file: + return file + + def find_build_command_line(c_file): rel_c_file = os.path.relpath(c_file, root_dir) - make_cmd = ["make", "rom.z64", "--always-make", "--dry-run", "--debug=j", "PERMUTER=1"] + make_cmd = ["make", "rom_uncompressed.z64", "--always-make", "--dry-run", "--debug=j", "PERMUTER=1"] debug_output = ( subprocess.check_output(make_cmd, cwd=root_dir).decode("utf-8").split("\n") ) @@ -47,12 +59,15 @@ def find_build_command_line(c_file): file=sys.stderr, ) sys.exit(1) - + elif len(output) == 0: + print(f"Error: Can't find the file?", file=sys.stderr) + sys.exit(1) return output[0] - -def import_c_file(compiler, in_file): +def import_c_file(in_file): + compiler = find_build_command_line(in_file) in_file = os.path.relpath(in_file, root_dir) + include_next = 0 cpp_command = ["cpp", "-P"] compiler_split = compiler.split(" ") @@ -84,7 +99,7 @@ def import_c_file(compiler, in_file): ] ) cpp_command.append(in_file) - + try: return subprocess.check_output(cpp_command, cwd=root_dir, encoding="utf-8") except subprocess.CalledProcessError: @@ -95,32 +110,31 @@ def import_c_file(compiler, in_file): ) sys.exit(1) - -def get_c_dir(dirname): - for root, dirs, files in os.walk(src_dir): - for dir in dirs: - if dir == dirname: - return os.path.join(root, dir) - - -def get_c_file(dir): - for root, dirs, files in os.walk(dir): - for file in files: - if file.endswith(".c") and "data" not in file: - return file - - def main(): - this_dir = os.getcwd().split("/")[-1] - c_dir_path = get_c_dir(this_dir) - c_file = get_c_file(c_dir_path) - c_file_path = os.path.join(c_dir_path, c_file) + parser = argparse.ArgumentParser(usage="./gen_mips_to_c_context.py --file path/to/file.c or ./gen_mips_to_c_context.py (from an actor or gamestate's asm dir)", + description="Creates a ctx.c file for mips2c. " + "Output will be saved as oot/ctx.c") + parser.add_argument('--file', help="path of c file to be processed", required=False) + args = parser.parse_args() - compiler = find_build_command_line(c_file_path) - output = import_c_file(compiler, c_file_path) - - with open(os.path.join(build_dir, "ctx.c"), "w") as f: + if args.file: + c_file_path = args.file + print("Using file: {}".format(c_file_path)) + else: + this_dir = Path.cwd() + c_dir_path = get_c_dir(this_dir.name) + if c_dir_path is None: + sys.exit( + "Cannot find appropriate c file dir. In argumentless mode, run this script from the c file's corresponding asm dir.") + c_file = get_c_file(c_dir_path) + c_file_path = os.path.join(c_dir_path, c_file) + print("Using file: {}".format(c_file_path)) + + output = import_c_file(c_file_path) + + with open(os.path.join(root_dir, "ctx.c"), "w", encoding="UTF-8") as f: f.write(output) + if __name__ == "__main__": main()