diff --git a/assets/xml/objects/object_nb.xml b/assets/xml/objects/object_nb.xml index 511fddd6c3..7ac63e118c 100644 --- a/assets/xml/objects/object_nb.xml +++ b/assets/xml/objects/object_nb.xml @@ -1,46 +1,58 @@  + - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/include/functions.h b/include/functions.h index dbe7d1de13..fd562daf07 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1675,7 +1675,7 @@ void Map_Destroy(PlayState* play); // void func_8010BEBC(void); // void func_8010BEF0(void); // void func_8010BF24(void); -s32 func_8010BF58(Actor* actor, PlayState* play, s32* param_3, UNK_PTR param_4, s32* param_5); +s32 func_8010BF58(Actor* actor, PlayState* play, void* param_3, UNK_PTR param_4, s32* param_5); void Nmi_Init(void); void Nmi_SetPrenmiStart(void); // s32 Nmi_GetPrenmiHasStarted(void); @@ -2393,7 +2393,7 @@ s32 func_8016A02C(GameState* thisx, Actor* actor, s16* yaw); s32 Play_IsUnderwater(PlayState* this, Vec3f* pos); s32 Play_IsDebugCamEnabled(void); void Play_AssignPlayerActorCsIdsFromScene(GameState* thisx, s32 startActorCsId); -void func_8016A268(GameState* gameState, s16 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5); +void Play_FillScreen(GameState* gameState, s16 fillScreenOn, u8 red, u8 green, u8 blue, u8 alpha); void Play_Init(GameState* gameState); // void func_8016AC10(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10); // void func_8016AE1C(void); diff --git a/include/regs.h b/include/regs.h index ab31e6d25e..212c1c0317 100644 --- a/include/regs.h +++ b/include/regs.h @@ -47,12 +47,19 @@ #define R_RUN_SPEED_LIMIT REG(45) #define R_UPDATE_RATE SREG(30) #define R_PAUSE_MENU_MODE SREG(94) +#define R_PLAY_FILL_SCREEN_ON MREG(64) +#define R_PLAY_FILL_SCREEN_R MREG(65) +#define R_PLAY_FILL_SCREEN_G MREG(66) +#define R_PLAY_FILL_SCREEN_B MREG(67) +#define R_PLAY_FILL_SCREEN_ALPHA MREG(68) #define R_PAUSE_WORLD_MAP_YAW YREG(24) #define R_PAUSE_WORLD_MAP_Y_OFFSET YREG(25) #define R_PAUSE_WORLD_MAP_DEPTH YREG(26) #define R_PAUSE_DBG_QUEST_CURSOR_ON YREG(69) #define R_PAUSE_DBG_QUEST_CURSOR_X YREG(70) #define R_PAUSE_DBG_QUEST_CURSOR_Y YREG(71) +#define R_C_UP_ICON_X YREG(88) +#define R_C_UP_ICON_Y YREG(89) #define R_MAGIC_FILL_COLOR(i) ZREG(0 + i) #define R_C_BTN_COLOR(i) ZREG(39 + i) #define R_B_BTN_COLOR(i) ZREG(43 + i) @@ -81,6 +88,7 @@ #define R_MOON_CRASH_TIMER_Y XREG(80) #define R_MOON_CRASH_TIMER_X XREG(81) #define R_PAUSE_OWLWARP_ALPHA XREG(87) +#define R_STORY_FILL_SCREEN_ALPHA XREG(91) #define R_REVERSE_FLOOR_INDEX XREG(94) #define R_MINIMAP_DISABLED XREG(95) #define R_B_LABEL_DD WREG(0) diff --git a/include/z64.h b/include/z64.h index 2daea1d77e..1b12ad5225 100644 --- a/include/z64.h +++ b/include/z64.h @@ -555,8 +555,8 @@ typedef struct { /* 0x318 */ u8 pictographBox; /* 0x319 */ u8 all; // "another"; enables all item restrictions } restrictions; // size = 0xC - /* 0x31A */ u8 unk_31A; - /* 0x31B */ u8 unk_31B; + /* 0x31A */ u8 storyState; + /* 0x31B */ u8 storyType; /* 0x31C */ u8 unk_31C; /* 0x320 */ OSMesgQueue unk_320; /* 0x338 */ OSMesg unk_338; diff --git a/spec b/spec index 48c0983a0e..ab9a801f71 100644 --- a/spec +++ b/spec @@ -4297,8 +4297,7 @@ beginseg name "ovl_En_Nb" compress include "build/src/overlays/actors/ovl_En_Nb/z_en_nb.o" - include "build/data/ovl_En_Nb/ovl_En_Nb.data.o" - include "build/data/ovl_En_Nb/ovl_En_Nb.reloc.o" + include "build/src/overlays/actors/ovl_En_Nb/ovl_En_Nb_reloc.o" endseg beginseg diff --git a/src/code/title_setup.c b/src/code/title_setup.c index 641160ea8b..8ba6f9b563 100644 --- a/src/code/title_setup.c +++ b/src/code/title_setup.c @@ -27,7 +27,7 @@ void Setup_SetRegs(void) { XREG(88) = 0x56; XREG(89) = 0x258; XREG(90) = 0x1C2; - XREG(91) = 0; + R_STORY_FILL_SCREEN_ALPHA = 0; R_REVERSE_FLOOR_INDEX = 0; R_MINIMAP_DISABLED = false; diff --git a/src/code/z_play.c b/src/code/z_play.c index 47bb97a604..71fbc897f7 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -540,13 +540,13 @@ void Play_AssignPlayerActorCsIdsFromScene(GameState* thisx, s32 startActorCsId) } } -// These regs are used by Gameplay_Draw, and several actors, purpose as yet unclear. -void func_8016A268(GameState* thisx, s16 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) { - MREG(64) = arg1; - MREG(65) = arg2; - MREG(66) = arg3; - MREG(67) = arg4; - MREG(68) = arg5; +// Set values to fill screen +void Play_FillScreen(GameState* thisx, s16 fillScreenOn, u8 red, u8 green, u8 blue, u8 alpha) { + R_PLAY_FILL_SCREEN_ON = fillScreenOn; + R_PLAY_FILL_SCREEN_R = red; + R_PLAY_FILL_SCREEN_G = green; + R_PLAY_FILL_SCREEN_B = blue; + R_PLAY_FILL_SCREEN_ALPHA = alpha; } #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Init.s") diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 1e2db7a603..896bf99ae2 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -462,20 +462,20 @@ Vec3f D_809DFA2C[] = { { -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, }; -void func_809DA1D0(PlayState* play, u8 arg1, u8 arg2, u8 arg3, u8 arg4) { - MREG(64) = 1; - MREG(65) = arg1; - MREG(66) = arg2; - MREG(67) = arg3; - MREG(68) = arg4; +void func_809DA1D0(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) { + R_PLAY_FILL_SCREEN_ON = true; + R_PLAY_FILL_SCREEN_R = red; + R_PLAY_FILL_SCREEN_G = green; + R_PLAY_FILL_SCREEN_B = blue; + R_PLAY_FILL_SCREEN_ALPHA = alpha; } -void func_809DA22C(PlayState* play, u8 arg1) { - MREG(68) = arg1; +void func_809DA22C(PlayState* play, u8 alpha) { + R_PLAY_FILL_SCREEN_ALPHA = alpha; } void func_809DA24C(PlayState* play) { - MREG(64) = 0; + R_PLAY_FILL_SCREEN_ON = false; } void Boss02_SpawnEffectSand(TwinmoldEffect* effects, Vec3f* pos, f32 scale) { @@ -1626,7 +1626,7 @@ void func_809DD934(Boss02* this, PlayState* play) { Vec3f sp58; u8 sp57 = 0; f32 phi_f0_2; - s16 phi_v1; + s16 alpha; this->unk_1D14++; @@ -1995,11 +1995,9 @@ void func_809DD934(Boss02* this, PlayState* play) { if (this->unk_1D7A >= 400) { this->unk_1D78 = 3; } - phi_v1 = this->unk_1D7A; - if (phi_v1 > 255) { - phi_v1 = 255; - } - func_809DA22C(play, phi_v1); + alpha = this->unk_1D7A; + alpha = CLAMP_MAX(alpha, 255); + func_809DA22C(play, alpha); break; case 3: @@ -2009,11 +2007,9 @@ void func_809DD934(Boss02* this, PlayState* play) { this->unk_1D78 = 0; func_809DA24C(play); } else { - phi_v1 = this->unk_1D7A; - if (phi_v1 > 255) { - phi_v1 = 255; - } - func_809DA22C(play, phi_v1); + alpha = this->unk_1D7A; + alpha = CLAMP_MAX(alpha, 255); + func_809DA22C(play, alpha); } break; } diff --git a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c index 3dcde37874..656f609042 100644 --- a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c +++ b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c @@ -5,7 +5,6 @@ */ #include "z_dm_nb.h" -#include "objects/object_nb/object_nb.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) @@ -28,7 +27,9 @@ const ActorInit Dm_Nb_InitVars = { (ActorFunc)DmNb_Draw, }; -static AnimationInfoS sAnimationInfo[] = { { &object_nb_Anim_000990, 1.0f, 0, -1, ANIMMODE_LOOP, 0 } }; +static AnimationInfoS sAnimationInfo[] = { + { &gNbIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, +}; s32 func_80C1DED0(DmNb* this, s32 arg1) { s32 ret = false; @@ -70,7 +71,7 @@ void DmNb_Init(Actor* thisx, PlayState* play) { DmNb* this = THIS; ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); - SkelAnime_InitFlex(play, &this->skelAnime, &object_nb_Skel_008C40, NULL, this->jointTable, this->morphTable, 8); + SkelAnime_InitFlex(play, &this->skelAnime, &gNbSkel, NULL, this->jointTable, this->morphTable, NB_LIMB_MAX); this->unk1F0 = -1; func_80C1DED0(this, 0); this->actor.flags &= ~ACTOR_FLAG_1; diff --git a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.h b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.h index eafc4ef996..e13032de13 100644 --- a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.h +++ b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.h @@ -2,6 +2,7 @@ #define Z_DM_NB_H #include "global.h" +#include "objects/object_nb/object_nb.h" struct DmNb; @@ -11,8 +12,8 @@ typedef struct DmNb { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ DmNbActionFunc actionFunc; - /* 0x18C */ Vec3s jointTable[8]; - /* 0x1BC */ Vec3s morphTable[8]; + /* 0x18C */ Vec3s jointTable[NB_LIMB_MAX]; + /* 0x1BC */ Vec3s morphTable[NB_LIMB_MAX]; /* 0x1EC */ u8 unk1EC; /* 0x1F0 */ s32 unk1F0; /* 0x1F4 */ s32 unk1F4; diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 34247cd7f8..ba7bac6c53 100644 --- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -261,7 +261,8 @@ void DoorShutter_Destroy(Actor* thisx, PlayState* play) { } void DoorShutter_SetupType(DoorShutter* this, PlayState* play) { - if (Object_IsLoaded(&play->objectCtx, this->requiredObjBankIndex) && ((MREG(64) == 0) || (MREG(68) == 0))) { + if (Object_IsLoaded(&play->objectCtx, this->requiredObjBankIndex) && + (!R_PLAY_FILL_SCREEN_ON || (R_PLAY_FILL_SCREEN_ALPHA == 0))) { this->actor.objBankIndex = this->requiredObjBankIndex; this->actor.draw = DoorShutter_Draw; DoorShutter_SetupDoor(this, play); diff --git a/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c b/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c index 788759e3cd..fe97117f9d 100644 --- a/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c +++ b/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c @@ -361,8 +361,7 @@ s32 EnBjt_ChooseAnimation(EnBjt* this, PlayState* play) { void EnBjt_Talk(EnBjt* this, PlayState* play) { s16 yaw = this->actor.yawTowardsPlayer; - // TODO: Casting to remove warning for now - if (func_8010BF58(&this->actor, play, (s32)sMsgEventScript, this->msgEventCallback, &this->msgEventArg4)) { + if (func_8010BF58(&this->actor, play, sMsgEventScript, this->msgEventCallback, &this->msgEventArg4)) { this->actor.flags &= ~ACTOR_FLAG_100; SubS_UpdateFlags(&this->stateFlags, 3, 7); this->stateFlags &= ~TOILET_HAND_STATE_TALKING; diff --git a/src/overlays/actors/ovl_En_Nb/z_en_nb.c b/src/overlays/actors/ovl_En_Nb/z_en_nb.c index 9e27fe6055..42dee5befe 100644 --- a/src/overlays/actors/ovl_En_Nb/z_en_nb.c +++ b/src/overlays/actors/ovl_En_Nb/z_en_nb.c @@ -5,6 +5,7 @@ */ #include "z_en_nb.h" +#include "objects/object_nb/object_nb.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) @@ -15,10 +16,100 @@ void EnNb_Destroy(Actor* thisx, PlayState* play); void EnNb_Update(Actor* thisx, PlayState* play); void EnNb_Draw(Actor* thisx, PlayState* play); -void func_80BC0D84(EnNb* this, PlayState* play); +void EnNb_FollowSchedule(EnNb* this, PlayState* play); void func_80BC0EAC(EnNb* this, PlayState* play); -#if 0 +void func_80BC08E0(EnNb* this, PlayState* play); +void func_80BC0978(EnNb* this, PlayState* play); + +s32 func_80BC00AC(Actor* thisx, PlayState* play); +s32 func_80BC01DC(Actor* thisx, PlayState* play); + +#define EN_NB_FLAG_NONE (0) +#define EN_NB_FLAG_1 (1 << 0) +#define EN_NB_FLAG_2 (1 << 1) +#define EN_NB_FLAG_4 (1 << 2) +#define EN_NB_FLAG_8 (1 << 3) +#define EN_NB_FLAG_10 (1 << 4) +#define EN_NB_FLAG_20 (1 << 5) +#define EN_NB_FLAG_40 (1 << 6) +#define EN_NB_FLAG_80 (1 << 7) +#define EN_NB_FLAG_100 (1 << 8) +#define EN_NB_FLAG_200 (1 << 9) +#define EN_NB_FLAG_400 (1 << 10) + +typedef enum EnNbScheduleResult { + /* 0 */ EN_NB_SCH_NONE, + /* 1 */ EN_NB_SCH_1, + /* 2 */ EN_NB_SCH_2, + /* 3 */ EN_NB_SCH_3, + /* 4 */ EN_NB_SCH_4, +} EnNbScheduleResult; + +static u8 sScheduleScript[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x21 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0x12 - 0x08), + /* 0x08 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(6, 0, 18, 0, 0x0F - 0x0E), + /* 0x0E */ SCHEDULE_CMD_RET_NONE(), + /* 0x0F */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_3), + /* 0x12 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_OMOYA, 0x20 - 0x16), + /* 0x16 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x1D - 0x1C), + /* 0x1C */ SCHEDULE_CMD_RET_NONE(), + /* 0x1D */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_4), + /* 0x20 */ SCHEDULE_CMD_RET_NONE(), + /* 0x21 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0x72 - 0x25), + /* 0x25 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(1, 0x47 - 0x29), + /* 0x29 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(8, 0, 12, 0, 0x44 - 0x2F), + /* 0x2F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 0, 12, 15, 0x41 - 0x35), + /* 0x35 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 15, 18, 0, 0x3E - 0x3B), + /* 0x3B */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_3), + /* 0x3E */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_1), + /* 0x41 */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_2), + /* 0x44 */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_1), + /* 0x47 */ SCHEDULE_CMD_CHECK_FLAG_S(0x32, 0x20, 0x57 - 0x4B), + /* 0x4B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(8, 0, 18, 0, 0x54 - 0x51), + /* 0x51 */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_3), + /* 0x54 */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_1), + /* 0x57 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(8, 0, 12, 0, 0x70 - 0x5D), + /* 0x5D */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 0, 12, 15, 0x6E - 0x63), + /* 0x63 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 15, 18, 0, 0x6C - 0x69), + /* 0x69 */ SCHEDULE_CMD_RET_VAL_L(EN_NB_SCH_3), + /* 0x6C */ SCHEDULE_CMD_RET_VAL_S(EN_NB_SCH_1), + /* 0x6E */ SCHEDULE_CMD_RET_VAL_S(EN_NB_SCH_2), + /* 0x70 */ SCHEDULE_CMD_RET_VAL_S(EN_NB_SCH_1), + /* 0x72 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80BC1464[] = { + 0x1B, 0x04, 0x08, 0x00, 0x6A, 0x0A, 0x00, 0x10, 0x00, 0x08, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x0E, + 0x29, 0x12, 0x2D, 0x00, 0x0E, 0x0C, 0x10, 0x0E, 0x29, 0x01, 0x2D, 0x00, 0x0E, 0x0C, 0x10, 0x0E, 0x29, 0x02, 0x0C, + 0x0F, 0x29, 0x03, 0x0C, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x22, 0x31, 0x2D, 0x00, 0x0E, 0x12, 0x10, 0x30, 0x1C, + 0x04, 0x04, 0x0E, 0x29, 0x04, 0x0C, 0x20, 0x00, 0x03, 0x00, 0x04, 0x15, 0x09, 0x00, 0xC4, 0x09, 0x00, 0x00, 0x0F, + 0x29, 0x05, 0x0C, 0x15, 0x09, 0x00, 0xB9, 0x30, 0x1D, 0x04, 0x04, 0x0E, 0x29, 0x0B, 0x0C, 0x20, 0x00, 0x03, 0x00, + 0x04, 0x15, 0x09, 0x00, 0xA8, 0x09, 0x00, 0x00, 0x0F, 0x29, 0x0C, 0x0C, 0x15, 0x09, 0x00, 0x9D, 0x20, 0x00, 0x03, + 0x00, 0x17, 0x1B, 0x04, 0x04, 0x00, 0x09, 0x0E, 0x29, 0x11, 0x2D, 0x00, 0x0E, 0x0C, 0x16, 0x10, 0x0E, 0x29, 0x0A, + 0x2D, 0x00, 0x0E, 0x0C, 0x16, 0x10, 0x1B, 0x04, 0x04, 0x00, 0x3B, 0x0E, 0x29, 0x0D, 0x0C, 0x05, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x0E, 0x29, 0x10, 0x2D, 0x00, 0x0E, 0x0C, 0x12, 0x16, 0x10, 0x0E, 0x29, 0x0E, 0x00, 0x32, 0x04, + 0x00, 0x59, 0x0C, 0x0F, 0x29, 0x0F, 0x0C, 0x12, 0x06, 0x00, 0x0C, 0x00, 0x00, 0x13, 0x00, 0x0C, 0x2F, 0x00, 0x00, + 0x2E, 0x2D, 0x00, 0x2A, 0x2D, 0x00, 0x0E, 0x11, 0x32, 0x04, 0x0C, 0x16, 0x10, 0x0E, 0x29, 0x06, 0x0C, 0x05, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x29, 0x07, 0x2D, 0x00, 0x0E, 0x0C, 0x12, 0x16, 0x10, 0x0E, 0x29, 0x08, 0x00, + 0x32, 0x02, 0x00, 0x1E, 0x0C, 0x0F, 0x29, 0x09, 0x0C, 0x12, 0x06, 0x00, 0x0C, 0x00, 0x00, 0x13, 0x00, 0x0C, 0x2F, + 0x00, 0x00, 0x2E, 0x2D, 0x00, 0x29, 0x2D, 0x00, 0x0E, 0x11, 0x32, 0x02, 0x0C, 0x16, 0x10, 0x2D, 0x00, 0x0E, 0x0C, + 0x12, 0x16, 0x10, 0x00, 0x00, 0x00, +}; + +u8 D_80BC1574[] = { + 0x09, 0x00, 0x00, 0x0E, 0x28, 0xC7, 0x0C, 0x09, 0x00, 0x00, 0x17, 0x0E, 0x28, 0xC8, 0x0C, 0x09, 0x00, + 0x00, 0x18, 0x0E, 0x28, 0xC9, 0x0C, 0x09, 0x00, 0x00, 0x17, 0x0E, 0x28, 0xCA, 0x0C, 0x09, 0x00, 0x00, + 0x18, 0x0E, 0x28, 0xCB, 0x0C, 0x09, 0x00, 0x00, 0x17, 0x0E, 0x28, 0xCC, 0x0C, 0x09, 0x00, 0x00, 0x18, + 0x0E, 0x28, 0xCD, 0x0C, 0x09, 0x00, 0x00, 0x17, 0x0E, 0x28, 0xCE, 0x0C, 0x09, 0x00, 0x00, 0x18, 0x0E, + 0x28, 0xCF, 0x2D, 0x00, 0x01, 0x2D, 0x00, 0x0E, 0x0C, 0x09, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, +}; + +u8 D_80BC15C8[] = { + 0x0E, 0x23, 0x62, 0x2D, 0x00, 0x0E, 0x0C, 0x10, +}; + const ActorInit En_Nb_InitVars = { ACTOR_EN_NB, ACTORCAT_NPC, @@ -31,81 +122,676 @@ const ActorInit En_Nb_InitVars = { (ActorFunc)EnNb_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BC15F0 = { - { COLTYPE_HIT1, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT1, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 10, 68, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BC161C = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfoS sAnimationInfo[] = { + { &gNbIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, // EN_NB_ANIM_0 + { &gNbIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, // EN_NB_ANIM_1 + { &gNbTalkAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, // EN_NB_ANIM_TALK_ONCE + { &gNbTalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, // EN_NB_ANIM_TALK_LOOP + { &gNbAngryAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, // EN_NB_ANIM_ANGRY + { &gNbRelievedAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, // EN_NB_ANIM_RELIEVED +}; -extern ColliderCylinderInit D_80BC15F0; -extern CollisionCheckInfoInit2 D_80BC161C; +Actor* EnNb_FindActor(EnNb* this, PlayState* play, u8 actorCategory, s16 actorId) { + Actor* thisx; + Actor* actor = NULL; -extern UNK_TYPE D_06008C40; + while (true) { + actor = SubS_FindActor(play, actor, actorCategory, actorId); + if (actor == NULL) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BBFDB0.s") + thisx = &this->actor; + if ((actor != thisx) && (actor->update != NULL)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BBFE60.s") + if (actor->next == NULL) { + actor = NULL; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BBFE8C.s") + actor = actor->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BBFF24.s") + return actor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BBFF90.s") +void EnNb_UpdateSkelAnime(EnNb* this) { + this->skelAnime.playSpeed = this->animPlaySpeed; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BBFFD4.s") +s32 EnNb_ChangeAnim(EnNb* this, EnNbAnimation animIndex) { + s32 shouldChange = false; + s32 didAnimationChange = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0050.s") + if ((animIndex == EN_NB_ANIM_0) || (animIndex == EN_NB_ANIM_1)) { + if ((this->animIndex != EN_NB_ANIM_0) && (this->animIndex != EN_NB_ANIM_1)) { + shouldChange = true; + } + } else if (animIndex != this->animIndex) { + shouldChange = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC00AC.s") + if (shouldChange) { + this->animIndex = animIndex; + didAnimationChange = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimationInfo, animIndex); + this->animPlaySpeed = this->skelAnime.playSpeed; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC01DC.s") + return didAnimationChange; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC045C.s") +void func_80BBFF24(EnNb* this, PlayState* play) { + f32 yDiff; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC04FC.s") + Collider_UpdateCylinder(&this->actor, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC05A8.s") + yDiff = this->actor.focus.pos.y - this->actor.world.pos.y; + this->collider.dim.height = yDiff; + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC06C4.s") +Actor* func_80BBFF90(EnNb* this, PlayState* play) { + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0800.s") + if (this->scheduleResult == EN_NB_SCH_2) { + actor = EnNb_FindActor(this, play, ACTORCAT_NPC, ACTOR_EN_AN); + } else { + actor = &GET_PLAYER(play)->actor; + } + return actor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC08E0.s") +s32 func_80BBFFD4(EnNb* this, s16 index) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0978.s") + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(index); + } else if (ActorCutscene_GetCanPlayNext(index)) { + ActorCutscene_StartAndSetUnkLinkFields(index, &this->actor); + ret = true; + } else { + ActorCutscene_SetIntentToPlay(index); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0A18.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0B98.s") +s16 func_80BC0050(EnNb* this, s32 arg1) { + s16 cutscene = this->actor.cutscene; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0C0C.s") + for (i = 0; i < arg1; i++) { + cutscene = ActorCutscene_GetAdditionalCutscene(cutscene); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0C80.s") + return cutscene; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0D08.s") +typedef enum EnNbBehaviour { + /* 0 */ ENNB_BEHAVIOUR_0, + /* 1 */ ENNB_BEHAVIOUR_1, + /* 2 */ ENNB_BEHAVIOUR_2, + /* 3 */ ENNB_BEHAVIOUR_3, + /* 4 */ ENNB_BEHAVIOUR_4, + /* 5 */ ENNB_BEHAVIOUR_5, + /* 6 */ ENNB_BEHAVIOUR_6, + /* 7 */ ENNB_BEHAVIOUR_7, + /* 8 */ ENNB_BEHAVIOUR_8, + /* 9 */ ENNB_BEHAVIOUR_9 +} EnNbBehaviour; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0D1C.s") +s32 func_80BC00AC(Actor* thisx, PlayState* play) { + EnNb* this = THIS; + s16 cutscene = func_80BC0050(this, 0); + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0D84.s") + switch (this->behaviour) { + case ENNB_BEHAVIOUR_0: + if (!func_80BBFFD4(this, cutscene)) { + break; + } + // fallthrough + case ENNB_BEHAVIOUR_2: + case ENNB_BEHAVIOUR_4: + case ENNB_BEHAVIOUR_6: + case ENNB_BEHAVIOUR_8: + Camera_SetTargetActor(Play_GetCamera(play, ActorCutscene_GetCurrentSubCamId(cutscene)), &this->actor); + this->behaviour++; + ret = true; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC0EAC.s") + case ENNB_BEHAVIOUR_1: + case ENNB_BEHAVIOUR_3: + case ENNB_BEHAVIOUR_5: + case ENNB_BEHAVIOUR_7: + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + Camera_SetTargetActor(Play_GetCamera(play, ActorCutscene_GetCurrentSubCamId(cutscene)), + this->actor.child); + } + this->behaviour++; + ret = true; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/EnNb_Init.s") + case ENNB_BEHAVIOUR_9: + ActorCutscene_Stop(cutscene); + this->behaviour++; + ret = true; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/EnNb_Destroy.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/EnNb_Update.s") +s32 func_80BC01DC(Actor* thisx, PlayState* play) { + EnNb* this = THIS; + s32 pad; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC1174.s") + switch (this->behaviour) { + case ENNB_BEHAVIOUR_0: + if (Player_GetMask(play) == PLAYER_MASK_ALL_NIGHT) { + this->behaviour = ENNB_BEHAVIOUR_1; + } else { + this->behaviour = ENNB_BEHAVIOUR_5; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC11B4.s") + case ENNB_BEHAVIOUR_1: + // Setup a black fill-screen, although initialize to 0 alpha + Play_FillScreen(&play->state, true, 0, 0, 0, 0); + this->storyTimer = 40; + this->behaviour = (u16)(this->behaviour + 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/func_80BC1278.s") + case ENNB_BEHAVIOUR_2: + // Slowly increase alpha to fill the screen with a black rectangle + R_PLAY_FILL_SCREEN_ALPHA = (s16)(s32)(255.0f - (((f32)ABS_ALT(20 - this->storyTimer) / 20.0f) * 255.0f)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nb/EnNb_Draw.s") + if (this->storyTimer == 20) { + if (gSaveContext.eventInf[4] & 4) { + // play->interfaceCtx.storyType = STORY_TYPE_MASK_FESTIVAL; + play->interfaceCtx.storyType = 0; + } else { + // play->interfaceCtx.storyType = STORY_TYPE_GIANTS_LEAVING; + play->interfaceCtx.storyType = 1; + } + // play->interfaceCtx.storyState = STORY_STATE_FADE_IN; + play->interfaceCtx.storyState = 6; + R_STORY_FILL_SCREEN_ALPHA = 255; + } + + if (DECR(this->storyTimer) == 0) { + this->behaviour++; + } + break; + + case ENNB_BEHAVIOUR_3: + // play->interfaceCtx.storyState = STORY_STATE_SETUP_IDLE; + play->interfaceCtx.storyState = 4; + this->behaviour++; + ret = true; + break; + + case ENNB_BEHAVIOUR_4: + // play->interfaceCtx.storyState = STORY_STATE_FADE_OUT; + play->interfaceCtx.storyState = 5; + this->behaviour++; + // fallthrough + case ENNB_BEHAVIOUR_5: + if (!(gSaveContext.eventInf[4] & 4)) { + gSaveContext.save.time = CLOCK_TIME(8, 0); + Sram_IncrementDay(); + } else { + func_800FE658(120.0f); + } + + this->behaviour++; + play->nextEntrance = ENTRANCE(STOCK_POT_INN, 2); + gSaveContext.nextCutsceneIndex = 0; + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_02; + gSaveContext.nextTransitionType = TRANS_TYPE_06; + gSaveContext.eventInf[4] |= 8; + break; + } + + return ret; +} + +u8* func_80BC045C(EnNb* this, PlayState* play) { + if (gSaveContext.eventInf[4] & 8) { + this->msgEventCallback = func_80BC01DC; + return D_80BC1464; + } else if (this->scheduleResult == EN_NB_SCH_2) { + this->msgEventCallback = func_80BC00AC; + return D_80BC1574; + } else if (Player_GetMask(play) == PLAYER_MASK_KAFEIS_MASK) { + return D_80BC15C8; + } else { + this->msgEventCallback = func_80BC01DC; + return D_80BC1464; + } +} + +s32 func_80BC04FC(EnNb* this, PlayState* play) { + s32 ret = false; + + if (this->stateFlags & (EN_NB_FLAG_1 | EN_NB_FLAG_2 | EN_NB_FLAG_4)) { + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + this->stateFlags |= EN_NB_FLAG_20; + SubS_UpdateFlags(&this->stateFlags, EN_NB_FLAG_NONE, EN_NB_FLAG_1 | EN_NB_FLAG_2 | EN_NB_FLAG_4); + this->behaviour = ENNB_BEHAVIOUR_0; + this->msgEventCallback = NULL; + this->actor.child = this->unk_1E8; + this->msgEventScript = func_80BC045C(this, play); + this->stateFlags |= EN_NB_FLAG_20; + this->actionFunc = func_80BC0EAC; + ret = true; + } + } + return ret; +} + +void func_80BC05A8(EnNb* this, PlayState* play) { + Player* player = GET_PLAYER(play); + TextState talkState = Message_GetState(&play->msgCtx); + u16 textId = play->msgCtx.currentTextId; + + if ((&this->actor == player->targetActor) && ((textId < 0xFF) || (textId > 0x200)) && (talkState == TEXT_STATE_3) && + (this->prevTalkState == TEXT_STATE_3)) { + if ((play->state.frames % 3) == 0) { + if (this->unk_26C == 120.0f) { + this->unk_26C = 0.0f; + } else { + this->unk_26C = 120.0f; + } + } + } else { + this->unk_26C = 0.0f; + } + + Math_SmoothStepToF(&this->unk_270, this->unk_26C, 0.8f, 40.0f, 10.0f); + Matrix_Translate(this->unk_270, 0.0f, 0.0f, MTXMODE_APPLY); + this->prevTalkState = talkState; +} + +void func_80BC06C4(EnNb* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + Player* player; + + Math_Vec3f_Copy(&sp40, &this->unk_1E8->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + Math_ApproachS(&this->headRotY, Math_Vec3f_Yaw(&sp34, &sp40) - this->actor.shape.rot.y, 4, 0x2AA8); + + this->headRotY = CLAMP(this->headRotY, -0x1FFE, 0x1FFE); + + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + + if (this->unk_1E8->id == ACTOR_PLAYER) { + player = (Player*)this->unk_1E8; + + sp40.y = player->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_1E8->focus.pos); + } + + Math_ApproachS(&this->headRotZ, Math_Vec3f_Pitch(&sp34, &sp40), 4, 0x2AA8); + + this->headRotZ = CLAMP(this->headRotZ, -0x1554, 0x1554); +} + +void func_80BC0800(EnNb* this) { + if (this->stateFlags & EN_NB_FLAG_20) { + if ((this->unk_1E8 != NULL) && (this->unk_1E8->update != NULL)) { + if (DECR(this->unk_282) == 0) { + func_80BC06C4(this); + this->stateFlags &= ~EN_NB_FLAG_400; + this->stateFlags |= EN_NB_FLAG_100; + return; + } + } + } + + if (this->stateFlags & EN_NB_FLAG_100) { + this->stateFlags &= ~EN_NB_FLAG_100; + this->headRotZ = 0; + this->headRotY = 0; + this->unk_282 = 20; + } else if (DECR(this->unk_282) == 0) { + this->stateFlags |= EN_NB_FLAG_400; + } +} + +// Related to both stories? +void func_80BC08E0(EnNb* this, PlayState* play) { + if (this->unk_284 == 0) { + EnNb_ChangeAnim(this, EN_NB_ANIM_TALK_ONCE); + this->stateFlags |= EN_NB_FLAG_400; + this->unk_284++; + } else if ((this->unk_284 == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + EnNb_ChangeAnim(this, EN_NB_ANIM_1); + this->stateFlags &= ~EN_NB_FLAG_400; + this->unk_284++; + } +} + +void func_80BC0978(EnNb* this, PlayState* play) { + if (this->unk_284 == 0) { + EnNb_ChangeAnim(this, EN_NB_ANIM_RELIEVED); + this->stateFlags &= ~EN_NB_FLAG_20; + this->stateFlags |= EN_NB_FLAG_400; + this->unk_284++; + } else if ((this->unk_284 == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + EnNb_ChangeAnim(this, EN_NB_ANIM_TALK_LOOP); + this->stateFlags &= ~EN_NB_FLAG_400; + this->unk_284++; + } +} + +s32 func_80BC0A18(EnNb* this, PlayState* play) { + Player* player = GET_PLAYER(play); + u16 currentTextId = play->msgCtx.currentTextId; + + if (player->stateFlags1 & PLAYER_STATE1_40) { + this->stateFlags |= EN_NB_FLAG_80; + + if (this->textId != currentTextId) { + switch (currentTextId) { + case 0x28CF: + this->stateFlags |= EN_NB_FLAG_20; + EnNb_ChangeAnim(this, EN_NB_ANIM_TALK_LOOP); + break; + + case 0x2904: // "You want to hear the carnival of time story? ..." + case 0x290B: // "You want to hear the four giants story? ..." + this->unk_18C = func_80BC08E0; + this->unk_284 = 0; + break; + + case 0x28CD: + this->unk_18C = func_80BC0978; + this->unk_284 = 0; + break; + + case 0x28CB: // "I told you I already ate!" + EnNb_ChangeAnim(this, EN_NB_ANIM_ANGRY); + break; + + case 0x28C7: + case 0x2901: + case 0x2902: + case 0x2906: + case 0x290D: + case 0x2912: + EnNb_ChangeAnim(this, EN_NB_ANIM_TALK_LOOP); + break; + } + } + + this->textId = currentTextId; + } else if (this->stateFlags & EN_NB_FLAG_80) { + this->unk_18C = NULL; + this->textId = 0; + this->stateFlags &= ~EN_NB_FLAG_80; + EnNb_ChangeAnim(this, EN_NB_ANIM_1); + } + + if (this->unk_18C != NULL) { + this->unk_18C(this, play); + } + + return 0; +} + +s32 func_80BC0B98(EnNb* this, PlayState* play, ScheduleOutput* scheduleOutput) { + s32 success = false; + + if (EnNb_FindActor(this, play, ACTORCAT_NPC, ACTOR_EN_AN) != NULL) { + SubS_UpdateFlags(&this->stateFlags, EN_NB_FLAG_1 | EN_NB_FLAG_2, EN_NB_FLAG_1 | EN_NB_FLAG_2 | EN_NB_FLAG_4); + this->stateFlags |= EN_NB_FLAG_20; + EnNb_ChangeAnim(this, EN_NB_ANIM_0); + success = true; + } + + return success; +} + +s32 func_80BC0C0C(EnNb* this, PlayState* play, ScheduleOutput* scheduleOutput) { + if (!(gSaveContext.eventInf[4] & 8)) { + SubS_UpdateFlags(&this->stateFlags, EN_NB_FLAG_1 | EN_NB_FLAG_2, EN_NB_FLAG_1 | EN_NB_FLAG_2 | EN_NB_FLAG_4); + } else { + SubS_UpdateFlags(&this->stateFlags, EN_NB_FLAG_4, EN_NB_FLAG_1 | EN_NB_FLAG_2 | EN_NB_FLAG_4); + } + EnNb_ChangeAnim(this, EN_NB_ANIM_0); + + return true; +} + +s32 EnNb_ProcessScheduleOutput(EnNb* this, PlayState* play, ScheduleOutput* scheduleOutput) { + s32 success; + + this->actor.flags |= ACTOR_FLAG_1; + this->actor.targetMode = 0; + this->stateFlags = EN_NB_FLAG_NONE; + this->unk_274 = 40.0f; + + switch (scheduleOutput->result) { + default: + success = false; + break; + + case EN_NB_SCH_1: + case EN_NB_SCH_3: + case EN_NB_SCH_4: + success = func_80BC0C0C(this, play, scheduleOutput); + break; + + case EN_NB_SCH_2: + success = func_80BC0B98(this, play, scheduleOutput); + break; + } + return success; +} + +s32 func_80BC0D08(EnNb* this, PlayState* play) { + return 0; +} + +void EnNb_HandleSchedule(EnNb* this, PlayState* play) { + if ((this->scheduleResult == EN_NB_SCH_1) || (this->scheduleResult == EN_NB_SCH_2) || + (this->scheduleResult == EN_NB_SCH_3) || (this->scheduleResult == EN_NB_SCH_4)) { + func_80BC0D08(this, play); + } + + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); +} + +void EnNb_FollowSchedule(EnNb* this, PlayState* play) { + ScheduleOutput scheduleOutput; + + this->timePathTimeSpeed = REG(15) + ((void)0, gSaveContext.save.daySpeed); + + if (gSaveContext.eventInf[4] & 8) { + scheduleOutput.result = EN_NB_SCH_1; + EnNb_ProcessScheduleOutput(this, play, &scheduleOutput); + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } else if (!Schedule_RunScript(play, sScheduleScript, &scheduleOutput) || + ((this->scheduleResult != scheduleOutput.result) && + !EnNb_ProcessScheduleOutput(this, play, &scheduleOutput))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + scheduleOutput.result = EN_NB_SCH_NONE; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } + + this->scheduleResult = scheduleOutput.result; + this->unk_1E8 = func_80BBFF90(this, play); + EnNb_HandleSchedule(this, play); +} + +void func_80BC0EAC(EnNb* this, PlayState* play) { + if (func_8010BF58(&this->actor, play, this->msgEventScript, this->msgEventCallback, &this->msgEventArg4)) { + if (gSaveContext.eventInf[4] & 8) { + gSaveContext.eventInf[4] &= (u8)~4; + gSaveContext.eventInf[4] &= (u8)~8; + } + + SubS_UpdateFlags(&this->stateFlags, EN_NB_FLAG_1 | EN_NB_FLAG_2, EN_NB_FLAG_1 | EN_NB_FLAG_2 | EN_NB_FLAG_4); + if (this->scheduleResult != EN_NB_SCH_2) { + this->stateFlags &= ~EN_NB_FLAG_20; + } + + this->actor.child = NULL; + this->stateFlags |= EN_NB_FLAG_400; + this->unk_282 = 20; + this->msgEventArg4 = 0; + this->actionFunc = EnNb_FollowSchedule; + } +} + +void EnNb_Init(Actor* thisx, PlayState* play) { + EnNb* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + SkelAnime_InitFlex(play, &this->skelAnime, &gNbSkel, NULL, this->jointTable, this->morphTable, NB_LIMB_MAX); + + this->animIndex = EN_NB_ANIM_INVALID; + EnNb_ChangeAnim(this, EN_NB_ANIM_0); + + Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + Actor_SetScale(&this->actor, 0.01f); + this->stateFlags = EN_NB_FLAG_NONE; + + if (gSaveContext.eventInf[4] & 8) { + SubS_UpdateFlags(&this->stateFlags, EN_NB_FLAG_4, EN_NB_FLAG_1 | EN_NB_FLAG_2 | EN_NB_FLAG_4); + } else { + gSaveContext.eventInf[4] &= (u8)~4; + gSaveContext.eventInf[4] &= (u8)~8; + } + + this->actionFunc = EnNb_FollowSchedule; + this->actionFunc(this, play); +} + +void EnNb_Destroy(Actor* thisx, PlayState* play) { + EnNb* this = THIS; + + Collider_DestroyCylinder(play, &this->collider); + play->interfaceCtx.storyState = 3; +} + +void EnNb_Update(Actor* thisx, PlayState* play) { + EnNb* this = THIS; + + func_80BC04FC(this, play); + this->actionFunc(this, play); + func_80BC0A18(this, play); + + if (this->scheduleResult != EN_NB_SCH_NONE) { + EnNb_UpdateSkelAnime(this); + func_80BC0800(this); + if (Actor_IsFacingPlayer(&this->actor, 0x38E0)) { + func_8013C964(&this->actor, play, this->unk_274, 30.0f, ITEM_OCARINA, + this->stateFlags & (EN_NB_FLAG_1 | EN_NB_FLAG_2 | EN_NB_FLAG_4)); + } + func_80BBFF24(this, play); + } +} + +s32 EnNb_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnNb* this = THIS; + + if (limbIndex == NB_LIMB_HEAD) { + func_80BC05A8(this, play); + } + + return false; +} + +void EnNb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnNb* this = THIS; + Vec3f focusTarget; + + if ((ActorCutscene_GetCurrentIndex() == -1) && (limbIndex == NB_LIMB_HEAD)) { + Matrix_MultVec3f(&gZeroVec3f, &focusTarget); + Math_ApproachF(&thisx->focus.pos.x, focusTarget.x, 0.6f, 10000.0f); + Math_ApproachF(&thisx->focus.pos.y, focusTarget.y, 0.6f, 10000.0f); + Math_ApproachF(&thisx->focus.pos.z, focusTarget.z, 0.6f, 10000.0f); + Math_Vec3s_Copy(&thisx->focus.rot, &thisx->world.rot); + } +} + +void EnNb_TransformLimbDraw(PlayState* play, s32 limbIndex, Actor* thisx) { + EnNb* this = THIS; + s32 stepRot; + s32 overrideRot; + + if (!(this->stateFlags & EN_NB_FLAG_400)) { + overrideRot = false; + if (this->stateFlags & EN_NB_FLAG_100) { + overrideRot = true; + stepRot = true; + } else { + stepRot = true; + } + } else { + overrideRot = false; + stepRot = false; + } + + if (limbIndex == NB_LIMB_HEAD) { + SubS_UpdateLimb(this->headRotZ + 0x4000, this->headRotY + this->actor.shape.rot.y + 0x4000, + &this->headComputedPos, &this->headComputedRot, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->headComputedPos.x, this->headComputedPos.y, this->headComputedPos.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->headComputedRot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->headComputedRot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->headComputedRot.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnNb_Draw(Actor* thisx, PlayState* play) { + EnNb* this = THIS; + + if (this->scheduleResult != EN_NB_SCH_NONE) { + func_8012C5B0(play->state.gfxCtx); + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnNb_OverrideLimbDraw, EnNb_PostLimbDraw, + EnNb_TransformLimbDraw, &this->actor); + } +} diff --git a/src/overlays/actors/ovl_En_Nb/z_en_nb.h b/src/overlays/actors/ovl_En_Nb/z_en_nb.h index b094456d92..f11464c794 100644 --- a/src/overlays/actors/ovl_En_Nb/z_en_nb.h +++ b/src/overlays/actors/ovl_En_Nb/z_en_nb.h @@ -2,18 +2,57 @@ #define Z_EN_NB_H #include "global.h" +#include "objects/object_nb/object_nb.h" struct EnNb; typedef void (*EnNbActionFunc)(struct EnNb*, PlayState*); +typedef s32 (*EnNbUnkFunc)(Actor*, PlayState*); +typedef void (*EnNbUnkFunc2)(struct EnNb*, PlayState*); + +typedef enum EnNbAnimation { + /* -1 */ EN_NB_ANIM_INVALID = -1, + /* 0 */ EN_NB_ANIM_0, + /* 1 */ EN_NB_ANIM_1, + /* 2 */ EN_NB_ANIM_TALK_ONCE, + /* 3 */ EN_NB_ANIM_TALK_LOOP, + /* 4 */ EN_NB_ANIM_ANGRY, + /* 5 */ EN_NB_ANIM_RELIEVED, +} EnNbAnimation; typedef struct EnNb { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x44]; + /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ EnNbActionFunc actionFunc; - /* 0x18C */ char unk_18C[0x110]; + /* 0x18C */ EnNbUnkFunc2 unk_18C; + /* 0x190 */ ColliderCylinder collider; + /* 0x1DC */ u8 scheduleResult; + /* 0x1E0 */ u8* msgEventScript; + /* 0x1E4 */ s32 msgEventArg4; + /* 0x1E8 */ Actor* unk_1E8; + /* 0x1EC */ UNK_TYPE1 unk_1EC[4]; + /* 0x1F0 */ Vec3f headComputedPos; + /* 0x1FC */ Vec3s headComputedRot; + /* 0x202 */ Vec3s jointTable[NB_LIMB_MAX]; + /* 0x232 */ Vec3s morphTable[NB_LIMB_MAX]; + /* 0x262 */ u16 stateFlags; + /* 0x264 */ u16 textId; + /* 0x268 */ f32 animPlaySpeed; + /* 0x26C */ f32 unk_26C; // Related to unk_270 + /* 0x270 */ f32 unk_270; // headDisplacement? controls how much the upper part of the head moves when she talks + /* 0x274 */ f32 unk_274; + /* 0x278 */ UNK_TYPE1 unk_278[4]; + /* 0x27C */ s16 headRotZ; // Slightly rotates head when talking + /* 0x27E */ s16 headRotY; + /* 0x280 */ s16 timePathTimeSpeed; + /* 0x282 */ s16 unk_282; // timer? + /* 0x284 */ s16 unk_284; // storyState? + /* 0x286 */ s16 storyTimer; + /* 0x288 */ s16 behaviour; + /* 0x28C */ EnNbUnkFunc msgEventCallback; + /* 0x290 */ EnNbAnimation animIndex; + /* 0x294 */ UNK_TYPE1 unk_294[4]; + /* 0x294 */ TextState prevTalkState; } EnNb; // size = 0x29C -extern const ActorInit En_Nb_InitVars; - #endif // Z_EN_NB_H diff --git a/src/overlays/actors/ovl_En_Test7/z_en_test7.c b/src/overlays/actors/ovl_En_Test7/z_en_test7.c index 22e4c70b14..e5a646191f 100644 --- a/src/overlays/actors/ovl_En_Test7/z_en_test7.c +++ b/src/overlays/actors/ovl_En_Test7/z_en_test7.c @@ -594,11 +594,11 @@ void func_80AF2030(EnTest7* this, PlayState* play) { subCam->fov = ((subCam->fov - this->subCamFov) * sp1C) + this->subCamFov; if (this->unk_1E54 >= 100) { - MREG(64) = 1; - MREG(65) = 255; - MREG(66) = 255; - MREG(67) = 255; - MREG(68) = 255; + R_PLAY_FILL_SCREEN_ON = true; + R_PLAY_FILL_SCREEN_R = 255; + R_PLAY_FILL_SCREEN_G = 255; + R_PLAY_FILL_SCREEN_B = 255; + R_PLAY_FILL_SCREEN_ALPHA = 255; play->unk_18844 = 0; this->unk_144 &= ~4; func_80AF082C(this, func_80AF21E8); @@ -612,13 +612,13 @@ void func_80AF21E8(EnTest7* this, PlayState* play) { Color_RGB8 sp24 = { 64, 0, 0 }; Color_RGB8 sp20 = { 220, 220, 255 }; - if (MREG(64) != 0) { + if (R_PLAY_FILL_SCREEN_ON) { Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WARP_WING_VANISH); - MREG(64) = 0; - MREG(65) = 0; - MREG(66) = 0; - MREG(67) = 0; - MREG(68) = 0; + R_PLAY_FILL_SCREEN_ON = false; + R_PLAY_FILL_SCREEN_R = 0; + R_PLAY_FILL_SCREEN_G = 0; + R_PLAY_FILL_SCREEN_B = 0; + R_PLAY_FILL_SCREEN_ALPHA = 0; } sp1C = 1.0f - (sp2C / 10.0f); diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.c b/src/overlays/actors/ovl_En_Tru/z_en_tru.c index 3e619cac39..5fec69f449 100644 --- a/src/overlays/actors/ovl_En_Tru/z_en_tru.c +++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.c @@ -955,7 +955,7 @@ s32 func_80A87B48(Actor* thisx, PlayState* play) { sp4C.z = 40.0f; Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, sp3E, &sp4C, &sp40); func_80A85620(this->unk_394, &sp40, 2.0f, 0.08f, 60.0f); - func_8016A268(&play->state, 1, 160, 160, 160, 0); + Play_FillScreen(&play->state, true, 160, 160, 160, 0); this->unk_370 = 20; this->unk_372 = 10; this->unk_364++; @@ -967,7 +967,7 @@ s32 func_80A87B48(Actor* thisx, PlayState* play) { case 2: if (DECR(this->unk_370) != 0) { - MREG(68) = 255.0f - ((fabsf(10.0f - this->unk_370) / 10) * 255.0f); + R_PLAY_FILL_SCREEN_ALPHA = 255.0f - ((fabsf(10.0f - this->unk_370) / 10) * 255.0f); if (this->unk_370 == 9) { this->actor.shape.shadowDraw = NULL; this->unk_34E |= (0x200 | 0x8); @@ -978,7 +978,7 @@ s32 func_80A87B48(Actor* thisx, PlayState* play) { EnTru_ChangeAnim(this, KOUME_ANIM_HOVER1); } } else { - MREG(64) = 0; + R_PLAY_FILL_SCREEN_ON = false; ret = true; } break; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 647cc3d79a..695c275ab2 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -3038,7 +3038,7 @@ 0x8016A0AC:("Play_IsUnderwater",), 0x8016A168:("Play_IsDebugCamEnabled",), 0x8016A178:("Play_AssignPlayerActorCsIdsFromScene",), - 0x8016A268:("func_8016A268",), + 0x8016A268:("Play_FillScreen",), 0x8016A2C8:("Play_Init",), 0x8016AC10:("func_8016AC10",), 0x8016AE1C:("func_8016AE1C",), @@ -15451,9 +15451,9 @@ 0x80BBF5F0:("EnSGoro_DrawUnrolled",), 0x80BBF6BC:("EnSGoro_DrawRolledUp",), 0x80BBF7BC:("EnSGoro_Draw",), - 0x80BBFDB0:("func_80BBFDB0",), - 0x80BBFE60:("func_80BBFE60",), - 0x80BBFE8C:("func_80BBFE8C",), + 0x80BBFDB0:("EnNb_FindActor",), + 0x80BBFE60:("EnNb_UpdateSkelAnime",), + 0x80BBFE8C:("EnNb_ChangeAnim",), 0x80BBFF24:("func_80BBFF24",), 0x80BBFF90:("func_80BBFF90",), 0x80BBFFD4:("func_80BBFFD4",), @@ -15470,17 +15470,17 @@ 0x80BC0A18:("func_80BC0A18",), 0x80BC0B98:("func_80BC0B98",), 0x80BC0C0C:("func_80BC0C0C",), - 0x80BC0C80:("func_80BC0C80",), + 0x80BC0C80:("EnNb_ProcessScheduleOutput",), 0x80BC0D08:("func_80BC0D08",), - 0x80BC0D1C:("func_80BC0D1C",), - 0x80BC0D84:("func_80BC0D84",), + 0x80BC0D1C:("EnNb_HandleSchedule",), + 0x80BC0D84:("EnNb_FollowSchedule",), 0x80BC0EAC:("func_80BC0EAC",), 0x80BC0F60:("EnNb_Init",), 0x80BC1080:("EnNb_Destroy",), 0x80BC10C0:("EnNb_Update",), - 0x80BC1174:("func_80BC1174",), - 0x80BC11B4:("func_80BC11B4",), - 0x80BC1278:("func_80BC1278",), + 0x80BC1174:("EnNb_OverrideLimbDraw",), + 0x80BC11B4:("EnNb_PostLimbDraw",), + 0x80BC1278:("EnNb_TransformLimbDraw",), 0x80BC1374:("EnNb_Draw",), 0x80BC1900:("func_80BC1900",), 0x80BC192C:("func_80BC192C",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index ee037b02a1..d5b33c745f 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -15626,7 +15626,7 @@ 0x80BC15D0:("En_Nb_InitVars","UNK_TYPE1","",0x1), 0x80BC15F0:("D_80BC15F0","UNK_TYPE1","",0x1), 0x80BC161C:("D_80BC161C","UNK_TYPE1","",0x1), - 0x80BC1628:("D_80BC1628","UNK_TYPE1","",0x1), + 0x80BC1628:("sAnimationInfo","UNK_TYPE1","",0x1), 0x80BC1690:("jtbl_80BC1690","UNK_PTR","",0x4), 0x80BC16B8:("jtbl_80BC16B8","UNK_PTR","",0x4), 0x80BC16D0:("jtbl_80BC16D0","UNK_PTR","",0x4), diff --git a/tools/namefixer.py b/tools/namefixer.py index eae3efd941..a60e583115 100755 --- a/tools/namefixer.py +++ b/tools/namefixer.py @@ -739,6 +739,8 @@ wordReplace = { "globalCtx->envCtx.unk_C3": "play->envCtx.lightSettingOverride", "globalCtx->envCtx.unk_DC": "play->envCtx.lightBlend", "globalCtx->interfaceCtx.unk_21E": "play->interfaceCtx.bButtonDoAction", + "play->interfaceCtx.unk_31A": "play->interfaceCtx.storyState", + "play->interfaceCtx.unk_31B": "play->interfaceCtx.storyType", # "play->actorCtx.flags": "play->actorCtx.sceneFlags", # "play->actorCtx.unk5": "play->actorCtx.flags", diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 1678b9186d..19f625dbf5 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -2552,7 +2552,7 @@ asm/non_matchings/code/z_play/func_8016A02C.s,func_8016A02C,0x8016A02C,0x20 asm/non_matchings/code/z_play/Play_IsUnderwater.s,Play_IsUnderwater,0x8016A0AC,0x2F asm/non_matchings/code/z_play/Play_IsDebugCamEnabled.s,Play_IsDebugCamEnabled,0x8016A168,0x4 asm/non_matchings/code/z_play/func_8016A178.s,func_8016A178,0x8016A178,0x3C -asm/non_matchings/code/z_play/func_8016A268.s,func_8016A268,0x8016A268,0x18 +asm/non_matchings/code/z_play/Play_FillScreen.s,Play_FillScreen,0x8016A268,0x18 asm/non_matchings/code/z_play/Play_Init.s,Play_Init,0x8016A2C8,0x252 asm/non_matchings/code/z_play_hireso/func_8016AC10.s,func_8016AC10,0x8016AC10,0x83 asm/non_matchings/code/z_play_hireso/func_8016AE1C.s,func_8016AE1C,0x8016AE1C,0x117 diff --git a/undefined_syms.txt b/undefined_syms.txt index 073840341b..e813cc9d32 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -1214,10 +1214,6 @@ D_060105DC = 0x060105DC; D_06019B88 = 0x06019B88; D_0601D518 = 0x0601D518; -// ovl_En_Nb - -D_06008C40 = 0x06008C40; - // ovl_En_Neo_Reeba D_060001E4 = 0x060001E4;