diff options
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/c_keyframe.c | 30 | ||||
| -rw-r--r-- | src/code/game.c | 6 | ||||
| -rw-r--r-- | src/code/m_actor.c | 1143 |
3 files changed, 1160 insertions, 19 deletions
diff --git a/src/code/c_keyframe.c b/src/code/c_keyframe.c index 9df0986..352eac5 100644 --- a/src/code/c_keyframe.c +++ b/src/code/c_keyframe.c @@ -38,12 +38,10 @@ #include "z64math.h" #include "m_lib.h" #include "gfx.h" -#include "m_play.h" #include "libc64/fp.h" #include "sys_matrix.h" #include "sys_math3d.h" - -UNK_PTR* B_801458A0_jp[4]; +#include "overlays/gamestates/ovl_play/m_play.h" void cKF_FrameControl_zeroClear(FrameControl* frameControl) { bzero(frameControl, sizeof(FrameControl)); @@ -719,13 +717,13 @@ void cKF_SkeletonInfo_R_init_reverse_setspeedandmorphandmode(SkeletonInfoR* skel void func_80053384_jp(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, UNK_PTR* arg6, UNK_PTR* arg7, UNK_PTR* arg8) { if (arg3 != 0) { - B_801458A0_jp[arg0] = OS_PHYSICAL_TO_K0(arg6); + gSegments[arg0] = (uintptr_t)OS_K0_TO_PHYSICAL(arg6); } if (arg4 != 0) { - B_801458A0_jp[arg1] = OS_PHYSICAL_TO_K0(arg7); + gSegments[arg1] = (uintptr_t)OS_K0_TO_PHYSICAL(arg7); } if (arg5 != 0) { - B_801458A0_jp[arg2] = OS_PHYSICAL_TO_K0(arg8); + gSegments[arg2] = (uintptr_t)OS_K0_TO_PHYSICAL(arg8); } } @@ -888,14 +886,14 @@ s32 cKF_SkeletonInfo_R_combine_play(SkeletonInfoR* skeletonInfo1, SkeletonInfoR* joint = (!IS_ZERO(skeletonInfo1->morphCounter)) ? (s16*)skeletonInfo1->morphTable : (s16*)skeletonInfo1->jointTable; if (arg4 != 0) { - sp44 = OS_PHYSICAL_TO_K0(B_801458A0_jp[arg2]); - B_801458A0_jp[arg2] = OS_PHYSICAL_TO_K0(arg4); + sp44 = OS_PHYSICAL_TO_K0(gSegments[arg2]); + gSegments[arg2] = (uintptr_t)OS_K0_TO_PHYSICAL(arg4); cKF_SkeletonInfo_R_combine_work_set(&combine3, skeletonInfo1); } if (arg5 != 0) { - sp40 = OS_PHYSICAL_TO_K0(B_801458A0_jp[arg3]); - B_801458A0_jp[arg3] = OS_PHYSICAL_TO_K0(arg5); + sp40 = OS_PHYSICAL_TO_K0(gSegments[arg3]); + gSegments[arg3] = (uintptr_t)OS_K0_TO_PHYSICAL(arg5); cKF_SkeletonInfo_R_combine_work_set(&combine2, skeletonInfo2); cKF_SkeletonInfo_R_combine_work_set(&combine1, skeletonInfo2); } @@ -966,18 +964,18 @@ void cKF_SkeletonInfo_R_T_combine_play(s32* arg0, s32* arg1, s32* arg2, Skeleton spAC = (!IS_ZERO(skeletonInfo1->morphCounter)) ? (s16*)skeletonInfo1->morphTable : (s16*)skeletonInfo1->jointTable; if (arg9 != 0) { - sp48 = OS_PHYSICAL_TO_K0(B_801458A0_jp[arg6]); - B_801458A0_jp[arg6] = OS_PHYSICAL_TO_K0(arg9); + sp48 = OS_PHYSICAL_TO_K0(gSegments[arg6]); + gSegments[arg6] = (uintptr_t)OS_K0_TO_PHYSICAL(arg9); cKF_SkeletonInfo_R_combine_work_set(&sp4C, skeletonInfo1); } if (argA != 0) { - sp44 = OS_PHYSICAL_TO_K0(B_801458A0_jp[arg7]); - B_801458A0_jp[arg7] = OS_PHYSICAL_TO_K0(argA); + sp44 = OS_PHYSICAL_TO_K0(gSegments[arg7]); + gSegments[arg7] = (uintptr_t)OS_K0_TO_PHYSICAL(argA); cKF_SkeletonInfo_R_combine_work_set(&sp6C, skeletonInfo2); } if (argB != 0) { - sp40 = OS_PHYSICAL_TO_K0(B_801458A0_jp[arg8]); - B_801458A0_jp[arg8] = OS_PHYSICAL_TO_K0(argB); + sp40 = OS_PHYSICAL_TO_K0(gSegments[arg8]); + gSegments[arg8] = (uintptr_t)OS_K0_TO_PHYSICAL(argB); cKF_SkeletonInfo_R_combine_work_set(&sp8C, skeletonInfo3); } diff --git a/src/code/game.c b/src/code/game.c index ac01008..1c634ba 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -145,9 +145,9 @@ void game_draw_first(GraphicsContext* gfxCtx) { gSPSegment(UNK_2C0_DISP++, 0x0F, gfxCtx->unk_2E4); gSPSegment(UNK_2C0_DISP++, 0x0E, temp_v0); - gSPSegment(UNK_2D0_DISP++, 0x00, NULL); - gSPSegment(UNK_2D0_DISP++, 0x0F, gfxCtx->unk_2E4); - gSPSegment(UNK_2D0_DISP++, 0x0E, temp_v0); + gSPSegment(LIGHT_DISP++, 0x00, NULL); + gSPSegment(LIGHT_DISP++, 0x0F, gfxCtx->unk_2E4); + gSPSegment(LIGHT_DISP++, 0x0E, temp_v0); CLOSE_DISPS(gfxCtx); } diff --git a/src/code/m_actor.c b/src/code/m_actor.c new file mode 100644 index 0000000..f5c2091 --- /dev/null +++ b/src/code/m_actor.c @@ -0,0 +1,1143 @@ +#include "m_actor.h" +#include "m_actor_dlftbls.h" +#include "m_collision_bg.h" +#include "m_collision_obj.h" +#include "m_common_data.h" +#include "m_debug.h" +#include "m_event.h" +#include "m_field_info.h" +#include "m_lights.h" +#include "m_malloc.h" +#include "m_lib.h" +#include "m_skin_matrix.h" +#include "m_player_lib.h" +#include "m_npc.h" +#include "m_scene.h" +#include "libc/math.h" +#include "fault.h" +#include "sys_matrix.h" +#include "ovlmgr.h" +#include "gfx.h" +#include "6E9650.h" +#include "unknown_structs.h" +#include "code_variables.h" +#include "macros.h" +#include "overlays/gamestates/ovl_play/m_play.h" +#include "overlays/actors/ovl_player_actor/m_player.h" + +void func_80056380_jp(void* arg0, void* arg1 UNUSED) { + Actor* actor = arg0; + const char* name; + + if ((actor == NULL) || (actor->overlayEntry == NULL)) { + //! @bug this will be overriden by the next printf + FaultDrawer_SetCursor(48, 24); + FaultDrawer_Printf("ACTOR NAME is NULL"); + } + + FaultDrawer_SetCursor(48, 24); + name = ""; + FaultDrawer_Printf("ACTOR NAME %08x:%s", actor, name); +} + +void projection_pos_set(PlayState* play, Vec3f* worldPos, Vec3f* projectedPos, f32* invW) { + Skin_Matrix_PrjMulVector(&play->viewProjectionMtxF, worldPos, projectedPos, invW); + + *invW = (*invW < 1.0f) ? 1.0f : (1.0f / *invW); +} + +void Actor_world_to_eye(Actor* actor, f32 arg1) { + actor->eye.pos.x = actor->world.pos.x; + actor->eye.pos.y = actor->world.pos.y + arg1; + actor->eye.pos.z = actor->world.pos.z; + actor->eye.rot.x = actor->world.rot.x; + actor->eye.rot.y = actor->world.rot.y; + actor->eye.rot.z = actor->world.rot.z; +} + +void Actor_position_move(Actor* actor) { + Kankyo* kankyo = &((PlayState*)gamePT)->kankyo; + f32 speedRate; + + speedRate = game_GameFrame_2F; + + kankyo->unk_C0(actor); + + actor->world.pos.x += actor->velocity.x * speedRate + actor->colStatus.displacement.x; + actor->world.pos.y += actor->velocity.y * speedRate + actor->colStatus.displacement.y; + actor->world.pos.z += actor->velocity.z * speedRate + actor->colStatus.displacement.z; +} + +void Actor_position_speed_set(Actor* actor) { + actor->velocity.x = sin_s(actor->world.rot.y) * actor->speed; + actor->velocity.z = cos_s(actor->world.rot.y) * actor->speed; + + chase_f(&actor->velocity.y, actor->terminalVelocity, actor->gravity); +} + +void Actor_position_moveF(Actor* actor) { + Actor_position_speed_set(actor); + Actor_position_move(actor); +} + +s32 Actor_player_look_direction_check(Actor* actor, s16 maxAngleDiff, PlayState* play) { + s16 yawDiff = BINANG_ROT180(actor->yawTowardsPlayer) - get_player_actor_withoutCheck(play)->actor.shape.rot.y; + + return ABS(yawDiff) < maxAngleDiff; +} + +void Actor_display_position_set(PlayState* play, Actor* actor, s16* x, s16* y) { + Vec3f projectedPos; + f32 invW; + + projection_pos_set(play, &actor->world.pos, &projectedPos, &invW); + + // Explicit cast to avoid implicit cast from f32 to s16 + *x = (s32)PROJECTED_TO_SCREEN_X(projectedPos, invW); + *y = (s32)PROJECTED_TO_SCREEN_Y(projectedPos, invW); +} + +s32 Actor_data_bank_dma_end_check(Actor* actor, PlayState* play) { + s32 var_v1; + + switch (ACTOR_FGNAME_GET_F000(actor->fgName)) { + case FGNAME_F000_D: + case FGNAME_F000_E: + var_v1 = common_data.unk_1004C->unk_F4(play->unk_0110, actor); + break; + + default: + var_v1 = play->unk_0110[actor->unk_026].unk_00 > 0; + break; + } + + return var_v1; +} + +void Shape_Info_init(Actor* actor, f32 arg1, Shape_Info_unk_0C arg2, f32 arg3, f32 arg4) { + actor->shape.unk_08 = arg1; + actor->shape.unk_0C = arg2; + actor->shape.unk_10 = arg3; + actor->shape.unk_14 = arg4; + actor->shape.unk_2C = 1; + actor->shape.unk_20 = 0; + actor->shape.unk_18 = 1.0f; + actor->shape.unk_1C = 1.0f; + actor->shape.unk_2E = 0; + actor->shape.unk_24 = &actor->world.pos; + actor->shape.unk_28 = -1; + actor->shape.unk_2D = 0; +} + +void Actor_foot_shadow_pos_set(Actor* actor, s32 limbIndex, s32 leftFootIndex, Vec3f* leftFootPos, s32 rightFootIndex, + Vec3f* rightFootPos) { + if (limbIndex == leftFootIndex) { + Matrix_Position(leftFootPos, &actor->shape.feetPos[FOOT_LEFT]); + } else if (limbIndex == rightFootIndex) { + Matrix_Position(rightFootPos, &actor->shape.feetPos[FOOT_RIGHT]); + } +} + +void Actor_delete(Actor* actor) { + if (actor != NULL) { + actor->update = NULL; + actor->draw = NULL; + } +} + +void Actor_ct(Actor* actor, PlayState* play) { + s32 pad[2] UNUSED; + PlayState_unk_0110* temp; + Npc* npc; + CommonData_unk_1004C_unk_14_arg0 sp34; + PlayState_unk_0110* temp_a0; + + temp_a0 = play->unk_0110; + + temp = temp_a0; + temp += actor->unk_026; + temp->unk_50++; + + if (actor->part == ACTOR_PART_NPC) { + npc = (Npc*)actor; + + common_data.unk_1004C->unk_14(&sp34, npc->actor.fgName); + npc->unk_708 = mSc_bank_regist_check(temp_a0, sp34.unk_02); + temp_a0[npc->unk_708].unk_50++; + } + + actor->world = actor->home; + actor->shape.rot = actor->world.rot; + + Actor_world_to_eye(actor, 0.0f); + xyz_t_move(&actor->prevPos, &actor->world.pos); + + actor->scale.x = 0.01f; + actor->scale.y = 0.01f; + actor->scale.z = 0.01f; + + actor->terminalVelocity = -20.0f; + actor->xyzDistToPlayerSq = FLT_MAX; + + actor->uncullZoneScale = 350.0f; + actor->uncullZoneDownward = 700.0f; + + actor->shape.unk_18 = 1.0f; + actor->shape.unk_1C = 1.0f; + + actor->unk_13C = 1000.0f; + actor->unk_140 = 350.0f; + actor->unk_144 = 55.0f; + + CollisionCheck_Status_ct(&actor->colStatus); + Shape_Info_init(actor, 0.0f, NULL, 0.0f, 0.0f); + + if (Actor_data_bank_dma_end_check(actor, play) == 1) { + gSegments[6] = (uintptr_t)OS_K0_TO_PHYSICAL(temp_a0[actor->unk_026].segment); + actor->ct(actor, play); + actor->ct = NULL; + } +} + +#ifdef NON_MATCHING +void Actor_dt(Actor* actor, PlayState* play) { + PlayState_unk_0110* temp_v0_6; + s32 new_var; + + if (actor->save != NULL) { + actor->save(actor, play); + actor->save = NULL; + } + + if (actor->dt != NULL) { + actor->dt(actor, play); + actor->dt = NULL; + } + + if ((actor->child != NULL) && (actor == actor->child->parent)) { + actor->child->parent = NULL; + } + + if ((actor->parent != NULL) && (actor == actor->parent->child)) { + actor->parent->child = NULL; + } + + temp_v0_6 = play->unk_0110; + if (0) {} + + switch ((actor->fgName & 0xF000) >> 0xC) { + case 0xD: + case 0xE: + common_data.unk_1004C->unk_F0(temp_v0_6, actor); + break; + + default: + new_var = play->unk_190C; + + if (actor->unk_026 >= new_var) { + temp_v0_6 = &temp_v0_6[(void)0, actor->unk_026]; + if (temp_v0_6->unk_50 > 0) { + actor->unk_026 = -1; + temp_v0_6->unk_50--; + } + } + break; + } +} +#else +void Actor_dt(Actor* actor, struct PlayState* play); +#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_actor/Actor_dt.s") +#endif + +void Actor_draw(PlayState* play, Actor* actor) { + FaultClient faultClient; + Lights* light; + + Fault_AddClient(&faultClient, func_80056380_jp, actor, "Actor_draw"); + + //! FAKE + if (1) {} + if (1) {} + if (1) {} + if (1) {} + + OPEN_DISPS(play->state.gfxCtx); + + light = Global_light_read(&play->lightCtx, play->state.gfxCtx); + LightsN_list_check(light, play->lightCtx.unk_0, (actor->flags & ACTOR_FLAG_400000) ? NULL : &actor->world.pos); + LightsN_disp(light, play->state.gfxCtx); + + Matrix_softcv3_load(actor->world.pos.x, actor->world.pos.y + actor->shape.unk_08 * actor->scale.y, + actor->world.pos.z, &actor->shape.rot); + Matrix_scale(actor->scale.x, actor->scale.y, actor->scale.z, MTXMODE_APPLY); + + { + void* segment = play->unk_0110[(void)0, actor->unk_026].segment; + + gSegments[6] = (uintptr_t)OS_PHYSICAL_TO_K0(segment); + + gSPSegment(POLY_OPA_DISP++, 0x06, segment); + gSPSegment(POLY_XLU_DISP++, 0x06, segment); + gSPSegment(UNK_2C0_DISP++, 0x06, segment); + } + + actor->draw(actor, play); + + if (actor->shape.unk_0C != NULL) { + actor->shape.unk_0C(actor, light, play); + } + + CLOSE_DISPS(play->state.gfxCtx); + + Fault_RemoveClient(&faultClient); +} + +s32 Actor_draw_actor_no_culling_check(Actor* actor) { + return Actor_draw_actor_no_culling_check2(actor, &actor->projectedPos, actor->projectedW); +} + +s32 Actor_draw_actor_no_culling_check2(Actor* actor, Vec3f* arg1, f32 arg2) { + s32 ret = 0; + + if ((-actor->unk_140 < arg1->z) && (arg1->z < (actor->unk_13C + actor->unk_140))) { + f32 var_fa1; + + if (arg2 < 1.0f) { + var_fa1 = 1.0f; + } else { + var_fa1 = 1.0f / arg2; + } + + if (((fabsf(arg1->x) - actor->uncullZoneScale) * var_fa1) < 1.0f) { + if (((arg1->y + actor->uncullZoneDownward) * var_fa1) > -1.0f) { + if (((arg1->y - actor->unk_140) * var_fa1) < 1.0f) { + ret = 1; + } + } + } + } + + return ret; +} + +void Actor_cull_check(Actor* actor) { + if (Actor_draw_actor_no_culling_check(actor) == 1) { + actor->flags |= ACTOR_FLAG_40; + } else { + actor->flags &= ~ACTOR_FLAG_40; + } +} + +void Actor_delete_check(Actor* actor, PlayState* play) { + if ((actor->flags & (ACTOR_FLAG_40 | ACTOR_FLAG_20 | ACTOR_FLAG_10)) || (actor->fgName == 0)) { + return; + } + + if ((actor->unk_008 < 0) || (actor->unk_009 < 0)) { + return; + } + + if ((actor->unk_008 == play->unk_00E4) && (actor->unk_009 == play->unk_00E5)) { + return; + } + + Actor_delete(actor); +} + +void Actor_info_ct(PlayState* play2, ActorInfo* actorInfo, ActorEntry* actorEntry) { + PlayState* play = play2; + Actor* temp_v0; + ActorOverlay* var_v0; + ActorEntry* var_s0_2; + s16* var_s0; + s32 var_s1; + + bzero(actorInfo, sizeof(ActorInfo)); + + actor_dlftbls_init(); + Matrix_copy_MtxF(&play->billboardMtxF, &MtxF_clear); + Matrix_copy_MtxF(&play->viewProjectionMtxF, &MtxF_clear); + + var_v0 = actor_dlftbls; + for (var_s1 = 0; var_s1 < 0xC9; var_s1++) { + var_v0->loadedRamAddr = NULL; + var_v0->numLoaded = 0; + var_v0++; + } + + if (mEv_CheckFirstJob() == 1) { + common_data.unk_107B6 = 0x5B; + } + + if (common_data.unk_107B6 != 0xC9) { + Actor_info_make_actor(actorInfo, play, common_data.unk_107B6, 0.0f, 0.0f, 0.0f, 0, 0, 0, -1, -1, -1, 0, -1, -1, + -1); + } + common_data.unk_107B6 = 0xC9; + +label: + + temp_v0 = Actor_info_make_actor(actorInfo, play, actorEntry->id, actorEntry->pos.x, actorEntry->pos.y, + actorEntry->pos.z, actorEntry->rot.x, actorEntry->rot.y, actorEntry->rot.z, -1, -1, + -1, 0, actorEntry->params, -1, -1); + if (temp_v0 != NULL) { + temp_v0->world.pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(temp_v0->world.pos, 0.0f); + mFI_SetBearActor(play, temp_v0->world.pos, 0); + } + + if (common_data.unk_1014E != 0) { + Actor_info_make_actor(actorInfo, play, common_data.unk_1014E, 0.0f, 0.0f, 0.0f, 0, 0, 0, -1, -1, -1, 0, -1, -1, + -1); + } + + if (play->unk_1EA6 != 0) { + var_s0 = play->unk_1EB0; + + for (var_s1 = 0; var_s1 < play->unk_1EA6; var_s1++) { + Actor_info_make_actor(&play->actorInfo, play, *var_s0, 0.0f, 0.0f, 0.0f, 0, 0, 0, -1, -1, -1, 0, -1, -1, + -1); + var_s0 += 1; + } + play->unk_1EA6 = 0; + } + + mSc_regist_initial_exchange_bank(play); + + if (play->unk_1EA5 != 0) { + var_s0_2 = play->unk_1EAC; + for (var_s1 = 0; var_s1 < play->unk_1EA5; var_s1++) { + Actor_info_make_actor(&play->actorInfo, play, var_s0_2->id, var_s0_2->pos.x, var_s0_2->pos.y, + var_s0_2->pos.z, var_s0_2->rot.x, var_s0_2->rot.y, var_s0_2->rot.z, -1, -1, -1, 0, + var_s0_2->params, -1, -1); + var_s0_2 += 1; + } + play->unk_1EA5 = 0; + } +} + +void Actor_info_dt(ActorInfo* actorInfo, PlayState* play) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(actorInfo->actorLists); i++) { + Actor* actor = actorInfo->actorLists[i].head; + + while (actor != NULL) { + Actor_info_delete(actorInfo, actor, play); + actor = actorInfo->actorLists[i].head; + } + } + + actor_dlftbls_cleanup(); +} + +void Actor_info_call_actor(PlayState* play, ActorInfo* actorInfo) { + s32 pad[1] UNUSED; + ActorPart part; + Player* player; + + player = get_player_actor_withoutCheck(play); + func_8008E5F4_jp(player->actor.world.pos); + + for (part = 0; part < ACTOR_PART_MAX; part++) { + Actor* actor; + Actor* next; + + for (actor = actorInfo->actorLists[part].head; actor != NULL; actor = next) { + play->state.unk_9C = actor->name; + play->state.unk_9D = 0x97; + + if (actor->world.pos.y < -25000.0f) { + actor->world.pos.y = -25000.0f; + } + + if (actor->ct != NULL) { + if (Actor_data_bank_dma_end_check(actor, play) == 1) { + gSegments[6] = (uintptr_t)OS_K0_TO_PHYSICAL(play->unk_0110[actor->unk_026].segment); + + play->state.unk_9D = 0x98; + actor->ct(actor, play); + play->state.unk_9D = 0x99; + actor->ct = NULL; + } + next = actor->next; + } else if (Actor_data_bank_dma_end_check(actor, play) == 0) { + play->state.unk_9D = 0x9A; + Actor_delete(actor); + play->state.unk_9D = 0x9B; + next = actor->next; + } else if (actor->update == NULL) { + if (!actor->isDrawn) { + play->state.unk_9D = 0x9C; + next = Actor_info_delete(&play->actorInfo, actor, play); + play->state.unk_9D = 0x9D; + } else { + play->state.unk_9D = 0x9E; + Actor_dt(actor, play); + play->state.unk_9D = 0x9F; + next = actor->next; + } + } else { + play->state.unk_9D = 0xA0; + xyz_t_move(&actor->prevPos, &actor->world.pos); + + actor->xzDistToPlayer = search_position_distanceXZ(&actor->world.pos, &player->actor.world.pos); + actor->playerHeightRel = player->actor.world.pos.y - actor->world.pos.y; + + actor->xyzDistToPlayerSq = SQ(actor->xzDistToPlayer) + SQ(actor->playerHeightRel); + actor->yawTowardsPlayer = search_position_angleY(&actor->world.pos, &player->actor.world.pos); + + actor->flags &= ~ACTOR_FLAG_1000000; + if ((actor->flags & (ACTOR_FLAG_40 | ACTOR_FLAG_10)) || (actor->part == ACTOR_PART_NPC)) { + gSegments[6] = (uintptr_t)OS_K0_TO_PHYSICAL(play->unk_0110[actor->unk_026].segment); + play->state.unk_9D = 0xA1; + actor->update(actor, play); + play->state.unk_9D = 0xA2; + } + + CollisionCheck_Status_Clear(&actor->colStatus); + next = actor->next; + } + } + } + + play->state.unk_9D = 0xA3; +} + +void Actor_info_draw_actor(PlayState* play, ActorInfo* actorInfo) { + PlayState_unk_2208 temp_s4 = play->unk_2208; + ActorListEntry* actorEntry = actorInfo->actorLists; + ActorPart part = 0; + + if (1) {} + + for (; part < ACTOR_PART_MAX; part++, actorEntry++) { + Actor* actor; + + for (actor = actorEntry->head; actor != NULL; actor = actor->next) { + s32 temp; + + Skin_Matrix_PrjMulVector(&play->viewProjectionMtxF, &actor->world.pos, &actor->projectedPos, + &actor->projectedW); + Actor_cull_check(actor); + + temp = temp_s4(actor, play); + actor->isDrawn = false; + + if (temp != 0) { + continue; + } + + if ((actor->ct != NULL) || (actor->draw == NULL)) { + continue; + } + + if (actor->flags & (ACTOR_FLAG_40 | ACTOR_FLAG_20)) { + if (!(actor->flags & ACTOR_FLAG_80) && (actor->unk_148 == 0) && (actor->unk_149 == 0)) { + Actor_draw(play, actor); + actor->isDrawn = true; + } + } else { + Actor_delete_check(actor, play); + } + } + } + + if (debug_mode->r[0x380] == 0) { + Light_list_point_draw(play); + } +} + +void Actor_info_part_new(ActorInfo* actorInfo, Actor* actor, u8 category) { + Actor* temp_v1; + + actor->part = category; + + actorInfo->unk_00++; + + actorInfo->actorLists[category].unk_0++; + temp_v1 = actorInfo->actorLists[category].head; + if (temp_v1 != NULL) { + temp_v1->prev = actor; + } + + actorInfo->actorLists[category].head = actor; + actor->next = temp_v1; +} + +Actor* Actor_info_part_delete(ActorInfo* actorInfo, Actor* actor) { + Actor* newHead; + + actorInfo->unk_00--; + + actorInfo->actorLists[actor->part].unk_0--; + + if (actor->prev != NULL) { + actor->prev->next = actor->next; + } else { + actorInfo->actorLists[actor->part].head = actor->next; + } + + newHead = actor->next; + if (newHead != NULL) { + newHead->prev = actor->prev; + } + + actor->prev = NULL; + actor->next = NULL; + + return newHead; +} + +void Actor_free_overlay_area(ActorOverlay* overlayEntry) { + if (!(overlayEntry->allocType & ALLOCTYPE_PERMANENT)) { + if (overlayEntry->allocType & ALLOCTYPE_ABSOLUTE) { + overlayEntry->loadedRamAddr = NULL; + } else { + zelda_free(overlayEntry->loadedRamAddr); + overlayEntry->loadedRamAddr = NULL; + } + } +} + +void actor_free_check(ActorOverlay* overlayEntry, u16 fgName) { + if ((overlayEntry->numLoaded == 0) && (overlayEntry->loadedRamAddr != NULL)) { + switch (ACTOR_FGNAME_GET_F000(fgName)) { + case FGNAME_F000_D: + case FGNAME_F000_E: + common_data.unk_1004C->unk_08(); + break; + + case FGNAME_F000_5: + common_data.unk_10098->unk_08(); + break; + + default: + Actor_free_overlay_area(overlayEntry); + break; + } + } +} + +void Actor_get_overlay_area(ActorOverlay* overlayEntry, const struct_801161E8_jp* arg1 UNUSED, size_t overlaySize) { + if (overlayEntry->allocType & ALLOCTYPE_PERMANENT) { + overlayEntry->loadedRamAddr = zelda_malloc_r(overlaySize); + } else { + overlayEntry->loadedRamAddr = zelda_malloc(overlaySize); + } +} + +s32 func_80057940_jp(ActorProfile** profileP, ActorOverlay* overlayEntry, const struct_801161E8_jp* arg2, + size_t overlaySize, u16 fgName) { + if (overlayEntry->vramStart == NULL) { + *profileP = overlayEntry->profile; + } else { + if (overlayEntry->loadedRamAddr == NULL) { + switch (ACTOR_FGNAME_GET_F000(fgName)) { + case FGNAME_F000_D: + case FGNAME_F000_E: + if (common_data.unk_1004C != NULL) { + common_data.unk_1004C->unk_04(overlayEntry, arg2, overlaySize, fgName); + } else { + overlayEntry->loadedRamAddr = NULL; + } + break; + + case FGNAME_F000_5: + if (common_data.unk_10098 != NULL) { + common_data.unk_10098->unk_4(overlayEntry, overlaySize); + } + break; + + default: + Actor_get_overlay_area(overlayEntry, arg2, overlaySize); + break; + } + + if (overlayEntry->loadedRamAddr == NULL) { + return 0; + } + + ovlmgr_Load(overlayEntry->vromStart, overlayEntry->vromEnd, overlayEntry->vramStart, overlayEntry->vramEnd, + overlayEntry->loadedRamAddr); + overlayEntry->numLoaded = 0; + } + + *profileP = (void*)(uintptr_t)((overlayEntry->profile != NULL) + ? (void*)((uintptr_t)overlayEntry->profile - + (intptr_t)((uintptr_t)overlayEntry->vramStart - + (uintptr_t)overlayEntry->loadedRamAddr)) + : NULL); + } + + return 1; +} + +// this function may be Actor_data_bank_regist_check_npc +s32 func_80057A8C_jp(s32* arg0, ActorProfile* profile UNUSED, ActorOverlay* overlayEntry, PlayState* play, u16 fgName) { + s32 pad UNUSED; + s16 sp92; + s16 sp90; + s32 temp_v0; + s32 ret; + + ret = 1; + + { + CommonData_unk_1004C_unk_14_arg0 sp24; + + common_data.unk_1004C->unk_14(&sp24, fgName); + + sp92 = sp24.unk_00; + sp90 = sp24.unk_02; + } + + *arg0 = mSc_bank_regist_check(play->unk_0110, sp92); + temp_v0 = mSc_bank_regist_check(play->unk_0110, sp90); + + if ((*arg0 < 0) || (temp_v0 < 0)) { + if (*arg0 >= 0) { + sp92 = 0; + } + if (temp_v0 >= 0) { + sp90 = 0; + } + common_data.unk_1004C->unk_EC(play->unk_0110, sp92, sp90); + actor_free_check(overlayEntry, fgName); + ret = 0; + } + return ret; +} + +s32 func_80057B70_jp(s32* arg0, ActorProfile* profile, ActorOverlay* overlayEntry, PlayState* play, u16 fgName) { + s32 pad UNUSED; + s32 ret = 1; + + *arg0 = mSc_bank_regist_check(play->unk_0110, profile->objectId); + + if (*arg0 == -1) { + func_800C6144_jp(play->unk_0110, profile->objectId); + actor_free_check(overlayEntry, fgName); + ret = 0; + } + + return ret; +} + +s32 Actor_data_bank_regist_check(s32* arg0, ActorProfile* profile, ActorOverlay* overlayEntry, PlayState* play, + u16 fgName) { + s32 var_v1 = 1; + + if (*arg0 == -1) { + if (profile->part == ACTOR_PART_NPC) { + var_v1 = func_80057A8C_jp(arg0, profile, overlayEntry, play, fgName); + } else { + var_v1 = func_80057B70_jp(arg0, profile, overlayEntry, play, fgName); + } + } + return var_v1; +} + +s32 Actor_malloc_actor_class(Actor** actorP, ActorProfile* profile, ActorOverlay* overlayEntry, + const struct_801161E8_jp* arg3, u16 fgName) { + CommonData_unk_1004C_unk_14_arg0 sp24; + + switch (ACTOR_FGNAME_GET_F000(fgName)) { + case FGNAME_F000_D: + case FGNAME_F000_E: + *actorP = common_data.unk_1004C->unk_0C(profile->instanceSize, arg3, 1); + + //! FAKE + if ((profile != NULL) && (profile != NULL) && (profile != NULL)) {} + + common_data.unk_1004C->unk_14(&sp24, fgName); + break; + + case FGNAME_F000_5: + *actorP = common_data.unk_10098->unk_0C(); + break; + + default: + *actorP = zelda_malloc(profile->instanceSize); + break; + } + + if (*actorP == NULL) { + actor_free_check(overlayEntry, fgName); + return 0; + } + return 1; +} + +void Actor_init_actor_class(Actor* actor, ActorProfile* profile, ActorOverlay* overlayEntry, PlayState* play, s32 arg4, + f32 x, f32 y, f32 z, s16 rotX, s16 rotY, s16 rotZ, s8 argB, s8 argC, s16 argD, u16 fgName, + s16 params) { + mem_clear(actor, profile->instanceSize, 0); + + actor->overlayEntry = overlayEntry; + + actor->name = profile->name; + actor->flags = profile->flags; + + actor->unk_026 = arg4; + + actor->ct = profile->ct; + actor->dt = profile->dt; + actor->update = profile->update; + actor->draw = profile->draw; + actor->save = profile->save; + + actor->params = params; + + actor->unk_004 = play->unk_00E0; + + actor->home.pos.x = x; + actor->home.pos.y = y; + actor->home.pos.z = z; + actor->home.rot.x = rotX; + actor->home.rot.y = rotY; + actor->home.rot.z = rotZ; + + actor->unk_008 = argB; + actor->unk_009 = argC; + actor->unk_00A = argD; + actor->fgName = fgName; +} + +extern const struct_801161E8_jp RO_801161E8_jp; +#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_actor/RO_801161E8_jp.s") + +Actor* Actor_info_make_actor(ActorInfo* actorInfo, PlayState* play, s16 actorId, f32 x, f32 y, f32 z, s16 rotX, + s16 rotY, s16 rotZ, s8 arg9, s8 argA, s16 argB, u16 fgName, s16 params, s8 argE, + s32 argF) { + u16* new_var = &fgName; + Actor* sp68; + ActorProfile* profile; + ActorOverlay* temp_s0 = &actor_dlftbls[actorId]; + size_t size = (uintptr_t)temp_s0->vramEnd - (uintptr_t)temp_s0->vramStart; + + if (actorInfo->unk_00 >= 0xC9) { + return NULL; + } + + if (func_80057940_jp(&profile, temp_s0, &RO_801161E8_jp, size, *new_var) == 0) { + return NULL; + } + if (Actor_data_bank_regist_check(&argF, profile, temp_s0, play, fgName) == 0) { + return NULL; + } + if (Actor_malloc_actor_class(&sp68, profile, temp_s0, &RO_801161E8_jp, fgName) == 0) { + return NULL; + } + + temp_s0->numLoaded++; + Actor_init_actor_class(sp68, profile, temp_s0, play, argF, x, y, z, rotX, rotY, rotZ, arg9, argA, argB, fgName, + params); + + Actor_info_part_new(actorInfo, sp68, profile->part); + + mNpc_SetNpcinfo(sp68, argE); + + { + uintptr_t segmentTemp; + + segmentTemp = gSegments[6]; + Actor_ct(sp68, play); + gSegments[6] = segmentTemp; + } + + return sp68; +} + +Actor* Actor_info_make_child_actor(ActorInfo* actorInfo, Actor* arg1, PlayState* play, s16 actorId, f32 x, f32 y, f32 z, + s16 rotX, s16 rotY, s16 rotZ, s16 argA, u16 fgName, s16 params, s32 argD) { + Actor* temp_v0 = Actor_info_make_actor(actorInfo, play, actorId, x, y, z, rotX, rotY, rotZ, -1, -1, argA, fgName, + params, -1, argD); + + if (temp_v0 != NULL) { + arg1->child = temp_v0; + temp_v0->parent = arg1; + } + + return temp_v0; +} + +void restore_fgdata(Actor* actor, PlayState* play UNUSED) { + Vec3f sp34; + + if ((actor->fgName == 0) || (actor->unk_00A != -1)) { + return; + } + + if ((actor->unk_008 < 0) || (actor->unk_009 < 0)) { + return; + } + + switch (ACTOR_FGNAME_GET_F000(actor->fgName)) { + case FGNAME_F000_8: + xyz_t_move(&sp34, &actor->home.pos); + if (func_8008B3E8_jp(&sp34, 0) == 1) { + mFI_SetFG_common(actor->fgName, sp34, 0); + } + break; + + default: + mFI_SetFG_common(actor->fgName, actor->home.pos, 0); + break; + } +} + +s32 restore_flag[ACTOR_PART_MAX] = { + 1, // ACTOR_PART_0 + 1, // ACTOR_PART_1 + 0, // ACTOR_PART_PLAYER + 0, // ACTOR_PART_NPC + 0, // ACTOR_PART_4 + 0, // ACTOR_PART_5 + 0, // ACTOR_PART_6 + 0, // ACTOR_PART_7 +}; + +void restore_fgdata_one(Actor* actor, PlayState* play) { + if (restore_flag[actor->part] == 1) { + restore_fgdata(actor, play); + } else if (actor->unk_003 == 1) { + restore_fgdata(actor, play); + } +} + +void restore_fgdata_all(PlayState* play) { + ActorInfo* actorInfo = &play->actorInfo; + ActorPart part; + + for (part = 0; part < ACTOR_PART_MAX; part++) { + Actor* actor; + + if (restore_flag[part] == 1) { + for (actor = actorInfo->actorLists[part].head; actor != NULL; actor = actor->next) { + restore_fgdata(actor, play); + } + } else { + for (actor = actorInfo->actorLists[part].head; actor != NULL; actor = actor->next) { + if (actor->unk_003 == 1) { + restore_fgdata(actor, play); + } + } + } + } +} + +void Actor_info_save_actor(PlayState* play) { + ActorInfo* actorInfo = &play->actorInfo; + ActorPart part; + + for (part = 0; part < ACTOR_PART_MAX; part++) { + Actor* actor; + + for (actor = actorInfo->actorLists[part].head; actor != NULL; actor = actor->next) { + if (actor->save != NULL) { + actor->save(actor, play); + actor->save = NULL; + } + } + } + + restore_fgdata_all(play); +} + +Actor* Actor_info_delete(ActorInfo* actorInfo, Actor* actor, PlayState* play) { + Actor* newHead; + s32 pad UNUSED; + ActorOverlay* overlayEntry; + s32 fgName = actor->fgName; + + overlayEntry = actor->overlayEntry; + + restore_fgdata_one(actor, play); + Actor_dt(actor, play); + + newHead = Actor_info_part_delete(actorInfo, actor); + + switch (ACTOR_FGNAME_GET_F000(fgName)) { + case FGNAME_F000_D: + case FGNAME_F000_E: + common_data.unk_1004C->unk_10(actor); + break; + + case FGNAME_F000_5: + common_data.unk_10098->unk_10(actor); + break; + + default: + zelda_free(actor); + break; + } + + if (overlayEntry->vramStart != NULL) { + overlayEntry->numLoaded--; + actor_free_check(overlayEntry, actor->fgName); + } + + return newHead; +} + +Actor* Actor_info_name_search_sub(Actor* actor, s16 name) { + for (; actor != NULL; actor = actor->next) { + if (name == actor->name) { + break; + } + } + return actor; +} + +Actor* Actor_info_name_search(ActorInfo* actorInfo, s16 name, ActorPart part) { + Actor* head = actorInfo->actorLists[part].head; + + if (head != NULL) { + return Actor_info_name_search_sub(head, name); + } + return NULL; +} + +Actor* Actor_info_fgName_search_sub(Actor* actor, u16 fgName) { + for (; actor != NULL; actor = actor->next) { + if (actor->fgName == fgName) { + break; + } + } + + return actor; +} + +Actor* Actor_info_fgName_search(ActorInfo* actorInfo, u16 fgName, ActorPart part) { + Actor* head = actorInfo->actorLists[part].head; + + if (head != NULL) { + return Actor_info_fgName_search_sub(head, fgName); + } + return NULL; +} + +// unused +void Part_Break_init(Part_Break* partBreak, s32 count, s32 arg2 UNUSED) { + size_t matricesSize; + size_t dListsSize; + size_t objectIdsSize; + + matricesSize = (count + 1) * sizeof(MtxF); + partBreak->matrices = zelda_malloc(matricesSize); + if (partBreak->matrices == NULL) { + goto cleanup; + } + + dListsSize = (count + 1) * sizeof(Gfx*); + partBreak->dLists = zelda_malloc(dListsSize); + if (partBreak->dLists == NULL) { + goto cleanup; + } + + objectIdsSize = (count + 1) * sizeof(s16); + partBreak->objectIds = zelda_malloc(objectIdsSize); + if (partBreak->objectIds == NULL) { + goto cleanup; + } + + mem_clear(partBreak->matrices, matricesSize, 0); + mem_clear(partBreak->dLists, dListsSize, 0); + mem_clear(partBreak->objectIds, objectIdsSize, 0); + + partBreak->val = 1; + return; + +cleanup: + if (partBreak->matrices != NULL) { + zelda_free(partBreak->matrices); + } + if (partBreak->dLists != NULL) { + zelda_free(partBreak->dLists); + } + if (partBreak->objectIds != NULL) { + zelda_free(partBreak->objectIds); + } +} + +Mtx B_8011B850_jp; + +Gfx* HiliteReflect_new(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx, Gfx* gfx, Hilite** hilite) { + LookAt* sp64 = GRAPH_ALLOC(gfxCtx, sizeof(LookAt)); + f32 var_fa1 = ((eye->x == object->x) && (eye->z == object->z)) ? (eye->x + 0.001f) : eye->x; + + *hilite = GRAPH_ALLOC(gfxCtx, sizeof(Hilite)); + + guLookAtHilite(&B_8011B850_jp, sp64, *hilite, var_fa1, eye->y, eye->z, object->x, object->y, object->z, 0.0f, 1.0f, + 0.0f, lightDir->x, lightDir->y, lightDir->z, lightDir->x, lightDir->y, lightDir->z, 0x10, 0x10); + + gSPLookAt(gfx++, sp64); + + gDPPipeSync(gfx++); + gDPSetHilite1Tile(gfx++, 1, *hilite, 0x10, 0x10); + + return gfx; +} + +Hilite* HiliteReflect_init(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx) { + Hilite* hilite; + + OPEN_DISPS(gfxCtx); + + POLY_OPA_DISP = HiliteReflect_new(object, eye, lightDir, gfxCtx, POLY_OPA_DISP, &hilite); + + CLOSE_DISPS(gfxCtx); + + return hilite; +} + +Hilite* HiliteReflect_xlu_init(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx) { + Hilite* hilite; + + OPEN_DISPS(gfxCtx); + + POLY_XLU_DISP = HiliteReflect_new(object, eye, lightDir, gfxCtx, POLY_XLU_DISP, &hilite); + + CLOSE_DISPS(gfxCtx); + + return hilite; +} + +Hilite* HiliteReflect_light_init(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx) { + Hilite* hilite; + + OPEN_DISPS(gfxCtx); + + LIGHT_DISP = HiliteReflect_new(object, eye, lightDir, gfxCtx, LIGHT_DISP, &hilite); + + CLOSE_DISPS(gfxCtx); + + return hilite; +} + +Hilite* Setpos_HiliteReflect_init(Vec3f* object, PlayState* play) { + Vec3f sp24; + + sp24.x = play->kankyo.unk_02; + sp24.y = play->kankyo.unk_03; + sp24.z = play->kankyo.unk_04; + return HiliteReflect_init(object, &play->unk_1960, &sp24, play->state.gfxCtx); +} + +Hilite* Setpos_HiliteReflect_xlu_init(Vec3f* object, PlayState* play) { + Vec3f sp24; + + sp24.x = play->kankyo.unk_02; + sp24.y = play->kankyo.unk_03; + sp24.z = play->kankyo.unk_04; + return HiliteReflect_xlu_init(object, &play->unk_1960, &sp24, play->state.gfxCtx); +} + +Hilite* Setpos_HiliteReflect_light_init(Vec3f* object, PlayState* play) { + Vec3f sp24; + + sp24.x = play->kankyo.unk_02; + sp24.y = play->kankyo.unk_03; + sp24.z = play->kankyo.unk_04; + return HiliteReflect_xlu_init(object, &play->unk_1960, &sp24, play->state.gfxCtx); +} |
