diff --git a/asm/non_matchings/code/z_player_lib/func_8008EEAC.s b/asm/non_matchings/code/z_player_lib/func_8008EEAC.s index 9ae2412a94..916cadde69 100644 --- a/asm/non_matchings/code/z_player_lib/func_8008EEAC.s +++ b/asm/non_matchings/code/z_player_lib/func_8008EEAC.s @@ -33,9 +33,3 @@ glabel func_8008EEAC /* B060C8 8008EF28 03E00008 */ jr $ra /* B060CC 8008EF2C 00000000 */ nop -/* B060D0 8008EF30 8C831C44 */ lw $v1, 0x1c44($a0) -/* B060D4 8008EF34 3C010080 */ lui $at, 0x80 -/* B060D8 8008EF38 8C62067C */ lw $v0, 0x67c($v1) -/* B060DC 8008EF3C 03E00008 */ jr $ra -/* B060E0 8008EF40 00411024 */ and $v0, $v0, $at - diff --git a/asm/non_matchings/code/z_player_lib/func_8008EF40.s b/asm/non_matchings/code/z_player_lib/func_8008EF40.s new file mode 100644 index 0000000000..dd539f43db --- /dev/null +++ b/asm/non_matchings/code/z_player_lib/func_8008EF40.s @@ -0,0 +1,6 @@ +glabel func_8008EF40 +/* B060D0 8008EF30 8C831C44 */ lw $v1, 0x1c44($a0) +/* B060D4 8008EF34 3C010080 */ lui $at, 0x80 +/* B060D8 8008EF38 8C62067C */ lw $v0, 0x67c($v1) +/* B060DC 8008EF3C 03E00008 */ jr $ra +/* B060E0 8008EF40 00411024 */ and $v0, $v0, $at diff --git a/include/functions.h b/include/functions.h index b9d39aec67..9f07bf50ba 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1114,7 +1114,7 @@ s32 func_8008F2F8(GlobalContext*); // ? func_8008FCC8(?); // ? func_800902F0(?); // ? func_80090440(?); -u8 func_80090480(GlobalContext* globalCtx, Collider* collider, UNK_PTR a2, Vec3f* a3, Vec3f* a4); +u8 func_80090480(GlobalContext* globalCtx, Collider* collider, Struct_80090480_arg2* arg2, Vec3f* arg3, Vec3f* arg4); // ? func_80090604(?); // ? func_800906D4(?); // ? func_800907E4(?); diff --git a/include/z64.h b/include/z64.h index b1eb8a8880..71e7b9257e 100644 --- a/include/z64.h +++ b/include/z64.h @@ -162,7 +162,7 @@ typedef struct { /* 0x1368 */ RespawnData respawn[3]; // "restart_data" /* 0x13BC */ char unk_13BC[0x0008]; /* 0x13C4 */ s16 dogParams; - /* 0x13C6 */ char unk_13C6[0x0001]; + /* 0x13C6 */ u8 unk_13C6; /* 0x13C7 */ u8 unk_13C7; /* 0x13C8 */ s16 nayrusLoveTimer; /* 0x13CA */ char unk_13CA[0x0002]; diff --git a/include/z64actor.h b/include/z64actor.h index c912a26c51..aaf65f15f9 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -3,6 +3,7 @@ #include #include +#include #define ACTOR_NUMBER_MAX 200 #define INVISIBLE_ACTOR_MAX 20 @@ -199,30 +200,52 @@ typedef struct { } DynaPolyActor; // size = 0x164 typedef struct { + /* 0x00 */ s32 active; + /* 0x04 */ Vec3f tip; + /* 0x10 */ Vec3f base; +} Struct_80090480_arg2; + +struct Player; +typedef void (*PlayerActionFunc)(struct Player*, struct GlobalContext*); + +typedef struct Player { /* 0x0000 */ Actor actor; /* 0x014C */ s8 currentTunic; /* 0x014D */ s8 currentSword; /* 0x014E */ s8 currentShield; /* 0x014F */ s8 currentBoots; - /* 0x0150 */ s8 unk_150; - /* 0x0151 */ s8 unk_151; + /* 0x0150 */ s8 heldItemCButtonIdx; + /* 0x0151 */ s8 heldItemActionParam; /* 0x0152 */ s8 unk_152; /* 0x0153 */ s8 unk_153; /* 0x0154 */ s8 unk_154; - /* 0x0155 */ char unk_155[0x008]; + /* 0x0155 */ char unk_155[0x003]; + /* 0x0158 */ s8 unk_158; + /* 0x0159 */ char unk_159[0x002]; + /* 0x015B */ u8 unk_15B; + /* 0x015C */ u8 unk_15C; /* 0x015D */ u8 unk_15D; /* 0x015E */ u8 unk_15E; /* 0x015F */ u8 currentMask; - /* 0x0160 */ char unk_160[0x050]; - /* 0x01B0 */ u32 unk_1B0; + /* 0x0160 */ UNK_PTR unk_160; + /* 0x0164 */ UNK_PTR unk_164; + /* 0x0168 */ UNK_PTR unk_168; + /* 0x016C */ UNK_PTR unk_16C; + /* 0x0170 */ u8 unk_170; + /* 0x0171 */ char unk_171[0x023]; + /* 0x0194 */ OSMesgQueue unk_194; + /* 0x01AC */ char unk_1AC[0x004]; + /* 0x01B0 */ void* getItemModel; // Pointer to the space where the get item model is allocated /* 0x01B4 */ SkelAnime skelAnime; /* 0x01F8 */ char unk_1F8[0x1B4]; /* 0x03AC */ Actor* heldActor; /* 0x03B0 */ char unk_3B0[0x084]; /* 0x0434 */ u8 getItemId; + /* 0x0435 */ char unk_435[0x001]; /* 0x0436 */ u16 getItemDirection; /* 0x0438 */ Actor* interactRangeActor; /* 0x043C */ s8 unk_43C; + /* 0x043D */ char unk_43D[0x003]; /* 0x0440 */ Actor* rideActor; /* 0x0444 */ u8 action; /* 0x0445 */ char unk_445[0x003]; @@ -231,55 +254,98 @@ typedef struct { /* 0x0450 */ Vec3f unk_450; /* 0x045C */ char unk_45C[0x00E]; /* 0x046A */ u16 unk_46A; - /* 0x046C */ char unk_46C[0x6E]; + /* 0x046C */ char unk_46C[0x06E]; /* 0x04DA */ s16 unk_4DA; - /* 0x04DC */ char unk_4DC[0x188]; + /* 0x04DC */ char unk_4DC[0x008]; + /* 0x04E4 */ Collider unk_4E4; // TODO determine type + /* 0x04FC */ char unk_4FC[0x068]; + /* 0x0564 */ Collider unk_564; // TODO determine type + /* 0x057C */ char unk_57C[0x07C]; + /* 0x05F8 */ u8 unk_5F8; + /* 0x05F9 */ char unk_5F9[0x06B]; /* 0x0664 */ Actor* unk_664; /* 0x0668 */ char unk_668[0x004]; /* 0x066C */ s32 unk_66C; - /* 0x0670 */ char unk_670[0x00C]; + /* 0x0670 */ u32 swordEffectId; + /* 0x0674 */ PlayerActionFunc actionFunc; + /* 0x0678 */ u32 ageProperties; /* 0x067C */ u32 stateFlags1; /* 0x0680 */ u32 stateFlags2; - /* 0x0684 */ char unk_684[0x008]; - /* 0x068C */ Actor* unk_68C; - /* 0x0690 */ char unk_690[0x002]; + /* 0x0684 */ s32 unk_684; + /* 0x0688 */ char unk_688[0x004]; + /* 0x068C */ Actor* navi; + /* 0x0690 */ u16 naviMessageId; /* 0x0692 */ u8 unk_692; /* 0x0693 */ s8 exchangeItemId; - /* 0x0694 */ Actor* unk_694; - /* 0x0698 */ f32 unk_698; + /* 0x0694 */ Actor* naviTargetActor; + /* 0x0698 */ f32 targetActorDistance; /* 0x069C */ char unk_69C[0x008]; /* 0x06A4 */ f32 unk_6A4; /* 0x06A8 */ Actor* unk_6A8; /* 0x06AC */ char unk_6AC[0x001]; /* 0x06AD */ u8 unk_6AD; - /* 0x06AE */ char unk_6AE[0x1A]; + /* 0x06AE */ char unk_6AE[0x2]; + /* 0x06B0 */ s16 unk_6B0; + /* 0x06B2 */ char unk_6B4[0x4]; + /* 0x06B6 */ Vec3s unk_6B6; + /* 0x06BC */ s16 unk_6BC; + /* 0x06BE */ s16 unk_6BE; + /* 0x06C0 */ s16 unk_6C0; + /* 0x06C2 */ s16 unk_6C2; + /* 0x06C4 */ f32 unk_6C4; /* 0x06C8 */ SkelAnime skelAnime2; /* 0x070C */ char unk_70C[0x128]; /* 0x0834 */ s16 unk_834; /* 0x0836 */ char unk_836[0x002]; - /* 0x0838 */ f32 unk_838; - /* 0x083C */ s16 unk_83C; - /* 0x083E */ char unk_83E[0x004]; + /* 0x0838 */ f32 linearVelocity; + /* 0x083C */ s16 currentYaw; + /* 0x083E */ s16 targetYaw; + /* 0x0840 */ u16 unk_840; /* 0x0842 */ s8 swordAnimation; /* 0x0843 */ s8 swordState; /* 0x0844 */ u8 unk_844; /* 0x0845 */ u8 unk_845; /* 0x0846 */ u8 unk_846; /* 0x0847 */ char unk_847[0x004]; - /* 0x084B */ s8 unk_84B[UNK_SIZE]; - /* 0x084C */ char unk_84C[0x003]; + /* 0x084B */ s8 unk_84B[4]; /* 0x084F */ s8 unk_84F; /* 0x0850 */ s16 unk_850; - /* 0x0852 */ char unk_852[0x04E]; + /* 0x0852 */ char unk_852[0x00A]; + /* 0x085C */ f32 stickLength; + /* 0x0860 */ s16 stickFlameTimer; + /* 0x0862 */ s8 overheadItemId; + /* 0x0863 */ char unk_863[0x021]; + + /* 0x0884 */ f32 ledgeDistance; // The distance from link to a grabbable ledge + // Only updates if pushing against a wall with a grabbable ledge above + // If the ledge is too high to grab the value is 399.96f + + /* 0x0888 */ f32 wallDistance; // Only updates if pushing against a wall with a grabbable ledge above + /* 0x088C */ char unk_88C[0x008]; + /* 0x0894 */ s16 dropY; // Truncated copy of y position that does not update while falling + /* 0x0896 */ s16 fallY; // The truncated y distance link has moved in that frame, positive is down, negative is up + /* 0x0898 */ char unk_898[0x008]; /* 0x08A0 */ u8 unk_8A0; /* 0x08A1 */ u8 unk_8A1; /* 0x08A2 */ u16 unk_8A2; /* 0x08A4 */ f32 unk_8A4; /* 0x08A8 */ f32 unk_8A8; - /* 0x08AC */ char unk_8AC[0x174]; + /* 0x08AC */ f32 fanWindSpeed; + /* 0x08B0 */ s16 fanWindDirection; + /* 0x08B2 */ char unk_8B2[0x002]; + /* 0x08B4 */ Struct_80090480_arg2 swordDimensions; // Trail active, tip, base? + /* 0x08D0 */ Struct_80090480_arg2 unk_8D0; + /* 0x08EC */ Struct_80090480_arg2 unk_8EC; + /* 0x0908 */ char unk_908[0x118]; /* 0x0A20 */ MtxF mf_A20; - /* 0x0A60 */ char unk_A60[0x18]; - /* 0x0A78 */ s8 unk_A78; + /* 0x0A60 */ char unk_A60[0x08]; + /* 0x0A68 */ s8 unk_A68; + /* 0x0A69 */ char unk_A6A[0x0F]; + + /* 0x0A78 */ s8 invincibilityTimer; // Take no damage if this value is nonzero + // Positive induces red flashing, negative does not + // Counts towards zero each frame + /* 0x0A79 */ char unk_A79[0x1B]; } Player; // size = 0xA94 diff --git a/src/code/code_800430A0.c b/src/code/code_800430A0.c index 344c4ddb51..0c15155b85 100644 --- a/src/code/code_800430A0.c +++ b/src/code/code_800430A0.c @@ -8,7 +8,7 @@ void func_800432A0(CollisionContext* colCtx, u32 floorPolySource, Actor* actor) s16 v1 = colCtx->dyna.actorMeshArr[floorPolySource].rot2.y - colCtx->dyna.actorMeshArr[floorPolySource].rot1.y; if (actor->id == 0) { - ((Player*)actor)->unk_83C += v1; + ((Player*)actor)->currentYaw += v1; } actor->shape.rot.y += v1; diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 5ac02fefc3..e696c25847 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -1521,13 +1521,13 @@ s32 func_8002F1C4(Actor* actor, GlobalContext* globalCtx, f32 arg2, f32 arg3, u3 // This is convoluted but it seems like it must be a single if statement to match if ((player->actor.flags & 0x100) || ((arg4 != 0) && func_8008E988(globalCtx)) || ((actor->unk_10C == 0) && - ((arg3 < fabsf(actor->yDistanceFromLink)) || (player->unk_698 < actor->xzDistanceFromLink) || + ((arg3 < fabsf(actor->yDistanceFromLink)) || (player->targetActorDistance < actor->xzDistanceFromLink) || (arg2 < actor->xzDistanceFromLink)))) { return 0; } - player->unk_694 = actor; - player->unk_698 = actor->xzDistanceFromLink; + player->naviTargetActor = actor; + player->targetActorDistance = actor->xzDistanceFromLink; player->exchangeItemId = arg4; return 1; @@ -1582,7 +1582,8 @@ s32 func_8002F434(Actor* actor, GlobalContext* globalCtx, s32 getItemId, f32 xzR s32 abs_var; if (!(player->stateFlags1 & 0x3C7080) && func_8008F29C(player) < 0) { - if ((((player->heldActor != NULL) || (actor == player->unk_694)) && (getItemId > 0) && (getItemId < 0x7E)) || + if ((((player->heldActor != NULL) || (actor == player->naviTargetActor)) && (getItemId > 0) && + (getItemId < 0x7E)) || (!(player->stateFlags1 & 0x20000800))) { if ((actor->xzDistanceFromLink < xzRange) && (fabsf(actor->yDistanceFromLink) < yRange)) { var = actor->rotTowardsLinkY - player->actor.shape.rot.y; @@ -2072,7 +2073,7 @@ void Actor_UpdateAll(GlobalContext* globalCtx, ActorContext* actorCtx) { } if ((player->stateFlags1 & 0x40) && ((player->actor.textId & 0xFF00) != 0x600)) { - sp74 = player->unk_694; + sp74 = player->naviTargetActor; } for (i = 0; i < ARRAY_COUNT(actorCtx->actorList); i++, sp80++) { @@ -2097,7 +2098,7 @@ void Actor_UpdateAll(GlobalContext* globalCtx, ActorContext* actorCtx) { Actor_Kill(actor); actor = actor->next; } else if ((unkFlag && !(actor->flags & unkFlag)) || - (!unkFlag && unkCondition && (sp74 != actor) && (actor != player->unk_68C) && + (!unkFlag && unkCondition && (sp74 != actor) && (actor != player->navi) && (actor != player->heldActor) && (&player->actor != actor->attachedA))) { func_80061E8C(&actor->colChkInfo); actor = actor->next; diff --git a/src/code/z_demo.c b/src/code/z_demo.c index d95b56c2f0..7beb6a3108 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -259,8 +259,8 @@ void func_80064824(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* break; case 15: if (sp3F != 0) { - TitleCard_InitPlaceName(globalCtx, &globalCtx->actorCtx.titleCtx, player->unk_1B0, 0xA0, 0x78, 0x90, - 0x18, 0x14); + TitleCard_InitPlaceName(globalCtx, &globalCtx->actorCtx.titleCtx, player->getItemModel, 0xA0, 0x78, + 0x90, 0x18, 0x14); } break; case 16: diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index 9030b5dc3c..862a10f333 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -1,7 +1,100 @@ #include #include -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008E750.s") +typedef struct { + u8 unk_0; + u16 unk_2; +} Struct_8008F2F8; + +// TODO decompile data + +extern SkeletonHeader* D_80125B70[]; + +extern s16 D_80125B78[]; + +extern u8 D_80125C44[]; + +extern Struct_8008F2F8 D_80125C88[]; + +extern u8 D_80125C98[]; + +extern UNK_TYPE D_80125F18[]; + +extern UNK_TYPE D_80125F20[]; + +extern UNK_TYPE D_80125F28[]; + +extern UNK_TYPE D_80125F30[]; + +extern UNK_TYPE D_80125F38[]; + +extern UNK_PTR D_80125F40[]; + +extern u8 D_8012607C[]; + +extern f32 D_801260D0; + +extern Vec3f D_801260A4; +extern Vec3f D_801260B0; +extern Vec3f D_801260BC; +extern Vec3f D_801260C8; + +extern Vec3f D_80126080; +extern Vec3f D_8012608C; +extern Vec3f D_80126098; + +// TODO decompile bss + +extern u8 D_80160008[]; // TODO check type + +// Segment Addresses + +extern LinkAnimetionEntry D_04003238; +extern UNK_TYPE D_0602A738; +extern UNK_TYPE D_0602CB48; + +void func_8008E750(GlobalContext* globalCtx, Player* player) { + s32 currentBoots; + s16* temp_var; + + REG(27) = 0x7D0; + REG(48) = 0x172; + + currentBoots = player->currentBoots; + if (currentBoots == 0) { + if (LINK_IS_CHILD) { + currentBoots = 5; + } + } else if (currentBoots == 1) { + if ((s32)(player->stateFlags1 * 0x10) < 0) { + currentBoots = 4; + } + REG(27) = 0x1F4; + REG(48) = 0x64; + } + + temp_var = (s16*)&D_80125B78 + (currentBoots * 0x11); + REG(19) = temp_var[0]; + REG(30) = temp_var[1]; + REG(32) = temp_var[2]; + REG(34) = temp_var[3]; + REG(35) = temp_var[4]; + REG(36) = temp_var[5]; + REG(37) = temp_var[6]; + REG(38) = temp_var[7]; + REG(43) = temp_var[8]; + REG(45) = temp_var[9]; + REG(68) = temp_var[10]; + REG(69) = temp_var[11]; + IREG(66) = temp_var[12]; + IREG(67) = temp_var[13]; + IREG(68) = temp_var[14]; + IREG(69) = temp_var[15]; + MREG(95) = temp_var[16]; + if (globalCtx->roomCtx.curRoom.unk_03 == 2) { + REG(45) = 0x1F4; + } +} s32 func_8008E8DC(GlobalContext* globalCtx, Player* player) { return (player->stateFlags1 & 0x20000080 || player->action || globalCtx->sceneLoadFlag == 0x14 || @@ -22,27 +115,110 @@ s32 func_8008E9D0(Player* player) { return LINK_IS_CHILD && player->currentShield == 2; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008E9F8.s") +s32 func_8008E9F8(Player* player, s32 arg1) { + s32 temp_v1 = D_80125C44[arg1]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008EA40.s") + if (temp_v1 == 2 && func_8008E9D0(player) != 0) { + return 1; + } else { + return temp_v1; + } +} +#ifdef NON_MATCHING +// Regalloc only +void func_8008EA40(Player* player) { + s8 temp; + + if ((s32)(player->stateFlags1 << 9) < 0) { + temp = player->unk_154; + if ((temp < 0) || (player->heldItemActionParam == temp)) { + if (func_8008F1A0(player) == 0 && func_8008E9D0(player) == 0) { + player->unk_15D = 0xA; + player->unk_160 = gSaveContext.linkAge + D_80125F40[10]; + if (player->unk_15E == 0x12) { + player->unk_15E = 0x10; + } else if (player->unk_15E == 0x13) { + player->unk_15E = 0x11; + } + player->unk_168 = gSaveContext.linkAge + D_80125F40[player->unk_15E]; + player->unk_15B = 2; + player->unk_154 = -1; + } + } + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008EA40.s") +#endif + +#ifdef NON_MATCHING +// Regalloc, gSaveContext and D_80125F40 hi/lo pairs swapped +void func_8008EB2C(Player* player, s32 arg1) { + player->unk_15C = D_80125C98[(arg1 * 5) + 1]; + player->unk_15D = D_80125C98[(arg1 * 5) + 2]; + player->unk_15E = D_80125C98[(arg1 * 5) + 3]; + player->unk_164 = gSaveContext.linkAge + D_80125F40[D_80125C98[(arg1 * 5) + 1]]; + player->unk_160 = gSaveContext.linkAge + D_80125F40[D_80125C98[(arg1 * 5) + 2]]; + player->unk_168 = gSaveContext.linkAge + D_80125F40[D_80125C98[(arg1 * 5) + 3]]; + player->unk_16C = gSaveContext.linkAge + D_80125F40[D_80125C98[(arg1 * 5) + 4]]; + func_8008EA40(player); +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008EB2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008EC04.s") +#endif + +void func_8008EC04(Player* player, s32 arg1) { + player->unk_158 = arg1; + if (arg1 == 1) { + player->unk_15B = 0; + } else { + player->unk_15B = D_80125C98[arg1 * 5]; + } + if (player->unk_15B < 3 && player->currentShield == 0) { + player->unk_15B = 0; + } + func_8008EB2C(player, arg1); +} void func_8008EC70(Player* player) { - player->unk_154 = player->unk_151; - func_8008EC04(player, func_8008E9F8(player, player->unk_151)); + player->unk_154 = player->heldItemActionParam; + func_8008EC04(player, func_8008E9F8(player, player->heldItemActionParam)); player->unk_6AD = 0; } +#ifdef NON_MATCHING +// Regalloc, ITEM_NONE immediate not reused +void func_8008ECAC(GlobalContext* globalCtx, Player* player) { + s32 phi_v0; + + if (player->action != 0x56) { + player->currentShield = ((gSaveContext.equips.equipment & gEquipMasks[1]) >> gEquipShifts[1]); + player->currentTunic = (((gSaveContext.equips.equipment & gEquipMasks[2]) >> gEquipShifts[2]) - 1); + player->currentBoots = (((gSaveContext.equips.equipment & gEquipMasks[3]) >> gEquipShifts[3]) - 1); + if (gSaveContext.buttonStatus[EQUIP_SWORD] == ITEM_NONE) { + player->currentSword = ITEM_NONE; + } else { + if (gSaveContext.equips.buttonItems[EQUIP_SWORD] == ITEM_SWORD_KNIFE) { + phi_v0 = ITEM_SWORD_BGS; + } else { + phi_v0 = gSaveContext.equips.buttonItems[EQUIP_SWORD]; + } + player->currentSword = phi_v0; + } + func_8008EC04(player, func_8008E9F8(player, player->heldItemActionParam)); + func_8008E750(globalCtx, player); + } +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008ECAC.s") +#endif void func_8008ED9C(GlobalContext* globalCtx, Player* player, s32 item, s32 arg2) { - Inventory_UpdateBottleItem(globalCtx, item, player->unk_150); + Inventory_UpdateBottleItem(globalCtx, item, player->heldItemCButtonIdx); if (item != ITEM_BOTTLE) { player->unk_152 = item; - player->unk_151 = arg2; + player->heldItemActionParam = arg2; } player->unk_154 = arg2; } @@ -52,18 +228,69 @@ void func_8008EDF0(Player* player) { player->stateFlags2 &= ~0x2000; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008EE08.s") +void func_8008EE08(Player* player) { + if ((player->actor.bgCheckFlags & 1) || (player->stateFlags1 & 0x8A00000) || + ((player->stateFlags1 & 0xC0000) == 0 && (player->actor.posRot.pos.y - player->actor.unk_80) < 100.0f)) { + player->stateFlags1 &= 0xBFF07FFF; + } else if ((player->stateFlags1 & 0x2C0000) == 0) { + player->stateFlags1 |= 0x80000; + } + func_8008EDF0(player); +} +#ifdef NON_MATCHING +// v1 instead of v0 +void func_8008EEAC(GlobalContext* globalCtx, UNK_PTR arg1) { + Player* player; + + player = PLAYER; + func_8008EE08(player); + player->unk_664 = arg1; + player->unk_684 = arg1; + player->stateFlags1 |= 0x10000; + func_8005AA90(Gameplay_GetCamera(globalCtx, 0), 8, arg1); + func_8005A444(Gameplay_GetCamera(globalCtx, 0), 2); +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008EEAC.s") +#endif + +s32 func_8008EF40(GlobalContext* globalCtx) { + Player* player = PLAYER; + return player->stateFlags1 & 0x800000; +} s32 func_8008EF44(GlobalContext* globalCtx, s32 arg1) { globalCtx->unk_11E5C = (arg1 + 1); return 1; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008EF5C.s") +s32 func_8008EF5C(GlobalContext* globalCtx, Vec3f* pos, f32 radius, f32 arg3) { + s32 pad; + Vec3f diff; + Player* player; + + player = PLAYER; + if ((player->heldItemActionParam == 6) && (player->stickFlameTimer != 0)) { + Math_Vec3f_Diff(&player->swordDimensions.tip, pos, &diff); + return ((diff.x * diff.x) + (diff.z * diff.z)) <= (radius * radius) && 0.0f <= diff.y && diff.y <= arg3; + } else { + return false; + } +} + +s32 func_8008F034() { + s32 temp_v1; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008F034.s") + temp_v1 = (s32)(gSaveContext.upgrades & gUpgradeMasks[2]) >> gUpgradeShifts[2]; + if (LINK_IS_ADULT) { + return temp_v1; + } else if (temp_v1 != 0) { + return 1; + } else { + return 0; + } +} u8 func_8008F080(GlobalContext* globalCtx) { Player* player = PLAYER; @@ -95,7 +322,7 @@ s32 func_8008F0D8(Player* player, s32 arg1) { } s32 func_8008F104(Player* player) { - return player->unk_151 == 0x10 || player->unk_151 == 0x11; + return player->heldItemActionParam == 0x10 || player->heldItemActionParam == 0x11; } s32 func_8008F128(Player* player) { @@ -111,17 +338,19 @@ s32 func_8008F158(s32 arg0) { } void func_8008F180(Player* player) { - func_8008F158(player->unk_151); + func_8008F158(player->heldItemActionParam); } s32 func_8008F1A0(Player* player) { - if (player->unk_151 >= 5 && player->unk_151 < 8) { + if (player->heldItemActionParam >= 5 && player->heldItemActionParam < 8) { return 1; } return 0; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008F1CC.s") +s32 func_8008F1CC(Player* player) { + return player->heldItemActionParam == 5 && gSaveContext.bgsHitsLeft <= 0.0f; +} s32 func_8008F224(Player* player, s32 arg1) { s32 temp_v0 = arg1 - 0x1E; @@ -132,7 +361,7 @@ s32 func_8008F224(Player* player, s32 arg1) { } void func_8008F250(Player* player) { - func_8008F224(player, player->unk_151); + func_8008F224(player, player->heldItemActionParam); } s32 func_8008F270(Player* player, s32 arg1) { @@ -144,12 +373,38 @@ s32 func_8008F270(Player* player, s32 arg1) { } s32 func_8008F29C(Player* player) { - return func_8008F270(player, player->unk_151); + return func_8008F270(player, player->heldItemActionParam); } #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008F2BC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008F2F8.s") +s32 func_8008F2F8(GlobalContext* globalCtx) { + Player* player; + Struct_8008F2F8* temp_a3; + s32 phi_v1; + + player = PLAYER; + if (globalCtx->roomCtx.curRoom.unk_02 == 3) { + phi_v1 = 0; + } else if (((s32)player->unk_840 >= 0x51) && (player->currentBoots == 1 || (s32)player->unk_840 >= 0x12C)) { + phi_v1 = (player->currentBoots == 1 && (player->actor.bgCheckFlags & 1)) ? 1 : 3; + } else if (((s32)player->stateFlags1 * 0x10) < 0) { + phi_v1 = 2; + } else { + return 0; + } + if (func_8008E988(globalCtx) == 0) { + temp_a3 = &D_80125C88[phi_v1]; + if (!temp_a3) {} + if (temp_a3->unk_0 != 0 && !(gSaveContext.unk_13C6 & temp_a3->unk_0) && + ((phi_v1 == 0 && player->currentTunic != 1) || + ((phi_v1 == 1 || phi_v1 == 3) && player->currentBoots == 1 && player->currentTunic != 2))) { + func_8010B680(globalCtx, temp_a3->unk_2, 0); + gSaveContext.unk_13C6 |= temp_a3->unk_0; + } + } + return phi_v1 + 1; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8008F470.s") @@ -159,23 +414,201 @@ s32 func_8008F29C(Player* player) { #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80090014.s") +#ifdef NON_MATCHING +// Regalloc only +s32 func_800902F0(s32 arg0, s32 arg1, UNK_PTR** arg2, s32 arg3, s32 arg4, Player* player) { + if (func_8008FCC8(arg0, arg1, arg2, arg3, arg4, player) == 0) { + if (player->unk_6AD != 2) { + *arg2 = NULL; + } else { + if (arg1 == 0xF) { + *arg2 = D_80125F18[gSaveContext.linkAge]; + } else if (arg1 == 0x10) { + *arg2 = D_80125F20[gSaveContext.linkAge]; + } else if (arg1 == 0x11) { + *arg2 = D_80125F28[gSaveContext.linkAge]; + } else if (arg1 == 0x12) { + *arg2 = D_80125F30[gSaveContext.linkAge]; + } else if (arg1 == 0x13) { + *arg2 = func_8008F104(player) ? &D_0602A738 : D_80125F38[gSaveContext.linkAge]; + } else { + *arg2 = NULL; + } + } + } + return 0; +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_800902F0.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80090440.s") +s32 func_80090440(s32 arg0, s32 arg1, UNK_PTR** arg2, s32 arg3, s32 arg4, Player* player) { + if (func_8008FCC8(arg0, arg1, arg2, arg3, arg4, player) == 0) { + *arg2 = NULL; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80090480.s") +u8 func_80090480(GlobalContext* globalCtx, Collider* collider, Struct_80090480_arg2* arg2, Vec3f* arg3, Vec3f* arg4) { + if (arg2->active == 0) { + if (collider != NULL) { + Collider_QuadSetAT(globalCtx, collider); + } + Math_Vec3f_Copy(&arg2->tip, arg3); + Math_Vec3f_Copy(&arg2->base, arg4); + arg2->active = 1; + return 1; + } else { + if (arg2->tip.x == arg3->x && arg2->tip.y == arg3->y && arg2->tip.z == arg3->z && arg2->base.x == arg4->x && + arg2->base.y == arg4->y && arg2->base.z == arg4->z) { + if (collider != NULL) { + Collider_QuadSetAT(globalCtx, collider); + } + return 0; + } + if (collider != NULL) { + func_80062734(collider, arg4, arg3, &arg2->base, &arg2->tip); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, collider); + } + Math_Vec3f_Copy(&arg2->base, arg4); + Math_Vec3f_Copy(&arg2->tip, arg3); + arg2->active = 1; + return 1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80090604.s") +void func_80090604(GlobalContext* globalCtx, Player* player, ColliderQuad* collider, ColliderQuadDimInit* quadInit) { + Vec3f d; + Vec3f c; + Vec3f b; + Vec3f a; + + if ((s32)(player->stateFlags1 << 9) < 0) { + player->unk_5F8 = D_8012607C[player->currentShield]; + Matrix_MultVec3f(&quadInit->quad[0], &a); + Matrix_MultVec3f(&quadInit->quad[1], &b); + Matrix_MultVec3f(&quadInit->quad[2], &c); + Matrix_MultVec3f(&quadInit->quad[3], &d); + func_80062734(collider, &a, &b, &c, &d); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &collider->base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &collider->base); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_800906D4.s") +void func_800906D4(GlobalContext* globalCtx, Player* player, ColliderTrisItemDimInit* trisInit) { + Vec3f sp44; + Vec3f sp38; + Vec3f sp2C; + + Matrix_MultVec3f(&D_801260A4, &sp2C); + Matrix_MultVec3f(&D_801260B0, &sp38); + Matrix_MultVec3f(&D_801260BC, &sp44); + if (func_80090480(globalCtx, NULL, &player->swordDimensions, &trisInit->vtx[0], &sp2C) != 0 && + (s32)(player->stateFlags1 << 9) >= 0) { + EffectBlure_AddVertex(Effect_GetByIndex(player->swordEffectId), &player->swordDimensions.tip, &player->swordDimensions.base); + } + if (player->swordState > 0 && ((player->swordAnimation < 0x18) || ((s32)(player->stateFlags2 << 0xE) < 0))) { + func_80090480(globalCtx, &player->unk_4E4, &player->unk_8D0, &trisInit->vtx[1], &sp38); + func_80090480(globalCtx, &player->unk_564, &player->unk_8EC, &trisInit->vtx[2], &sp44); + } +} +#ifdef NON_MATCHING +// Regalloc, single stack difference +void func_800907E4(GlobalContext* globalCtx, Player* player, Vec3f* arg2, s32 arg3) { + f32 sp4C; + GraphicsContext* gfxCtx; + Gfx* dispRefs[4]; + s32 temp_at; + f32 sp28; + + sp4C = (player->exchangeItemId != 0) ? 6.0f : 14.0f; + gfxCtx = globalCtx->state.gfxCtx; + Graph_OpenDisps(dispRefs, globalCtx->state.gfxCtx, "../z_player_lib.c", 0x961); + gSegments[6] = PHYSICAL_TO_VIRTUAL(player->getItemModel); + + gSPSegment(gfxCtx->polyOpa.p++, 0x06, player->getItemModel); + gSPSegment(gfxCtx->polyXlu.p++, 0x06, player->getItemModel); + + sp28 = Math_Sins(player->actor.shape.rot.y); + Matrix_Translate((sp28 * 3.299999952316284f) + arg2->x, arg2->y + sp4C, + (Math_Coss(player->actor.shape.rot.y) * (3.299999952316284f + (IREG(90) / 10.0f))) + arg2->z, + MTXMODE_NEW); + temp_at = globalCtx->gameplayFrames; + Matrix_RotateZYX(0.0f, ((((globalCtx->gameplayFrames << 5) - temp_at) * 4) + temp_at) * 8, 0.0f, MTXMODE_APPLY); + Matrix_Scale(0.20000000298023224f, 0.20000000298023224f, 0.20000000298023224f, MTXMODE_APPLY); + func_800694A0(globalCtx, arg3 - 1); + Graph_CloseDisps(dispRefs, globalCtx->state.gfxCtx, "../z_player_lib.c", 0x975); +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_800907E4.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_800909B4.s") +void func_800909B4(GlobalContext* globalCtx, Player* player) { + if ((player->unk_170 == 0) || !osRecvMesg(&player->unk_194, NULL, OS_MESG_NOBLOCK)) { + player->unk_170 = 0; + func_800907E4(globalCtx, player, &D_80160008, ABS(player->overheadItemId)); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80090A28.s") +void func_80090A28(Player* player, ColliderTrisItemDimInit* trisInit) { + D_8012608C.x = D_80126080.x; + if (player->unk_845 >= 3) { + player->unk_845 += 1; + D_8012608C.x *= (1.0f + ((9 - player->unk_845) * 0.10000000149011612f)); + } + D_8012608C.x += 1200.0f; + D_80126098.x = D_8012608C.x; + Matrix_MultVec3f(&D_80126080, &trisInit->vtx[0]); + Matrix_MultVec3f(&D_8012608C, &trisInit->vtx[1]); + Matrix_MultVec3f(&D_80126098, &trisInit->vtx[2]); +} +#ifdef NON_MATCHING +// This function needs a bit of work still, but should be functionally equivalent. +// The biggest differences are in loads/stores of .data variables, +// also regalloc past Matrix_NewMtx and a minor stack difference. +void func_80090AFC(GlobalContext* globalCtx, Player* player, f32 arg2) { + f32 sp9C; + f32 sp98; + Vec3f sp8C; + Vec3f sp80; + Vec3f sp74; + Vec3f sp68; + f32 sp64; + f32 sp60; + Gfx* dispRefs[5]; // TODO confirm size + GraphicsContext* gfxCtx; + + D_801260D0 = 0.0f; + Matrix_MultVec3f(&D_801260C8, &sp8C); + D_801260D0 = arg2; + Matrix_MultVec3f(&D_801260C8, &sp80); + + if (func_8003E188(&globalCtx->colCtx, &sp8C, &sp80, &sp74, &sp9C, 1, 1, 1, 1, &sp98) != 0) { + gfxCtx = globalCtx->state.gfxCtx; + Graph_OpenDisps(dispRefs, globalCtx->state.gfxCtx, "../z_player_lib.c", 0xA0C); + + gfxCtx->overlay.p = Gfx_CallSetupDL(gfxCtx->overlay.p, 7); + + func_800A6E10(&globalCtx->mf_11D60, &sp74, &sp68, &sp64); + + sp60 = (sp64 < 200.0f) ? 0.07999999821186066f : (sp64 / 200.0f) * 0.07999999821186066f; + + Matrix_Translate(sp74.x, sp74.y, sp74.z, MTXMODE_NEW); + Matrix_Scale(sp60, sp60, sp60, MTXMODE_APPLY); + + gSPMatrix(gfxCtx->overlay.p++, Matrix_NewMtx(gfxCtx, "../z_player_lib.c", 0xA1B), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(gfxCtx->overlay.p++, 0x06, globalCtx->objectCtx.status[player->actor.objBankIndex].segment); + gSPDisplayList(gfxCtx->overlay.p++, &D_0602CB48); + + Graph_CloseDisps(dispRefs, globalCtx->state.gfxCtx, "../z_player_lib.c", 0xA20); + } +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80090AFC.s") +#endif #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80090D20.s") diff --git a/src/overlays/actors/ovl_En_Boom/z_en_boom.h b/src/overlays/actors/ovl_En_Boom/z_en_boom.h index c78a16d2a1..9934edcd8b 100644 --- a/src/overlays/actors/ovl_En_Boom/z_en_boom.h +++ b/src/overlays/actors/ovl_En_Boom/z_en_boom.h @@ -16,7 +16,7 @@ typedef struct EnBoom { /* 0x01D4 */ u8 returnTimer; // returns to Link when 0 /* 0x01D5 */ u8 activeTimer; // increments once every update /* 0x01D8 */ u32 effectIndex; // set by Effect_Add - /* 0x01DC */ u32 unk_1DC[0x7]; + /* 0x01DC */ Struct_80090480_arg2 unk_1DC; /* 0x01F8 */ EnBoomActionFunc actionFunc; } EnBoom; // size = 0x01FC diff --git a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c index c496a5d397..a4465b902c 100644 --- a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c +++ b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c @@ -788,7 +788,7 @@ void EnFloormas_GrabLink(EnFloormas* this, GlobalContext* globalCtx) { this->actor.posRot.pos.z = Math_Coss(this->actor.shape.rot.y) * (xzDelta * 0.1f) + player->actor.posRot.pos.z; // let go - if (!(player->stateFlags2 & 0x80) || (player->unk_A78 < 0)) { + if (!(player->stateFlags2 & 0x80) || (player->invincibilityTimer < 0)) { attachedA = this->actor.attachedA; attachedB = this->actor.attachedB; diff --git a/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c b/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c index 9ae50c5d41..3207fe0f46 100644 --- a/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c +++ b/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c @@ -881,7 +881,7 @@ void func_80AEC780(EnRu1* this, GlobalContext* globalCtx) { globalCtx->csCtx.segment = &D_80AF0880; gSaveContext.cutsceneTrigger = 1; - player->unk_838 = 0.0f; + player->linearVelocity = 0.0f; this->action = 8; } } diff --git a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c index 9087c97d68..4f64efe8f9 100644 --- a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c +++ b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c @@ -297,7 +297,7 @@ void EnWallmas_WaitToDrop(EnWallmas* this, GlobalContext* globalCtx) { void EnWallmas_Drop(EnWallmas* this, GlobalContext* globalCtx) { Player* player = PLAYER; - if (!func_8008E988(globalCtx) && (player->stateFlags2 & 0x10) == 0 && (player->unk_A78 >= 0) && + if (!func_8008E988(globalCtx) && (player->stateFlags2 & 0x10) == 0 && (player->invincibilityTimer >= 0) && (this->actor.xzDistanceFromLink < 30.0f) && (this->actor.yDistanceFromLink < -5.0f) && (-(f32)(player->unk_4DA + 0xA) < this->actor.yDistanceFromLink)) { EnWallmas_TakePlayerBegin(this, globalCtx);