diff --git a/code/Makefile b/code/Makefile index 67437b6a..d52f0072 100644 --- a/code/Makefile +++ b/code/Makefile @@ -33,7 +33,7 @@ include $(DEVKITARM)/3ds_rules #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) BUILD := build -SOURCES := source source/asm source/lib source/common source/game source/rnd source/game/ui/screens source/rnd/actors +SOURCES := source source/asm source/asm/actors source/lib source/common source/game source/rnd source/game/ui/screens source/rnd/actors DATA := data INCLUDES := include GRAPHICS := gfx @@ -61,13 +61,13 @@ endif ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -mfpu=vfpv2 CFLAGS := -g -Wall -O2 -mword-relocations -D DEBUG \ - -ffunction-sections \ + -ffunction-sections -fomit-frame-pointer \ $(ARCH) CFLAGS += $(INCLUDE) -D__3DS__ $(VERFLAGS) CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 -Wno-invalid-offsetof \ - -Wno-array-bounds + -Wno-array-bounds ASFLAGS := -g $(ARCH) LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map) -T $(TOPDIR)/$(LINK_SCRIPT) @@ -193,11 +193,10 @@ ifneq ($(ROMFS),) export _3DSXFLAGS += --romfs=$(CURDIR)/$(ROMFS) endif -.PHONY: all clean +.PHONY: all clean $(BUILD) #--------------------------------------------------------------------------------- all: $(BUILD) - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile $(BUILD): @[ -d $@ ] || mkdir -p $@ @@ -240,7 +239,7 @@ else #--------------------------------------------------------------------------------- # main targets #--------------------------------------------------------------------------------- -$(OUTPUT).elf : $(OFILES) +$(OUTPUT).elf : $(OFILES) $(TOPDIR)/$(LINK_SCRIPT) #$(OUTPUT).3dsx : $(OUTPUT).elf $(_3DSXDEPS) #$(OFILES_SOURCES) : $(HFILES) diff --git a/code/include/game/actor.h b/code/include/game/actor.h index c5affc3c..ad059b67 100644 --- a/code/include/game/actor.h +++ b/code/include/game/actor.h @@ -64,6 +64,8 @@ namespace game::act { BossGyorg = 0x00CD, // Great Fairy NpcGreatFairy = 0x00D2, + // Boss Remains + DmHina = 0x00DC, // [4] Kafei NpcKafei = 0x00F4, // Koume (Boat Lady) @@ -72,6 +74,10 @@ namespace game::act { EnGinkoMan = 0x010F, // Deku Butler EnDno = 0x0117, + // Happy Mask Salesman (Cutscenes) + DmChar03 = 0x12B, + // Masks (Cutscenes) + DmChar05 = 0x012D, // Ice platform created using ice arrows. BgIcePlatform = 0x013E, // Npc For Curiosity Shop Owner @@ -80,6 +86,8 @@ namespace game::act { EnShn = 0x0158, // NPC Postman NpcEnPm = 0x0166, + // Fish Heart Piece + FishHeart = 0x016A, // Goht BossGoht = 0x016E, // Postbox @@ -116,6 +124,8 @@ namespace game::act { NpcEnBjt = 0x020C, // [4] Bombers NpcBombers = 0x020F, + // Moon Stone + ObjMoonStone = 0x0212, // Keaton EnKitan = 0x021B, // [6] Sheikah Hint Stone (MM3D) @@ -349,6 +359,14 @@ namespace game::act { }; static_assert(sizeof(DayTimerActor) == 0x20C); + typedef struct SA_TextureAnimation { + /* 0x00 */ char gap_00[0x14]; + /* 0x10 */ f32 animSpeed; + /* 0x18 */ s8 animMode; + // ... size unknown + } SA_TextureAnimation; + static_assert(offsetof(SA_TextureAnimation, animMode) == 0x18); + struct sa_unk_d4 { void* field_00; void* field_04; @@ -356,8 +374,10 @@ namespace game::act { int field_0c; float field_10; float field_14; - z3d_nn_math_MTX34* mtx; - u8 gap_1C[184]; + z3d_nn_math_MTX34 mtx; + u8 gap_48[0x50]; + SA_TextureAnimation* texAnim; + u8 gap_9C[0x38]; }; static_assert(sizeof(sa_unk_d4) == 0xD4); diff --git a/code/include/game/as.h b/code/include/game/as.h index 88c0ee45..0d765159 100644 --- a/code/include/game/as.h +++ b/code/include/game/as.h @@ -13,6 +13,7 @@ #include "common/types.h" #include "common/utils.h" +#include "game/actor.h" namespace game::as { @@ -52,7 +53,7 @@ namespace game::as { int field_28; int field_2C; int field_30; - void* field_34; + game::act::sa_unk_d4* field_34; int field_38; State state; u8 gap_64[24]; diff --git a/code/include/game/camera.h b/code/include/game/camera.h index 09eeeaf1..01253a7e 100644 --- a/code/include/game/camera.h +++ b/code/include/game/camera.h @@ -253,9 +253,7 @@ namespace game { u16 field_148; u16 field_14A; u16 field_14C; - __attribute__((packed)) __attribute__((aligned(1))) int field_14E; - u16 field_152; - u16 field_154; + z3dVec3s cam_dir; CameraState state; CameraMode mode; u16 field_15A; diff --git a/code/include/rnd/actors/dm_char03.h b/code/include/rnd/actors/dm_char03.h index 358a7321..f0e54080 100644 --- a/code/include/rnd/actors/dm_char03.h +++ b/code/include/rnd/actors/dm_char03.h @@ -21,9 +21,8 @@ namespace rnd { void* skelAnimeModel; }; static_assert(sizeof(Dm_Char03) == 0x29C); - extern "C" float rDmChar03Scale; void Dm_Char03_Init(game::act::Actor* actor, game::GlobalContext* gctx); - void Dm_Char03_Draw(game::act::Actor* actor, game::GlobalContext* gctx); + extern "C" s32 Dm_Char03_OverrideModelDraw(game::act::sa_unk_d4*, game::act::Actor*); void Dm_Char03_Destroy(game::act::Actor* actor, game::GlobalContext* gctx); } // namespace rnd diff --git a/code/include/rnd/actors/dm_char05.h b/code/include/rnd/actors/dm_char05.h index 64beb0e6..e8565bb8 100644 --- a/code/include/rnd/actors/dm_char05.h +++ b/code/include/rnd/actors/dm_char05.h @@ -22,10 +22,16 @@ namespace rnd { }; static_assert(sizeof(Dm_Char05) == 0x2B8); - void DMChar05_Init(game::act::Actor* actor, game::GlobalContext* gctx); - - void DMChar05_Draw(game::act::Actor* actor, game::GlobalContext* gctx); + enum DmChar05Param { + DMCHAR05_GORON_MASK = 0x0, + DMCHAR05_ZORA_MASK = 0x1, + DMCHAR05_GIBDO_MASK = 0x2, + DMCHAR05_MAJORA_MASK = 0x3, + DMCHAR05_COUPLE_MASK = 0x4, + DMCHAR05_BOMBERS_NOTEBOOK = 0xD, + }; - void DMChar05_Destroy(game::act::Actor* self, game::GlobalContext* gctx); + void Dm_Char05_Init(game::act::Actor* actor, game::GlobalContext* gctx); + void Dm_Char05_Destroy(game::act::Actor* self, game::GlobalContext* gctx); } // namespace rnd #endif \ No newline at end of file diff --git a/code/include/rnd/actors/dm_hina.h b/code/include/rnd/actors/dm_hina.h index e44917af..6d7fb2dc 100644 --- a/code/include/rnd/actors/dm_hina.h +++ b/code/include/rnd/actors/dm_hina.h @@ -1,5 +1,5 @@ -#ifndef _RND_ACTORS_EN_DOOR_1_H_ -#define _RND_ACTORS_EN_DOOR_1_H_ +#ifndef _RND_ACTORS_DM_HINA_H_ +#define _RND_ACTORS_DM_HINA_H_ #include "game/actor.h" #include "rnd/models.h" @@ -10,9 +10,16 @@ extern "C" { } #endif namespace rnd { + struct Dm_Hina : public game::act::Actor { + void* next_fn; + u8 gap_1fc[60]; + void* skel_anime_model; + void* multi_effect; + int gap_240; + }; void Dm_Hina_Init(game::act::Actor*, game::GlobalContext*); - void Dm_Hina_Draw(game::act::Actor*, game::GlobalContext*); - void Dm_Hina_Draw(game::act::Actor*, game::GlobalContext*); + extern "C" void Dm_Hina_Draw(game::act::Actor*, game::GlobalContext*); + // void Dm_Hina_Draw(game::act::Actor*, game::GlobalContext*); void Dm_Hina_Destroy(game::act::Actor*, game::GlobalContext*); } // namespace rnd #endif \ No newline at end of file diff --git a/code/include/rnd/actors/en_mag.h b/code/include/rnd/actors/en_mag.h new file mode 100644 index 00000000..0c88fba7 --- /dev/null +++ b/code/include/rnd/actors/en_mag.h @@ -0,0 +1,37 @@ +#ifndef _RND_ACTOR_EN_MAG_H_ +#define _RND_ACTOR_EN_MAG_H_ + +#include "game/actor.h" +#include "game/context.h" +#include "rnd/custom_models.h" +#include "rnd/models.h" +#include "rnd/objects.h" +#include "z3d/z3DVec.h" +namespace rnd { + struct En_Mag : public game::act::Actor { + u8 gap_1f8[36]; + game::act::sa_unk_d4* skelAnime; + game::act::sa_unk_d4* field_220; + game::act::sa_unk_d4* field_224; + game::act::sa_unk_d4* field_228; + game::act::sa_unk_d4* field_22c; + u8 gap_230[54]; + u8 field_266; + u8 gap_267[13]; + u32 field_274; + u32 field_278; + u32 field_27c; + u8 gap_280[4]; + u16 field_284; + u16 field_286; + u16 field_288; + u16 field_28a; + u32 field_28c; + u32 field_290; + }; + static_assert(sizeof(En_Mag) == 0x294); + + void En_Mag_rInit(game::act::Actor*, game::GlobalContext*); +} // namespace rnd + +#endif //_TITLE_SCREEN_H_ \ No newline at end of file diff --git a/code/include/rnd/actors/fish_heart.h b/code/include/rnd/actors/fish_heart.h new file mode 100644 index 00000000..5876f44d --- /dev/null +++ b/code/include/rnd/actors/fish_heart.h @@ -0,0 +1,28 @@ +#ifndef _RND_ACTORS_FISH_HEART_H_ +#define _RND_ACTORS_FISH_HEART_H_ + +#include "game/actor.h" +#include "rnd/models.h" +#if defined ENABLE_DEBUG || defined DEBUG_PRINT +#include "common/debug.h" +extern "C" { +#include <3ds/svc.h> +} +#endif +namespace rnd { + struct Fish_Heart : public game::act::Actor { + void* next_fn; + u8 gap_1fc[8]; + float scale; + u8 gap_208[88]; + game::act::sa_unk_d4* skelAnimeModel; + u8 field_264; + u8 gap_265[3]; + }; + static_assert(sizeof(Fish_Heart) == 0x268); + void Fish_Heart_Init(game::act::Actor* actor, game::GlobalContext* gctx); + extern "C" s32 Fish_Heart_OverrideModelDraw(game::act::sa_unk_d4*, game::act::Actor*); + void Fish_Heart_Destroy(game::act::Actor* actor, game::GlobalContext* gctx); + +} // namespace rnd +#endif \ No newline at end of file diff --git a/code/include/rnd/actors/obj_moon_stone.h b/code/include/rnd/actors/obj_moon_stone.h new file mode 100644 index 00000000..c6f7ebf9 --- /dev/null +++ b/code/include/rnd/actors/obj_moon_stone.h @@ -0,0 +1,27 @@ +#ifndef _RND_ACTORS_OBJ_MOONSTONE_H_ +#define _RND_ACTORS_OBJ_MOONSTONE_H_ + +#include "game/actor.h" +#include "rnd/models.h" +#if defined ENABLE_DEBUG || defined DEBUG_PRINT +#include "common/debug.h" +extern "C" { +#include <3ds/svc.h> +} +#endif +namespace rnd { + struct Obj_Moon_Stone : public game::act::Actor { + u8 gap_1f8[88]; + void* next_fn; + u32 field_254; + game::act::sa_unk_d4* skelAnimeModelOne; + game::act::sa_unk_d4* skelAnimeModelTwo; + game::act::sa_unk_d4* skelAnimeModelThree; + }; + static_assert(sizeof(Obj_Moon_Stone) == 0x264); + void Obj_Moon_Stone_Init(game::act::Actor* actor, game::GlobalContext* gctx); + extern "C" s32 Obj_Moon_Stone_OverrideModelDraw(game::act::sa_unk_d4*, game::act::Actor*); + void Obj_Moon_Stone_Destroy(game::act::Actor* actor, game::GlobalContext* gctx); + +} // namespace rnd +#endif \ No newline at end of file diff --git a/code/include/rnd/gfx.h b/code/include/rnd/gfx.h index 45e8b3bd..70c04cdc 100644 --- a/code/include/rnd/gfx.h +++ b/code/include/rnd/gfx.h @@ -11,7 +11,6 @@ #include "rnd/savefile.h" #include "rnd/settings.h" #include "rnd/spoiler_data.h" -#include "rnd/title_screen.h" extern "C" { #include <3ds/svc.h> } diff --git a/code/include/rnd/models.h b/code/include/rnd/models.h index df2f5888..3259ec37 100644 --- a/code/include/rnd/models.h +++ b/code/include/rnd/models.h @@ -15,24 +15,26 @@ namespace rnd { s32 objectBankIdx; s32 objectBankIdx2; u8 loaded; - void* saModel; - void* saModel2; + game::act::sa_unk_d4* saModel; + game::act::sa_unk_d4* saModel2; + z3d_nn_math_MTX34* hardcodedMtx; // used for actors that draw their models in unusual ways f32 scale; + z3dVec3f posOffset; } Model; - void* SkeletonAnimationModel_Spawn(game::act::Actor*, game::GlobalContext*, s16, s32); - void SkeletonAnimationModel_CopyMtx(void*, void*); + game::act::sa_unk_d4* SkeletonAnimationModel_Spawn(game::act::Actor*, game::GlobalContext*, s16, s32); + void SkeletonAnimationModel_CopyMtx(z3d_nn_math_MTX34* dst, z3d_nn_math_MTX34* src); + void TexAnim_Spawn(game::act::SA_TextureAnimation*, void*); void SkeletonAnimationModel_SetMeshByDrawItemID(void* model, s32 drawItemId); void SkeletonAnimationModel_Draw(void*, int); void Model_SetScale(game::act::Actor*, float); - void Model_SetMtxAndModel(void*, void*); void Model_InvertMatrix(void* mtx); void Model_InvertMatrixByScale(void* mtx, float scale); void Model_UpdateMatrixPosition(void* mtx, void* mtxTwo, void* scaleMtx); void Model_GetObjectBankIndex(Model* model, game::act::Actor* actor, game::GlobalContext* globalCtx); - void Model_SetAnim(void* model, s16 objectId, u32 objectAnimIndex); + void Model_SetAnim(game::act::sa_unk_d4* model, s16 objectId, u32 objectAnimIndex); void Model_Init(Model* model, game::GlobalContext* globalCtx); void Model_Destroy(Model* model); @@ -45,7 +47,7 @@ namespace rnd { void Model_SpawnByActor(game::act::Actor* actor, game::GlobalContext* globalCtx, u16 baseItemId); void Model_DestroyByActor(game::act::Actor* actor); void Model_DestroyAll(void); - s32 Model_DrawByActor(game::act::Actor* actor); + s32 Model_DrawByActor(game::act::Actor* actor, z3d_nn_math_MTX34* hardcodedMtx = NULL); Model* Model_GetOverrideSaModel(game::act::Actor* actor); void Actor_Init(); } // namespace rnd diff --git a/code/include/rnd/objects.h b/code/include/rnd/objects.h index ac371568..b48adc93 100644 --- a/code/include/rnd/objects.h +++ b/code/include/rnd/objects.h @@ -11,19 +11,17 @@ namespace rnd { // Extended Object to deal with spawning multiple actors without running out of standard game space. typedef game::ActorResource::ObjectContext ExtendedObjectContext; extern "C" ExtendedObjectContext rExtendedObjectCtx; - extern "C" s32 storedObjId; + extern "C" s32 rStoredObjId; extern "C" s32 yPos; extern "C" s32 xPos; extern "C" s32 zPos; - void TexAnim_Spawn(void*, void*); - s32 Object_SpawnPersistent(void* objectCtx, s16 objectId); s32 Object_GetSlot(void* objectCtx, s16 objectId); void Object_Clear(void* objectCtx); bool Object_IsLoaded(game::ActorResource::ObjectContext* objectCtx, s16 bankIdx); void Object_UpdateBank(game::ActorResource::ObjectContext* objectCtx); - void* GAR_GetCMBByIndex(game::ObjectBank::ObjectBankArchive* objBankArchive, u32 objectAnimIdx); + void* GAR_GetCMABByIndex(game::ObjectBank::ObjectBankArchive* objBankArchive, u32 objectAnimIdx); s32 ExtendedObject_Spawn(game::ActorResource::ObjectContext* objectCtx, s16 objectId); extern "C" void ExtendedObject_Clear(game::ActorResource::ObjectContext* objectCtx); diff --git a/code/include/rnd/title_screen.h b/code/include/rnd/title_screen.h deleted file mode 100644 index 31d981f5..00000000 --- a/code/include/rnd/title_screen.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _RND_TITLE_SCREEN_H_ -#define _RND_TITLE_SCREEN_H_ - -#include "game/actor.h" -#include "game/context.h" -#include "z3d/z3DVec.h" - -// TODO: Make new struct for EnMag? -struct SkeletonAnimationModel { - void spawn(void* cmbPtr); -}; - -struct EnMag { - game::act::Actor actor; - // SkeletonAnimationModel* model; - // SkeletonAnimationModel* fireModel; - // SkeletonAnimationModel* copyrightModel; - // char unk_1B0[0x30]; -}; // size 0x1E0; - -void EnMag_rInit(game::act::Actor* thisx, game::GlobalContext* globalCtx); - -#endif //_TITLE_SCREEN_H_ \ No newline at end of file diff --git a/code/mm.ld b/code/mm.ld index 1c89c9ce..0b43e9b2 100644 --- a/code/mm.ld +++ b/code/mm.ld @@ -229,6 +229,10 @@ SECTIONS{ *(.patch_CheckMagicForZoraFastSwim) } + .patch_storeObjectIdForExtendedObject 0x203C44 : { + *(.patch_storeObjectIdForExtendedObject) + } + .patch_ModelSpawnGetObjectStatus 0x203CF8 : { *(.patch_ModelSpawnGetObjectStatus) } @@ -269,9 +273,9 @@ SECTIONS{ *(.patch_SecondZoraSwimCheck) } - .patch_GetExtendedObjectStatus 0x222330 : { + /* .patch_GetExtendedObjectStatus 0x222330 : { *(.patch_GetExtendedObjectStatus) - } + } */ .patch_RemoveRemainsStateCheck 0x22B7BC : { *(.patch_RemoveRemainsStateCheck) @@ -443,10 +447,18 @@ SECTIONS{ *(.patch_OverrideItem00Init) } + .patch_DmChar03ModelDraw 0x3B9254 : { + *(.patch_DmChar03ModelDraw) + } + .patch_OverrideRemainSpawn 0x389E7C : { *(.patch_OverrideRemainSpawn) } + .patch_RemainsModelDraw 0x3C7D7C : { + *(.patch_RemainsModelDraw) + } + .patch_TingleCheckClocktownMapTwo 0x3F5F00 : { *(.patch_TingleCheckClocktownMapTwo) } @@ -515,6 +527,26 @@ SECTIONS{ *(.patch_HMSGiveItem) } + .patch_GoronMaskModelDraw 0x41D380 : { + *(.patch_GoronMaskModelDraw) + } + + .patch_ZoraMaskModelDraw 0x41D4E8: { + *(.patch_ZoraMaskModelDraw) + } + + .patch_GibdoMaskModelDraw 0x41D654: { + *(.patch_GibdoMaskModelDraw) + } + + .patch_CoupleMaskModelDraw 0x41D7F4: { + *(.patch_CoupleMaskModelDraw) + } + + .patch_BombersNotebookModelDraw 0x41D994: { + *(.patch_BombersNotebookModelDraw) + } + .patch_GoronMaskGiveItem 0x41DAB0 : { *(.patch_GoronMaskGiveItem) } @@ -583,10 +615,18 @@ SECTIONS{ *(.patch_RemoveJimWhenExitingHideout) } - .patch_DmChar05GetObjectStatus 0x50F3DC : { - *(.patch_DmChar05GetObjectStatus) + .patch_ObjMoonStoneDraw 0x4CEE88 : { + *(.patch_ObjMoonStoneDraw) + } + + .patch_FishHeartDraw 0x50C1E4 : { + *(.patch_FishHeartDraw) } + /* .patch_DmChar05GetObjectStatus 0x50F3DC : { + *(.patch_DmChar05GetObjectStatus) + } */ + /* XXX: May need this in the future, but will have to steal object ID from table in function call. */ /* .patch_DmChar05GetObjectStatusTwo 0x504CA8 : { *(.patch_DmChar05GetObjectStatusTwo) diff --git a/code/source/asm/model_hooks.s b/code/source/asm/model_hooks.s index 198ff296..f280546b 100644 --- a/code/source/asm/model_hooks.s +++ b/code/source/asm/model_hooks.s @@ -1,6 +1,18 @@ .arm .text +.global rStoredObjId +.rStoredObjId_addr: + .word rStoredObjId + +.global hook_storeObjectIdForExtendedObject +hook_storeObjectIdForExtendedObject: + push {r0-r12, lr} + ldr r0, .rStoredObjId_addr + str r2, [r0] @ store object ID in rStoredObjId + pop {r0-r12, lr} + cpy r4, r1 + bx lr .global hook_ModelSpawnGetObjectStatus hook_ModelSpawnGetObjectStatus: @@ -47,4 +59,62 @@ hook_OverrideItem00Draw: cmp r0,#0x0 pop {r0-r12, lr} bxeq lr - pop {r4,r5,pc} \ No newline at end of file + pop {r4,r5,pc} + +.global hook_RemainsModelDraw +hook_RemainsModelDraw: + mov r1,#0x0 + push {r0-r12, lr} + @ r0 = saModel + cpy r1,r4 @ actor + bl Remains_OverrideModelDraw + cmp r0,#0x0 + pop {r0-r12, lr} + addne lr,lr,#0x4 @ skip drawing vanilla model + bx lr + +.global hook_ObjMoonStoneDraw +hook_ObjMoonStoneDraw: + mov r1,#0x0 + push {r0-r12, lr} + cpy r1,r4 @ actor + bl Obj_Moon_Stone_OverrideModelDraw + cmp r0,#0x0 + pop {r0-r12, lr} + addne lr,lr,#0x4 @ skip drawing vanilla model + @bne 0x4CEEDC + bx lr + +.global hook_FishHeartDraw +hook_FishHeartDraw: + push {r0-r12, lr} + cpy r1,r4 @ actor + bl Fish_Heart_OverrideModelDraw + cmp r0,#0x0 + pop {r0-r12, lr} + bxne lr + b 0x20AAA8 + +.global hook_DmChar03ModelDraw +hook_DmChar03ModelDraw: + mov r1,#0x0 + push {r0-r12, lr} + @ r0 = saModel + cpy r1,r4 @ actor + bl Dm_Char03_OverrideModelDraw + cmp r0,#0x0 + pop {r0-r12, lr} + addne lr,lr,#0x4 @ skip drawing vanilla model + bx lr + +.global hook_DmChar05ModelDraw +hook_DmChar05ModelDraw: + cpy r0,r5 + push {r0-r12, lr} + cpy r0,r4 @ actor + cpy r1,r2 @ model matrix + bl Dm_Char05_OverrideModelDraw + cmp r0,#0x0 + pop {r0-r12, lr} + addne lr,lr,#0x4 @ skip drawing vanilla model + bx lr diff --git a/code/source/asm/model_patches.s b/code/source/asm/model_patches.s index 19a3c178..39e05534 100644 --- a/code/source/asm/model_patches.s +++ b/code/source/asm/model_patches.s @@ -10,6 +10,11 @@ patch_ExtendedObjectClear: patch_ModelSpawnGetObjectStatus: bl hook_ModelSpawnGetObjectStatus +.section .patch_storeObjectIdForExtendedObject +.global patch_storeObjectIdForExtendedObject +patch_storeObjectIdForExtendedObject: + bl hook_storeObjectIdForExtendedObject + .section .patch_GetExtendedObjectStatus .global patch_GetExtendedObjectStatus patch_GetExtendedObjectStatus: @@ -38,4 +43,49 @@ patch_OverrideItem00Draw: .section .patch_DmChar05GetObjectStatus .global patch_DmChar05GetObjectStatus patch_DmChar05GetObjectStatus: - bl hook_ModelSpawnGetObjectStatus \ No newline at end of file + bl hook_ModelSpawnGetObjectStatus + +.section .patch_RemainsModelDraw +.global RemainsModelDraw_patch +RemainsModelDraw_patch: + bl hook_RemainsModelDraw + +.section .patch_ObjMoonStoneDraw +.global patch_ObjMoonStoneDraw +patch_ObjMoonStoneDraw: + bl hook_ObjMoonStoneDraw + +.section .patch_FishHeartDraw +.global patch_FishHeartDraw +patch_FishHeartDraw: + b hook_FishHeartDraw + +.section .patch_DmChar03ModelDraw +.global DmChar03ModelDraw +DmChar03ModelDraw: + bl hook_DmChar03ModelDraw + +.section .patch_GoronMaskModelDraw +.global GoronMaskModelDraw_patch +GoronMaskModelDraw_patch: + bl hook_DmChar05ModelDraw + +.section .patch_ZoraMaskModelDraw +.global ZoraMaskModelDraw_patch +ZoraMaskModelDraw_patch: + bl hook_DmChar05ModelDraw + +.section .patch_GibdoMaskModelDraw +.global GibdoMaskModelDraw_patch +GibdoMaskModelDraw_patch: + bl hook_DmChar05ModelDraw + +.section .patch_CoupleMaskModelDraw +.global CoupleMaskModelDraw_patch +CoupleMaskModelDraw_patch: + bl hook_DmChar05ModelDraw + +.section .patch_BombersNotebookModelDraw +.global BombersNotebookModelDraw_patch +BombersNotebookModelDraw_patch: + bl hook_DmChar05ModelDraw diff --git a/code/source/rnd/actors/dm_char03.cpp b/code/source/rnd/actors/dm_char03.cpp index 3157a004..77b28830 100644 --- a/code/source/rnd/actors/dm_char03.cpp +++ b/code/source/rnd/actors/dm_char03.cpp @@ -5,23 +5,10 @@ namespace rnd { void Dm_Char03_Init(game::act::Actor* actor, game::GlobalContext* gctx) { util::GetPointer(0x3C6A38)(actor, gctx); Model_SpawnByActor(actor, GetContext().gctx, 0x78); - Model* model = Model_GetOverrideSaModel(actor); - - // static_cast(actor)->skelAnimeModel = model->saModel; - if (model != NULL) { - static_cast(actor)->actor_util->field_34 = model->saModel; - if (model->objectId == 0x01) { - auto* scale = util::GetPointer(0x3B9298); - util::Write(scale, 0x00, 0.005f); - } - } } - void Dm_Char03_Draw(game::act::Actor* actor, game::GlobalContext* gctx) { - Model* model = Model_GetOverrideSaModel(actor); - static_cast(actor)->skelAnimeModel = model->saModel; - static_cast(actor)->actor_util->field_34 = model->saModel; - util::GetPointer(0x41CE70)(actor, gctx); + extern "C" s32 Dm_Char03_OverrideModelDraw(game::act::sa_unk_d4* saModel, game::act::Actor* actor) { + return Model_DrawByActor(actor, &saModel->mtx); } void Dm_Char03_Destroy(game::act::Actor* actor, game::GlobalContext* gctx) { diff --git a/code/source/rnd/actors/dm_char05.cpp b/code/source/rnd/actors/dm_char05.cpp index cd79e6c8..9cf54a99 100644 --- a/code/source/rnd/actors/dm_char05.cpp +++ b/code/source/rnd/actors/dm_char05.cpp @@ -1,52 +1,27 @@ #include "rnd/actors/dm_char05.h" namespace rnd { - void DmChar05_SetScale(game::act::Actor* actor) { - Model* model = Model_GetOverrideSaModel(actor); - - // static_cast(actor)->skelAnimeModel = model->saModel; - if (model != NULL) { - static_cast(actor)->actor_util.field_34 = model->saModel; - if (model->objectId == 0x01) { - auto* scale = util::GetPointer(0x41D5B0); - util::Write(scale, 0x00, 0.005f); - } - } - } - - void DMChar05_Init(game::act::Actor* actor, game::GlobalContext* gctx) { + void Dm_Char05_Init(game::act::Actor* actor, game::GlobalContext* gctx) { util::GetPointer(0x3C6CD8)(actor, gctx); - if (actor->params == 0x00) // Goron + if (actor->params == DMCHAR05_GORON_MASK) Model_SpawnByActor(actor, GetContext().gctx, 0x79); - else if (actor->params == 0x01) // Zora + else if (actor->params == DMCHAR05_ZORA_MASK) Model_SpawnByActor(actor, GetContext().gctx, 0x7A); - else if (actor->params == 0x02) // Gibdo + else if (actor->params == DMCHAR05_GIBDO_MASK) Model_SpawnByActor(actor, GetContext().gctx, 0x87); - else if (actor->params == 0x04) // Couple's + else if (actor->params == DMCHAR05_COUPLE_MASK) Model_SpawnByActor(actor, GetContext().gctx, 0x85); - else if (actor->params == 0x0D) // Bomber's Notebook + else if (actor->params == DMCHAR05_BOMBERS_NOTEBOOK) Model_SpawnByActor(actor, GetContext().gctx, 0x50); - DmChar05_SetScale(actor); } - void DMChar05_Draw(game::act::Actor* actor, game::GlobalContext* gctx) { - Model* model = Model_GetOverrideSaModel(actor); - if (model != NULL) { - static_cast(actor)->skelAnimeModel = model->saModel; - static_cast(actor)->actor_util.field_34 = model->saModel; - } - util::GetPointer(0x41D1C8)(actor, gctx); - } - - void DMChar05_Destroy(game::act::Actor* self, game::GlobalContext* gctx) { - if (self->params != 0x03) - Model_DestroyByActor(self); + void Dm_Char05_Destroy(game::act::Actor* self, game::GlobalContext* gctx) { + Model_DestroyByActor(self); util::GetPointer(0x3C6F90)(self); } - void DmChar05_Goron_Init(game::act::Actor* actor, game::GlobalContext* gctx) { - Model_SpawnByActor(actor, rnd::GetContext().gctx, 0x79); - DmChar05_SetScale(actor); + // Used for all models drawn by this actor + extern "C" s32 Dm_Char05_OverrideModelDraw(game::act::Actor* actor, z3d_nn_math_MTX34* modelMtx) { + return Model_DrawByActor(actor, modelMtx); } - } // namespace rnd \ No newline at end of file diff --git a/code/source/rnd/actors/dm_hina.cpp b/code/source/rnd/actors/dm_hina.cpp index 9a09bc85..78b136c5 100644 --- a/code/source/rnd/actors/dm_hina.cpp +++ b/code/source/rnd/actors/dm_hina.cpp @@ -4,13 +4,7 @@ namespace rnd { void Dm_Hina_Init(game::act::Actor* actor, game::GlobalContext* gctx) { util::GetPointer(0x34F7A4)(actor, gctx); // TODO - Use scene or params to determined base item ID. - Model_SpawnByActor(actor, rnd::GetContext().gctx, 0x55); - } - - void Dm_Hina_Draw(game::act::Actor* actor, game::GlobalContext* gctx) { - if (!Model_DrawByActor(actor)) { - util::GetPointer(0x3C7BA8)(actor, gctx); - } + Model_SpawnByActor(actor, rnd::GetContext().gctx, 0x5C + (actor->params * 2)); } void Dm_Hina_Destroy(game::act::Actor* self, game::GlobalContext* gctx) { @@ -18,4 +12,8 @@ namespace rnd { util::GetPointer(0x34F864)(self); } + extern "C" s32 Remains_OverrideModelDraw(game::act::sa_unk_d4* saModel, game::act::Actor* actor) { + return Model_DrawByActor(actor, &saModel->mtx); + } + } // namespace rnd \ No newline at end of file diff --git a/code/source/rnd/actors/en_mag.cpp b/code/source/rnd/actors/en_mag.cpp new file mode 100644 index 00000000..815a4d1f --- /dev/null +++ b/code/source/rnd/actors/en_mag.cpp @@ -0,0 +1,36 @@ +#include "rnd/actors/en_mag.h" + +namespace rnd { + + void En_Mag_rInit(game::act::Actor* self, game::GlobalContext* gctx) { + En_Mag* enMag = static_cast(self); + + u8 objBankIdx = enMag->object_id; + void* titleScreenZar = gctx->object_context.status[objBankIdx].archive.archive.raw; + void* cmabMan; + + s16 exObjectBankIdx = Object_GetSlot(&rExtendedObjectCtx, 182); + if (exObjectBankIdx < 0) { + exObjectBankIdx = Object_SpawnPersistent(&rExtendedObjectCtx, 182); + } + + CustomModel_EditTitleScreenLogo(titleScreenZar); + + util::GetPointer(0x32433C)(self, gctx); + + cmabMan = GAR_GetCMABByIndex(&rExtendedObjectCtx.status[exObjectBankIdx].archive, 2); + TexAnim_Spawn(enMag->skelAnime->texAnim, cmabMan); + enMag->skelAnime->texAnim->animSpeed = 0.0f; + enMag->skelAnime->texAnim->animMode = 0; + + // cmabMan = GAR_GetCMABByIndex(&rExtendedObjectCtx.status[exObjectBankIdx].archive, 1); + // TexAnim_Spawn(enMag->field_220->texAnim, cmabMan); + // enMag->field_220->texAnim->animSpeed = 0.0f; + // enMag->field_220->texAnim->animMode = 0; + + // cmabMan = ZAR_GetCMABByIndex(&rExtendedObjectCtx.status[exObjectBankIdx].zarInfo, + // TEXANIM_COPY_NINTENDO); TexAnim_Spawn(enmag->copyrightModel->unk_0C, cmabMan); + // enmag->copyrightModel->unk_0C->animSpeed = 0.0f; + // enmag->copyrightModel->unk_0C->animMode = 0; + } +} // namespace rnd diff --git a/code/source/rnd/actors/fish_heart.cpp b/code/source/rnd/actors/fish_heart.cpp new file mode 100644 index 00000000..873b0cc9 --- /dev/null +++ b/code/source/rnd/actors/fish_heart.cpp @@ -0,0 +1,18 @@ +#include "rnd/actors/fish_heart.h" + +namespace rnd { + void Fish_Heart_Init(game::act::Actor* actor, game::GlobalContext* gctx) { + util::GetPointer(0x3F7808)(actor, gctx); + Model_SpawnByActor(actor, gctx, 0x0C); + } + + extern "C" s32 Fish_Heart_OverrideModelDraw(game::act::sa_unk_d4* saModel, game::act::Actor* actor) { + return Model_DrawByActor(actor, &saModel->mtx); + } + + void Fish_Heart_Destroy(game::act::Actor* self, game::GlobalContext*) { + Model_DestroyByActor(self); + util::GetPointer(0x3F7AB4)(self); + } + +} // namespace rnd \ No newline at end of file diff --git a/code/source/rnd/actors/obj_moon_stone.cpp b/code/source/rnd/actors/obj_moon_stone.cpp new file mode 100644 index 00000000..cd24f46d --- /dev/null +++ b/code/source/rnd/actors/obj_moon_stone.cpp @@ -0,0 +1,18 @@ +#include "rnd/actors/obj_moon_stone.h" + +namespace rnd { + void Obj_Moon_Stone_Init(game::act::Actor* actor, game::GlobalContext* gctx) { + util::GetPointer(0x4A95E4)(actor, gctx); + Model_SpawnByActor(actor, gctx, 0x96); + } + + extern "C" s32 Obj_Moon_Stone_OverrideModelDraw(game::act::sa_unk_d4* saModel, game::act::Actor* actor) { + return Model_DrawByActor(actor, &saModel->mtx); + } + + void Obj_Moon_Stone_Destroy(game::act::Actor* self, game::GlobalContext*) { + Model_DestroyByActor(self); + util::GetPointer(0x4A9820)(self); + } + +} // namespace rnd \ No newline at end of file diff --git a/code/source/rnd/item_override.cpp b/code/source/rnd/item_override.cpp index a25077c7..7fcc1305 100644 --- a/code/source/rnd/item_override.cpp +++ b/code/source/rnd/item_override.cpp @@ -52,8 +52,8 @@ namespace rnd { rItemOverrides[0].value.looksLikeItemId = 0x56; rItemOverrides[1].key.scene = 0x6F; rItemOverrides[1].key.type = ItemOverride_Type::OVR_COLLECTABLE; - rItemOverrides[1].value.getItemId = 0x44; - rItemOverrides[1].value.looksLikeItemId = 0x44; + rItemOverrides[1].value.getItemId = 0x81; + rItemOverrides[1].value.looksLikeItemId = 0x81; rItemOverrides[2].key.scene = 0x12; rItemOverrides[2].key.type = ItemOverride_Type::OVR_COLLECTABLE; rItemOverrides[2].value.getItemId = 0x37; diff --git a/code/source/rnd/item_table.cpp b/code/source/rnd/item_table.cpp index 11cd6e90..c4a54c68 100644 --- a/code/source/rnd/item_table.cpp +++ b/code/source/rnd/item_table.cpp @@ -322,8 +322,8 @@ namespace rnd { 0x00, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, DrawGraphicItemID::DI_DUNGEON_MAP_MAYBE, (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1, 1.00f), // Map - [0x3F] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::DECORATED_BIG, (u8)game::ItemId::Compass, 0x003F, 0x0139, - 0x00, (s8)0xFF, (s8)0x01, (s8)0xFF, (s8)0xFF, DrawGraphicItemID::DI_COMPASS, + [0x3F] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::DECORATED_BIG, (u8)game::ItemId::Compass, 0x003F, 0x0091, + 0x00, (s8)0xFF, (s8)0x00, (s8)0xFF, (s8)0xFF, DrawGraphicItemID::DI_COMPASS, (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1, 1.00f), // Compass [0x40] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::KokiriSword, 0x009C, @@ -346,7 +346,7 @@ namespace rnd { 1.00f), // Pictograph Box [0x44] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_SMALL, (u8)game::ItemId::GoldSkulltula, 0x0052, - 0x0020, 0x02, (s8)0xFF, (s8)0x03, (s8)0xFF, (s8)0xFF, DrawGraphicItemID::DI_GOLD_SKULLTULA, + 0x0020, 0x02, (s8)0xFF, (s8)0x03, (s8)0x00, (s8)0xFF, DrawGraphicItemID::DI_GOLD_SKULLTULA, (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_GiveSkulltula, (s16)0, (s16)-1, 1.00f), // Gold Skulltula @@ -507,13 +507,13 @@ namespace rnd { (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1, 1.00f), // Bottle With Blue fire - not used - [0x65] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::Poe, 0x0065, 0x0139, 0x00, - (s8)0xFF, 0x02, (s8)0xFF, (s8)0xFF, DrawGraphicItemID::DI_BOTTLE_BIG_POE_PURPLE, + [0x65] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::Poe, 0x0065, 0x0139, 0x02, + (s8)0xFF, 0x00, (s8)0x00, (s8)0xFF, DrawGraphicItemID::DI_BOTTLE_POE, (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1, 1.00f), // Bottle With Poe - not used? [0x66] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::BigPoe, 0x0066, 0x0139, - 0x01, (s8)0xFF, 0x04, (s8)0xFF, (s8)0xFF, DrawGraphicItemID::DI_BOTTLE_BIG_POE, + 0x01, (s8)0xFF, 0x04, (s8)0x02, (s8)0xFF, DrawGraphicItemID::DI_BOTTLE_BIG_POE, (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1, 1.00f), // Bottle With Big Poe @@ -533,7 +533,7 @@ namespace rnd { (rnd::upgradeFunc)ItemUpgrade_None, ItemEffect_None, (s16)-1, (s16)-1, 1.00f), // Bottle With Zora Egg - [0x6A] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::GoldDust, 0x006A, 0x01E8, + [0x6A] = ITEM_ROW((u32)GetItemID::GI_NUTS_30, ChestType::WOODEN_BIG, (u8)game::ItemId::GoldDust, 0x006A, 0x01E9, 0x00, (s8)0xFF, (s8)0xFF, (s8)0xFF, (s8)0xFF, DrawGraphicItemID::DI_BOTTLE_GOLD_DUST, (rnd::upgradeFunc)ItemUpgrade_RefillBottle, ItemEffect_None, (s16)-1, (s16)-1, 1.00f), // Bottle With Gold Dust diff --git a/code/source/rnd/models.cpp b/code/source/rnd/models.cpp index 9173275e..1ac6beea 100644 --- a/code/source/rnd/models.cpp +++ b/code/source/rnd/models.cpp @@ -2,26 +2,36 @@ #include "rnd/actors/dm_char03.h" #include "rnd/actors/dm_char05.h" #include "rnd/actors/dm_hina.h" +#include "rnd/actors/en_mag.h" #include "rnd/actors/en_si.h" +#include "rnd/actors/fish_heart.h" #include "rnd/actors/item00.h" #include "rnd/actors/item_b_heart.h" +#include "rnd/actors/obj_moon_stone.h" #define LOADEDMODELS_MAX 16 namespace rnd { Model ModelContext[LOADEDMODELS_MAX] = {0}; - void* SkeletonAnimationModel_Spawn(game::act::Actor* actor, game::GlobalContext* gctx, s16 objectId, - s32 objectModelIndex) { - return util::GetPointer(0x203C40)(actor, gctx, objectId, objectModelIndex); + game::act::sa_unk_d4* SkeletonAnimationModel_Spawn(game::act::Actor* actor, game::GlobalContext* gctx, s16 objectId, + s32 objectModelIndex) { + return util::GetPointer(0x203C40)(actor, gctx, objectId, objectModelIndex); } - void SkeletonAnimationModel_CopyMtx(void* fromMtx, void* toMtx) { - util::GetPointer(0x1FEAB0)(fromMtx, toMtx); + void Actor_SetModelMatrix(float x, float y, float z, z3d_nn_math_MTX34* mtx, game::act::ActorShape* shape) { + util::GetPointer(0x1F0948)( + x, y, z, mtx, shape); } - void TexAnim_Spawn(void* skelModel, int objectId) { - util::GetPointer(0x12A3DC)(skelModel, objectId); + void SkeletonAnimationModel_CopyMtx(z3d_nn_math_MTX34* dst, z3d_nn_math_MTX34* src) { + util::GetPointer(0x1FEAB0)(dst, src); + } + + void TexAnim_Spawn(game::act::SA_TextureAnimation* texAnim, void* cmab) { + // This pointer was extracted at runtime from the Skulltula Token init function (En_Si::init), + // but it comes from a virtual method, so it might not work in all cases. + util::GetPointer(0x229DA4)(texAnim, cmab); } void SkeletonAnimationModel_Destroy(void* skelModel) { @@ -44,10 +54,6 @@ namespace rnd { util::GetPointer(0x21E30C)(actor, scale); } - void Model_SetMtxAndModel(void* model, void* mtx) { - util::GetPointer(0x1FEAA8)(model, mtx); - } - void Model_InvertMatrix(void* mtx) { // Inverse model if model is upside down. util::GetPointer(0x22B038)(mtx, 3.14159, 1); @@ -62,8 +68,8 @@ namespace rnd { util::GetPointer(0x20BDB4)(mtx, mtxTwo, vec3); } - void Model_MultiplyMatrix(void* mtx, void* mtxTwo, void* scaleMtx) { - util::GetPointer(0x21B850)(mtx, mtxTwo, scaleMtx); + void Model_MultiplyMatrix(z3d_nn_math_MTX34* dst, z3d_nn_math_MTX34* lhs, z3d_nn_math_MTX44* rhs) { + util::GetPointer(0x21B850)(dst, lhs, rhs); } void Model_GetObjectBankIndex(Model* model, game::act::Actor* actor, game::GlobalContext* globalCtx) { @@ -71,77 +77,94 @@ namespace rnd { if (objectBankIdx < 0) { objectBankIdx = ExtendedObject_Spawn(&globalCtx->object_context, model->itemRow->objectId); } - storedObjId = model->itemRow->objectId; + // rStoredObjId = model->itemRow->objectId; model->objectBankIdx = objectBankIdx; } - void Model_SetAnim(void* model, s16 objectId) { - TexAnim_Spawn(model, objectId); + void Model_SetAnim(game::act::sa_unk_d4* model, s16 objectId, u32 objectAnimIdx) { + void* cmabMan = ExtendedObject_GetCMABByIndex(objectId, objectAnimIdx); + TexAnim_Spawn(model->texAnim, cmabMan); + model->texAnim->animSpeed = 1.0f; + model->texAnim->animMode = 1; + } + + void Matrix_UpdatePosition(void* dst, void* src, void* vec) { + util::GetPointer(0x19A360)(dst, src, vec); } void Model_SetMatrix(Model* model) { - float tmpMtx[3][4] = {0}; - float scaleMtx[4][4] = {0}; -#if defined ENABLE_DEBUG || defined DEBUG_PRINT - z3dVec3f tmpPos = {0.0f, 0.0f, 0.0f}; -#endif - - SkeletonAnimationModel_CopyMtx(&tmpMtx, &model->actor->mtx); - // Base case - if we're a free-standing heart piece then set scale and use built-in scaling call. - if (model->baseItemId == 0x00 && model->itemRow->objectId == 0x01) { - if (model->itemRow->objectModelIdx == 0x05) - model->scale = 0.010f; - else - model->scale = 0.015f; - Model_SetScale(model->actor, model->scale); + // Init scale matrix + z3d_nn_math_MTX44 scaleMtx = {0}; + f32 scale = model->scale; + switch (model->actor->id) { // Change model scale when overriding special actors + case game::act::Id::DmChar03: + scale *= 2; + break; + case game::act::Id::DmHina: + case game::act::Id::ObjMoonStone: + case game::act::Id::DmChar05: + scale *= 3; + break; + case game::act::Id::FishHeart: + scale *= 25; + break; + default: + break; + } + scaleMtx.data[0][0] = scale; + scaleMtx.data[1][1] = scale; + scaleMtx.data[2][2] = scale; + scaleMtx.data[3][3] = 1.0f; + + // Get model coordinates + z3dVec3f actorPos = model->actor->pos.pos; + f32 modelPosY = actorPos.y + (model->actor->model_scale.y * model->actor->actor_shape.y_offset); + + if (model->hardcodedMtx != NULL) { + // Use the hardcoded matrix if present + SkeletonAnimationModel_CopyMtx(&model->saModel->mtx, model->hardcodedMtx); } else { - if (model->baseItemId == 0x00) { - if (model->itemRow->objectId == 0x0157) - model->scale = 1.00f; - else - model->scale = 10.00f; - } - scaleMtx[0][0] = model->scale; - scaleMtx[1][1] = model->scale; - scaleMtx[2][2] = model->scale; - scaleMtx[3][3] = 1.0f; - Model_MultiplyMatrix(&tmpMtx, &tmpMtx, &scaleMtx); + // Otherwise, compute model matrix from actor shape and given position. + Actor_SetModelMatrix(actorPos.x, modelPosY, actorPos.z, &model->saModel->mtx, &model->actor->actor_shape); } -#if defined ENABLE_DEBUG || defined DEBUG_PRINT - tmpPos.y = yPos; - tmpPos.x = xPos; - tmpPos.z = zPos; - - Model_UpdateMatrixPosition(&tmpMtx, &tmpMtx, &tmpPos); -#endif - if (model->saModel != NULL) - Model_SetMtxAndModel(model->saModel, &tmpMtx); + // Apply scale + Model_MultiplyMatrix(&model->saModel->mtx, &model->saModel->mtx, &scaleMtx); + // Repeat for second model if present if (model->saModel2 != NULL) { - float tmpY = model->actor->actor_shape.rot.y; - if (model->objectId != 0x0020) { - model->actor->actor_shape.rot.y = GetContext().gctx->main_camera.field_11C.y; + if (model->hardcodedMtx != NULL) { + SkeletonAnimationModel_CopyMtx(&model->saModel2->mtx, model->hardcodedMtx); + // TODO: how to force facing the camera if the matrix is hardcoded? + } else { + f32 tempRotY = model->actor->actor_shape.rot.y; + // The second model should always face the camera, except for Skull Token + if (model->itemRow->objectId != 0x0020) { + model->actor->actor_shape.rot.y = GetContext().gctx->main_camera.cam_dir.y; + } + Actor_SetModelMatrix(actorPos.x, modelPosY, actorPos.z, &model->saModel2->mtx, &model->actor->actor_shape); + model->actor->actor_shape.rot.y = tempRotY; } - Model_SetMtxAndModel(model->saModel2, &tmpMtx); - model->actor->actor_shape.rot.y = tmpY; + Model_MultiplyMatrix(&model->saModel2->mtx, &model->saModel2->mtx, &scaleMtx); } } void Model_Init(Model* model, game::GlobalContext* globalCtx) { s16 objectId = model->itemRow->objectId; model->saModel = SkeletonAnimationModel_Spawn(model->actor, globalCtx, objectId, model->itemRow->objectModelIdx); + + SkeletonAnimationModel_SetMeshByDrawItemID(model->saModel, (s32)model->itemRow->graphicId - 1); + + if (model->itemRow->cmabIndex >= 0) { + Model_SetAnim(model->saModel, model->itemRow->objectId, model->itemRow->cmabIndex); + } + if (model->itemRow->objectModelIdx2 >= 0) { model->saModel2 = SkeletonAnimationModel_Spawn(model->actor, globalCtx, objectId, model->itemRow->objectModelIdx2); - Model_SetAnim(model->saModel2, model->itemRow->objectId); - } - - SkeletonAnimationModel_SetMeshByDrawItemID(model->saModel, (s32)model->itemRow->graphicId - 1); - if (model->itemRow->objectModelIdx != 0xFF) { - Model_SetAnim(model->saModel, model->itemRow->objectId); - // model->saModel->unk_0C->animSpeed = 2.0f; - // model->saModel->unk_0C->animMode = 1; + if (model->itemRow->cmabIndex2 >= 0) { + Model_SetAnim(model->saModel2, model->itemRow->objectId, model->itemRow->cmabIndex2); + } } model->loaded = 1; @@ -161,6 +184,7 @@ namespace rnd { model->loaded = 0; model->objectBankIdx = -1; model->objectId = -1; + model->posOffset = {0, -10.00, 0}; } void Model_UpdateAll(game::GlobalContext* globalCtx) { @@ -246,6 +270,10 @@ namespace rnd { newModel->objectBankIdx = model->objectBankIdx; newModel->baseItemId = model->baseItemId; newModel->objectId = model->itemRow->objectId; + // XXX: Small patch - if we are not the index of a deku nut, then we adjust scale. + if (newModel->itemRow->objectModelIdx != 0x8D) { + newModel->scale = 0.3f * newModel->itemRow->scale; + } } } @@ -274,11 +302,12 @@ namespace rnd { } } - s32 Model_DrawByActor(game::act::Actor* actor) { + s32 Model_DrawByActor(game::act::Actor* actor, z3d_nn_math_MTX34* hardcodedMtx /*= NULL*/) { s32 actorDrawn = 0; for (s32 i = 0; i < LOADEDMODELS_MAX; ++i) { if (ModelContext[i].actor == actor) { actorDrawn = 1; + ModelContext[i].hardcodedMtx = hardcodedMtx; Model_Draw(&ModelContext[i]); } } @@ -299,26 +328,32 @@ namespace rnd { void Actor_Init() { game::act::ActorOverlayInfo* overlayTable = game::act::GetActorOverlayInfoTable(); // Setup destroy and init functions at this point instead of creating a ton of ASM patches. + // Use this only if the drwaing for the actor is not complex. Otherwise ASM patches are better. overlayTable[0x0E].info->deinit_fn = EnItem00_rDestroy; - // overlayTable[0xDC].info->init_fn = Dm_Hina_Init; - // overlayTable[0xDC].info->draw_fn = Dm_Hina_Draw; - // overlayTable[0xDC].info->deinit_fn = Dm_Hina_Destroy; + overlayTable[0xDC].info->init_fn = Dm_Hina_Init; + overlayTable[0xDC].info->deinit_fn = Dm_Hina_Destroy; overlayTable[0x2F].info->init_fn = ItemBHeart_Init; overlayTable[0x2F].info->draw_fn = ItemBHeart_Draw; overlayTable[0x2F].info->deinit_fn = ItemBHeart_Destroy; + // overlayTable[0x87].info->init_fn = En_Mag_rInit; + overlayTable[0x99].info->init_fn = En_Si_Init; overlayTable[0x99].info->draw_fn = En_Si_Draw; overlayTable[0x99].info->deinit_fn = En_Si_Destroy; - // overlayTable[0x12B].info->init_fn = Dm_Char03_Init; - // overlayTable[0x12B].info->draw_fn = Dm_Char03_Draw; - // overlayTable[0x12B].info->deinit_fn = Dm_Char03_Destroy; + overlayTable[0x12B].info->init_fn = Dm_Char03_Init; + overlayTable[0x12B].info->deinit_fn = Dm_Char03_Destroy; + + overlayTable[0x12D].info->init_fn = Dm_Char05_Init; + overlayTable[0x12D].info->deinit_fn = Dm_Char05_Destroy; + + overlayTable[0x16A].info->init_fn = Fish_Heart_Init; + overlayTable[0x16A].info->deinit_fn = Fish_Heart_Destroy; - // overlayTable[0x12D].info->init_fn = DMChar05_Init; - // overlayTable[0x12D].info->draw_fn = DMChar05_Draw; - // overlayTable[0x12D].info->deinit_fn = DMChar05_Destroy; + overlayTable[0x212].info->init_fn = Obj_Moon_Stone_Init; + overlayTable[0x212].info->deinit_fn = Obj_Moon_Stone_Destroy; } } // namespace rnd diff --git a/code/source/rnd/objects.cpp b/code/source/rnd/objects.cpp index b01d53b8..280b1c44 100644 --- a/code/source/rnd/objects.cpp +++ b/code/source/rnd/objects.cpp @@ -2,14 +2,14 @@ namespace rnd { ExtendedObjectContext rExtendedObjectCtx = {0}; - s32 storedObjId = -1; + s32 rStoredObjId = -1; s32 yPos = 0; s32 xPos = 0; s32 zPos = 0; - void TexAnim_Spawn(void* model, void* cmabMan) { - return util::GetPointer(0x609c3c)(model, cmabMan); - } + // void TexAnim_Spawn(void* model, void* cmabMan) { + // return util::GetPointer(0x609c3c)(model, cmabMan); + // } s32 Object_SpawnPersistent(void* objectCtx, s16 objectId) { return util::GetPointer(0x4C01CC)(objectCtx, objectId); @@ -31,7 +31,7 @@ namespace rnd { return util::GetPointer(0x175A00)(objectCtx); } - void* GAR_GetCMBByIndex(game::ObjectBank::ObjectBankArchive* objBankArchive, u32 objectAnimIdx) { + void* GAR_GetCMABByIndex(game::ObjectBank::ObjectBankArchive* objBankArchive, u32 objectAnimIdx) { return util::GetPointer(0x1F28AC)(objBankArchive, objectAnimIdx); } @@ -47,8 +47,8 @@ namespace rnd { s32 ExtendedObject_GetIndex(game::ActorResource::ObjectContext* objectCtx, s16 objectId) { // XXX: There seems to be a race condition issue. If we include one or two more function // calls, it appears that gold dust and it's bottle will willingly spawn in. - if (objectId == 0x01E9 || objectId == 0x01E8) - rnd::util::Print("%s: %#06x\n", __func__, objectId); + // if (objectId == 0x01E9 || objectId == 0x01E8) + // rnd::util::Print("%s: %#06x\n", __func__, objectId); s32 index = Object_GetSlot(objectCtx, objectId); if (index < 0) { s32 i; @@ -72,11 +72,14 @@ namespace rnd { extern "C" game::ActorResource::ActorResource* ExtendedObject_GetStatus() { s32 i; +#if defined ENABLE_DEBUG || defined DEBUG_PRINT + rnd::util::Print("%s: rStoredObjId is %#06x\n", __func__, rStoredObjId); +#endif for (i = 0; i < rExtendedObjectCtx.num; ++i) { s32 id = rExtendedObjectCtx.status[i].object_id; id = (id < 0 ? -id : id); - if (id == storedObjId) { - util::GetPointer(0x1F15B4)(&rExtendedObjectCtx, id); + if (id == rStoredObjId) { + // util::GetPointer(0x1F15B4)(&rExtendedObjectCtx, id); return &rExtendedObjectCtx.status[i]; } } @@ -89,10 +92,10 @@ namespace rnd { void* cmabMan; if (objectBankIdx < OBJECT_EXCHANGE_BANK_MAX) { - cmabMan = GAR_GetCMBByIndex(&gctx->object_context.status[objectBankIdx].archive, objectAnimIdx); + cmabMan = GAR_GetCMABByIndex(&gctx->object_context.status[objectBankIdx].archive, objectAnimIdx); } else { - cmabMan = GAR_GetCMBByIndex(&rExtendedObjectCtx.status[objectBankIdx - OBJECT_EXCHANGE_BANK_MAX].archive, - objectAnimIdx); + cmabMan = GAR_GetCMABByIndex(&rExtendedObjectCtx.status[objectBankIdx - OBJECT_EXCHANGE_BANK_MAX].archive, + objectAnimIdx); } return cmabMan; } diff --git a/code/source/rnd/title_screen.cpp b/code/source/rnd/title_screen.cpp deleted file mode 100644 index 8f527f0c..00000000 --- a/code/source/rnd/title_screen.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "rnd/custom_models.h" -#include "z3d/z3DVec.h" -// #include "rnd/objects.h" -#include "rnd/title_screen.h" - -namespace rnd { -#define EnMag_Init_addr 0x32433C -#define EnMag_Init ((ActorFunc)EnMag_Init_addr) - - // TODO: Init hooks for title screen. - void EnMag_rInit(EnMag* self, game::GlobalContext* globalCtx) { - // void* cmbPtr = rnd::util::GetPointer(0x1F28AC)(3); - // self->model->spawn(cmbPtr); - return; - // EnMag *enmag = (EnMag *)thisx; - - // s8 objBankIdx = enmag->actor.objBankIndex; - // void *titleScreenZAR = globalCtx->objectCtx.status[objBankIdx].zarInfo.buf; - // void *cmabMan; - - // s16 exObjectBankIdx = Object_GetIndex(&rExtendedObjectCtx, OBJECT_CUSTOM_GENERAL_ASSETS); - // if (exObjectBankIdx < 0) { - // exObjectBankIdx = Object_Spawn(&rExtendedObjectCtx, OBJECT_CUSTOM_GENERAL_ASSETS); - // } - - // CustomModel_EditTitleScreenLogo(titleScreenZAR); - - // EnMag_Init(thisx, globalCtx); - - // cmabMan = ZAR_GetCMABByIndex(&rExtendedObjectCtx.status[exObjectBankIdx].zarInfo, - // TEXANIM_TITLE_LOGO_US); TexAnim_Spawn(enmag->logoModel->unk_0C, cmabMan); - // enmag->logoModel->unk_0C->animSpeed = 0.0f; - // enmag->logoModel->unk_0C->animMode = 0; - - // cmabMan = ZAR_GetCMABByIndex(&rExtendedObjectCtx.status[exObjectBankIdx].zarInfo, - // TEXANIM_COPY_NINTENDO); TexAnim_Spawn(enmag->copyrightModel->unk_0C, cmabMan); - // enmag->copyrightModel->unk_0C->animSpeed = 0.0f; - // enmag->copyrightModel->unk_0C->animMode = 0; - } -} // namespace rnd