From 2cb01b5b6a69635f7c8f554cf97442268aff28be Mon Sep 17 00:00:00 2001 From: engineer124 <47598039+engineer124@users.noreply.github.com> Date: Thu, 23 Mar 2023 09:36:09 +1100 Subject: z_room (1 non-matching) (#1143) * begin room docs and decomp * match Room_DrawImageSingle * match Room_DrawImageMulti * Room_AllocateAndLoad non-matching * big improvements on Room_DrawCullable * match Room_AllocateAndLoad * improvement? * cleanup * comments * cleanup * small pr suggestions * PR Suggestions * cleanup sceneCmds * some PR * PR Suggestions * more PR Suggestions * col to collision --- src/code/PreRender.c | 12 +- src/code/z_actor.c | 2 +- src/code/z_parameter.c | 7 +- src/code/z_play.c | 16 +- src/code/z_player_lib.c | 4 +- src/code/z_room.c | 591 +++++++++++++++++++++++++++++++++++++++++++----- src/code/z_scene.c | 143 ++++++------ 7 files changed, 633 insertions(+), 142 deletions(-) (limited to 'src/code') diff --git a/src/code/PreRender.c b/src/code/PreRender.c index 16ae999c5..075f941d4 100644 --- a/src/code/PreRender.c +++ b/src/code/PreRender.c @@ -53,8 +53,8 @@ void func_8016FDB8(PreRender* this, Gfx** gfxp, void* buf, void* bufSave, u32 ar flags = 0x1C; } - func_80172758(&gfx, buf, NULL, this->width, this->height, G_IM_FMT_RGBA, G_IM_SIZ_16b, G_TT_NONE, 0, 0.0f, 0.0f, - 1.0f, 1.0f, flags); + Prerender_DrawBackground2D(&gfx, buf, NULL, this->width, this->height, G_IM_FMT_RGBA, G_IM_SIZ_16b, G_TT_NONE, 0, + 0.0f, 0.0f, 1.0f, 1.0f, flags); gDPPipeSync(gfx++); gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->fbuf); @@ -89,8 +89,8 @@ void func_8016FF90(PreRender* this, Gfx** gfxp, void* buf, void* bufSave, s32 en gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, this->width, this->height); - func_80172758(&gfx, buf, 0, this->width, this->height, G_IM_FMT_RGBA, G_IM_SIZ_16b, G_TT_NONE, 0, 0.0f, 0.0f, 1.0f, - 1.0f, 0xB); + Prerender_DrawBackground2D(&gfx, buf, 0, this->width, this->height, G_IM_FMT_RGBA, G_IM_SIZ_16b, G_TT_NONE, 0, 0.0f, + 0.0f, 1.0f, 1.0f, 0xB); gDPPipeSync(gfx++); gDPSetColorImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_16b, this->width, this->fbuf); @@ -454,8 +454,8 @@ void func_801720C4(PreRender* this) { #pragma GLOBAL_ASM("asm/non_matchings/code/PreRender/func_801720FC.s") -void func_80172758(Gfx** gfxp, void* timg, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tt, u16 arg8, f32 x, - f32 y, f32 xScale, f32 yScale, u32 flags) { +void Prerender_DrawBackground2D(Gfx** gfxp, void* timg, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tt, + u16 arg8, f32 x, f32 y, f32 xScale, f32 yScale, u32 flags) { PreRenderParams params; PreRenderParams* paramsp = ¶ms; diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 72d330f59..d3eea4ebe 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -1344,7 +1344,7 @@ s32 func_800B715C(PlayState* play) { } void Actor_SetCameraHorseSetting(PlayState* play, Player* player) { - if ((play->roomCtx.curRoom.unk3 != 4) && (player->actor.id == ACTOR_PLAYER)) { + if ((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_4) && (player->actor.id == ACTOR_PLAYER)) { EnHorse* rideActor = (EnHorse*)player->rideActor; if ((rideActor != NULL) && !(rideActor->unk_1EC & 0x10)) { diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c index f3bfb530f..ca127a8b6 100644 --- a/src/code/z_parameter.c +++ b/src/code/z_parameter.c @@ -1767,7 +1767,7 @@ void Interface_UpdateHudAlphas(PlayState* play, s16 dimmingAlpha) { break; } - if ((play->roomCtx.curRoom.unk3 == 1) && (interfaceCtx->minimapAlpha >= 255)) { + if ((play->roomCtx.curRoom.behaviorType1 == ROOM_BEHAVIOR_TYPE1_1) && (interfaceCtx->minimapAlpha >= 255)) { interfaceCtx->minimapAlpha = 255; } } @@ -5096,8 +5096,9 @@ void Interface_Draw(PlayState* play) { // Load in Grandma's Story gSPLoadUcodeL(OVERLAY_DISP++, gspS2DEX2_fifo); gfx = OVERLAY_DISP; - func_80172758(&gfx, sStoryTextures[interfaceCtx->storyType], sStoryTLUTs[interfaceCtx->storyType], - SCREEN_WIDTH, SCREEN_HEIGHT, 2, 1, 0x8000, 0x100, 0.0f, 0.0f, 1.0f, 1.0f, 0); + Prerender_DrawBackground2D(&gfx, sStoryTextures[interfaceCtx->storyType], + sStoryTLUTs[interfaceCtx->storyType], SCREEN_WIDTH, SCREEN_HEIGHT, 2, 1, 0x8000, + 0x100, 0.0f, 0.0f, 1.0f, 1.0f, 0); OVERLAY_DISP = gfx; gSPLoadUcode(OVERLAY_DISP++, SysUcode_GetUCode(), SysUcode_GetUCodeData()); diff --git a/src/code/z_play.c b/src/code/z_play.c index f6a425367..5f8c197f2 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -992,8 +992,8 @@ void Play_UpdateMain(PlayState* this) { Rumble_SetUpdateEnabled(false); } - Room_nop8012D510(this, &this->roomCtx.curRoom, &input[1], 0); - Room_nop8012D510(this, &this->roomCtx.prevRoom, &input[1], 1); + Room_Noop(this, &this->roomCtx.curRoom, &input[1], 0); + Room_Noop(this, &this->roomCtx.prevRoom, &input[1], 1); Skybox_Update(&this->skyboxCtx); if ((this->pauseCtx.state != 0) || (this->pauseCtx.debugEditor != DEBUG_EDITOR_NONE)) { @@ -1127,7 +1127,7 @@ void Play_DrawMain(PlayState* this) { } if ((R_PAUSE_BG_PRERENDER_STATE <= PAUSE_BG_PRERENDER_SETUP) && (gTransitionTileState <= TRANS_TILE_SETUP)) { - if (this->skyboxCtx.skyboxShouldDraw || (this->roomCtx.curRoom.mesh->type0.type == 1)) { + if (this->skyboxCtx.skyboxShouldDraw || (this->roomCtx.curRoom.roomShape->base.type == ROOM_SHAPE_TYPE_IMAGE)) { func_8012CF0C(gfxCtx, false, true, 0, 0, 0); } else { func_8012CF0C(gfxCtx, true, true, this->lightCtx.fogColor.r, this->lightCtx.fogColor.g, @@ -1573,7 +1573,7 @@ void Play_InitScene(PlayState* this, s32 spawn) { Door_InitContext(&this->state, &this->doorCtx); Room_Init(this, &this->roomCtx); gSaveContext.worldMapArea = 0; - Scene_ProcessHeader(this, this->sceneSegment); + Scene_ExecuteCommands(this, this->sceneSegment); Play_InitEnvironment(this, this->skyboxId); } @@ -1940,11 +1940,10 @@ void func_80169FDC(GameState* thisx) { func_80169F78(thisx); } -// Used by Kankyo to determine how to change the lighting, e.g. for game over. -s32 func_80169FFC(GameState* thisx) { +s32 Play_CamIsNotFixed(GameState* thisx) { PlayState* this = (PlayState*)thisx; - return this->roomCtx.curRoom.mesh->type0.type != 1; + return this->roomCtx.curRoom.roomShape->base.type != ROOM_SHAPE_TYPE_IMAGE; } s32 FrameAdvance_IsEnabled(GameState* thisx) { @@ -2304,7 +2303,8 @@ void Play_Init(GameState* thisx) { while (!Room_HandleLoadCallbacks(this, &this->roomCtx)) {} - if ((CURRENT_DAY != 0) && ((this->roomCtx.curRoom.unk3 == 1) || (this->roomCtx.curRoom.unk3 == 5))) { + if ((CURRENT_DAY != 0) && ((this->roomCtx.curRoom.behaviorType1 == ROOM_BEHAVIOR_TYPE1_1) || + (this->roomCtx.curRoom.behaviorType1 == ROOM_BEHAVIOR_TYPE1_5))) { Actor_Spawn(&this->actorCtx, this, ACTOR_EN_TEST4, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0); } diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index 4bdd22e0a..6e7d0222c 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -441,7 +441,7 @@ void func_80123140(PlayState* play, Player* player) { IREG(69) = bootRegs[16]; MREG(95) = bootRegs[17]; - if (play->roomCtx.curRoom.unk3 == 2) { + if (play->roomCtx.curRoom.behaviorType1 == ROOM_BEHAVIOR_TYPE1_2) { R_RUN_SPEED_LIMIT = 500; } @@ -1456,7 +1456,7 @@ s32 Player_GetEnvironmentalHazard(PlayState* play) { EnvHazardTextTriggerEntry* triggerEntry; s32 envHazard; - if (play->roomCtx.curRoom.unk2 == 3) { // Room is hot + if (play->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_HOT) { envHazard = PLAYER_ENV_HAZARD_HOTROOM - 1; } else if ((player->transformation != PLAYER_FORM_ZORA) && (player->underwaterTimer > 80)) { envHazard = PLAYER_ENV_HAZARD_UNDERWATER_FREE - 1; diff --git a/src/code/z_room.c b/src/code/z_room.c index eb615c409..3358bb300 100644 --- a/src/code/z_room.c +++ b/src/code/z_room.c @@ -1,62 +1,481 @@ #include "global.h" -void Room_nop8012D510(PlayState* play, Room* room, UNK_PTR param_3, UNK_TYPE1 param_4) { +void Room_Noop(PlayState* play, Room* room, Input* input, s32 arg3) { } -void Room_DrawType3Mesh(PlayState* play, Room* room, u32 flags) { +void Room_DrawNone(PlayState* play, Room* room, u32 flags) { } -void Room_DrawType0Mesh(PlayState* play, Room* room, u32 flags) { - RoomMeshType0* mesh; +static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f }; + +void Room_DrawNormal(PlayState* play, Room* room, u32 flags) { + RoomShapeNormal* roomShape; + RoomShapeDListsEntry* entry; s32 i; - RoomMeshType0Params* meshParams; - GraphicsContext* gfxCtx; - UNK_TYPE4 pad; - - gfxCtx = play->state.gfxCtx; - if (flags & 1) { - func_800BCBF4(&D_801C1D10, play); - gSPSegment(gfxCtx->polyOpa.p++, 0x03, room->segment); + + OPEN_DISPS(play->state.gfxCtx); + + if (flags & ROOM_DRAW_OPA) { + func_800BCBF4(&sZeroVec, play); + gSPSegment(POLY_OPA_DISP++, 0x03, room->segment); func_8012C268(play); - gSPMatrix(gfxCtx->polyOpa.p++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(POLY_OPA_DISP++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); } - if (flags & 2) { - func_800BCC68(&D_801C1D10, play); - gSPSegment(gfxCtx->polyXlu.p++, 0x03, room->segment); + if (flags & ROOM_DRAW_XLU) { + func_800BCC68(&sZeroVec, play); + gSPSegment(POLY_XLU_DISP++, 0x03, room->segment); func_8012C2DC(play->state.gfxCtx); - gSPMatrix(gfxCtx->polyXlu.p++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); } - mesh = &room->mesh->type0; - meshParams = Lib_SegmentedToVirtual(mesh->paramsStart); - for (i = 0; i < mesh->count; i++) { - if ((flags & 1) && (meshParams->opaqueDl != NULL)) { - gSPDisplayList(gfxCtx->polyOpa.p++, meshParams->opaqueDl); + roomShape = &room->roomShape->normal; + entry = Lib_SegmentedToVirtual(roomShape->entries); + for (i = 0; i < roomShape->numEntries; i++) { + if ((flags & ROOM_DRAW_OPA) && (entry->opa != NULL)) { + gSPDisplayList(POLY_OPA_DISP++, entry->opa); } - if ((flags & 2) && (meshParams->translucentDl != NULL)) { - gSPDisplayList(gfxCtx->polyXlu.p++, meshParams->translucentDl); + if ((flags & ROOM_DRAW_XLU) && (entry->xlu != NULL)) { + gSPDisplayList(POLY_XLU_DISP++, entry->xlu); } - meshParams++; + entry++; } + + CLOSE_DISPS(play->state.gfxCtx); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/Room_DrawType2Mesh.s") +typedef enum { + /* 0 */ ROOM_CULL_DEBUG_MODE_OFF, + /* 1 */ ROOM_CULL_DEBUG_MODE_UP_TO_TARGET, + /* 2 */ ROOM_CULL_DEBUG_MODE_ONLY_TARGET +} RoomCullableDebugMode; + +typedef struct RoomShapeCullableEntryLinked { + /* 0x00 */ RoomShapeCullableEntry* entry; + /* 0x04 */ f32 boundsNearZ; + /* 0x08 */ struct RoomShapeCullableEntryLinked* prev; + /* 0x0C */ struct RoomShapeCullableEntryLinked* next; +} RoomShapeCullableEntryLinked; // size = 0x10 + +// TODO: 127 is an arbitrarily chosen number to make the stack sorta work +#define ROOM_SHAPE_CULLABLE_MAX_ENTRIES 127 + +#ifdef NON_MATCHING +// Small regalloc, likely related to temp usage and scoping +void Room_DrawCullable(PlayState* play, Room* room, u32 flags) { + RoomShapeCullable* roomShape; + RoomShapeCullableEntry* roomShapeCullableEntry; + RoomShapeCullableEntry* roomShapeCullableEntries; + RoomShapeCullableEntry* roomShapeCullableEntryIter; + Gfx* displayList; + f32 entryBoundsNearZ; + RoomShapeCullableEntryLinked linkedEntriesBuffer[ROOM_SHAPE_CULLABLE_MAX_ENTRIES]; + RoomShapeCullableEntryLinked* head = NULL; + RoomShapeCullableEntryLinked* tail = NULL; + s32 var_a1; + RoomShapeCullableEntryLinked* iter; + RoomShapeCullableEntryLinked* insert; + f32 var_fv1; + s32 i; + Vec3f pos; + Vec3f projectedPos; + s32 pad2; + + OPEN_DISPS(play->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/func_8012DEE8.s") + if (flags & ROOM_DRAW_OPA) { + func_800BCBF4(&sZeroVec, play); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/func_8012E254.s") + //! TODO: Fake + if (1) {} + if (1) {} + if (1) {} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/func_8012E32C.s") + gSPSegment(POLY_OPA_DISP++, 0x03, room->segment); + if (play->roomCtx.unk74 != NULL) { + gSPSegment(POLY_OPA_DISP++, 0x06, play->roomCtx.unk74); + } + func_8012C268(play); + gSPMatrix(POLY_OPA_DISP++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); + } + + if (flags & ROOM_DRAW_XLU) { + func_800BCC68(&sZeroVec, play); + gSPSegment(POLY_XLU_DISP++, 0x03, room->segment); + if (play->roomCtx.unk74 != NULL) { + gSPSegment(POLY_XLU_DISP++, 0x06, play->roomCtx.unk74); + } + func_8012C2DC(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); + } + + if ((room->enablePosLights != 0) || (MREG(93) != 0)) { + gSPSetGeometryMode(POLY_OPA_DISP++, G_LIGHTING_POSITIONAL); + gSPSetGeometryMode(POLY_XLU_DISP++, G_LIGHTING_POSITIONAL); + } -void Room_DrawType1Mesh(PlayState* play, Room* room, u32 flags) { - RoomMeshType1* mesh = &room->mesh->type1; - if (mesh->format == 1) { - func_8012DEE8(play, room, flags); - } else if (mesh->format == 2) { - func_8012E32C(play, room, flags); + roomShape = &room->roomShape->cullable; + roomShapeCullableEntry = Lib_SegmentedToVirtual(roomShape->entries); + insert = linkedEntriesBuffer; + + roomShapeCullableEntries = roomShapeCullableEntry; + + if (play->roomCtx.unk78 < 0) { + for (i = 0; i < roomShape->numEntries; i++, roomShapeCullableEntry++) { + if (R_ROOM_CULL_DEBUG_MODE != 0) { + if (((R_ROOM_CULL_DEBUG_MODE == ROOM_CULL_DEBUG_MODE_UP_TO_TARGET) && + (i <= R_ROOM_CULL_DEBUG_TARGET)) || + ((R_ROOM_CULL_DEBUG_MODE == ROOM_CULL_DEBUG_MODE_ONLY_TARGET) && (i == R_ROOM_CULL_DEBUG_TARGET))) { + if (flags & ROOM_DRAW_OPA) { + displayList = roomShapeCullableEntry->opa; + if (displayList != NULL) { + gSPDisplayList(POLY_OPA_DISP++, displayList); + } + } + + if (flags & ROOM_DRAW_XLU) { + displayList = roomShapeCullableEntry->xlu; + if (displayList != NULL) { + gSPDisplayList(POLY_XLU_DISP++, displayList); + } + } + } + } else { + if (flags & ROOM_DRAW_OPA) { + displayList = roomShapeCullableEntry->opa; + if (displayList != NULL) { + gSPDisplayList(POLY_OPA_DISP++, displayList); + } + } + + if (flags & ROOM_DRAW_XLU) { + displayList = roomShapeCullableEntry->xlu; + if (displayList != NULL) { + gSPDisplayList(POLY_XLU_DISP++, displayList); + } + } + } + } + } else { + f32 var_fa1 = 1.0f / play->projectionMtxFDiagonal.z; // sp54 + s32 pad5; + + // Pick and sort entries by depth + for (i = 0; i < roomShape->numEntries; i++, roomShapeCullableEntry++) { + + // Project the entry position, to get the depth it is at. + pos.x = roomShapeCullableEntry->boundsSphereCenter.x; + pos.y = roomShapeCullableEntry->boundsSphereCenter.y; + pos.z = roomShapeCullableEntry->boundsSphereCenter.z; + SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &pos, &projectedPos); + + projectedPos.z *= var_fa1; + + var_fv1 = ABS_ALT(roomShapeCullableEntry->boundsSphereRadius); + + // If the entry bounding sphere isn't fully before the rendered depth range + if (-var_fv1 < projectedPos.z) { + + // Compute the depth of the nearest point in the entry's bounding sphere + entryBoundsNearZ = projectedPos.z - var_fv1; + + // If the entry bounding sphere isn't fully beyond the rendered depth range + if (entryBoundsNearZ < play->lightCtx.zFar) { + + // This entry will be rendered + insert->entry = roomShapeCullableEntry; + + if (roomShapeCullableEntry->boundsSphereRadius < 0) { + insert->boundsNearZ = FLT_MAX; + } else { + insert->boundsNearZ = entryBoundsNearZ; + } + + // Insert into the linked list, ordered by ascending depth of the nearest point in the bounding + // sphere + iter = head; + if (iter == NULL) { + head = tail = insert; + insert->prev = insert->next = NULL; + } else { + do { + if (insert->boundsNearZ < iter->boundsNearZ) { + break; + } + iter = iter->next; + } while (iter != NULL); + + if (iter == NULL) { + insert->prev = tail; + insert->next = NULL; + tail->next = insert; + tail = insert; + } else { + insert->prev = iter->prev; + if (insert->prev == NULL) { + head = insert; + } else { + insert->prev->next = insert; + } + iter->prev = insert; + insert->next = iter; + } + } + + insert++; + } + } + } + + //! FAKE: Similar trick used in OoT + R_ROOM_CULL_NUM_ENTRIES = roomShape->numEntries & 0xFFFF & 0xFFFF & 0xFFFF; + + // Draw entries, from nearest to furthest + i = 1; + + if (flags & ROOM_DRAW_OPA) { + for (; head != NULL; head = head->next, i++) { + s32 pad3; + RoomShapeCullableEntry* roomShapeCullableEntry; + + roomShapeCullableEntry = head->entry; + + if (R_ROOM_CULL_DEBUG_MODE != ROOM_CULL_DEBUG_MODE_OFF) { + // Debug mode drawing + + if (((R_ROOM_CULL_DEBUG_MODE == ROOM_CULL_DEBUG_MODE_UP_TO_TARGET) && + (i <= R_ROOM_CULL_DEBUG_TARGET)) || + ((R_ROOM_CULL_DEBUG_MODE == ROOM_CULL_DEBUG_MODE_ONLY_TARGET) && + (i == R_ROOM_CULL_DEBUG_TARGET))) { + + displayList = roomShapeCullableEntry->opa; + if (displayList != NULL) { + gSPDisplayList(POLY_OPA_DISP++, displayList); + } + } + } else { + displayList = roomShapeCullableEntry->opa; + if (displayList != NULL) { + gSPDisplayList(POLY_OPA_DISP++, displayList); + } + } + } + } + + if (flags & ROOM_DRAW_XLU) { + for (; head != NULL; head = head->prev) { + f32 temp_fv0; + f32 temp_fv1; + + roomShapeCullableEntry = head->entry; + displayList = roomShapeCullableEntry->xlu; + + if (displayList != NULL) { + if (roomShapeCullableEntry->boundsSphereRadius & 1) { + + temp_fv0 = head->boundsNearZ - (f32)(iREG(93) + 0xBB8); + temp_fv1 = iREG(94) + 0x7D0; + + if (temp_fv0 < temp_fv1) { + if (temp_fv0 < 0.0f) { + var_a1 = 255; + } else { + var_a1 = 255 - (s32)((temp_fv0 / temp_fv1) * 255.0f); + } + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, var_a1); + gSPDisplayList(POLY_XLU_DISP++, displayList); + } + } else { + gSPDisplayList(POLY_XLU_DISP++, displayList); + } + } + } + } + + R_ROOM_CULL_USED_ENTRIES = i - 1; + } + + CLOSE_DISPS(play->state.gfxCtx); +} +#else +void Room_DrawCullable(PlayState* play, Room* room, u32 flags); +#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/Room_DrawCullable.s") +#endif + +#define ROOM_IMAGE_NODRAW_BACKGROUND (1 << 0) +#define ROOM_IMAGE_NODRAW_OPA (1 << 1) +#define ROOM_IMAGE_NODRAW_XLU (1 << 2) + +void Room_DrawImageSingle(PlayState* play, Room* room, u32 flags) { + Camera* activeCam; + Gfx* gfx; + RoomShapeImageSingle* roomShape; + RoomShapeDListsEntry* entry; + u32 isFixedCamera; + u32 drawBackground; + u32 drawOpa; + u32 drawXlu; + + OPEN_DISPS(play->state.gfxCtx); + + activeCam = GET_ACTIVE_CAM(play); + isFixedCamera = false; // Condition is inferred from OoT + roomShape = &room->roomShape->image.single; + entry = Lib_SegmentedToVirtual(roomShape->base.entry); + drawBackground = (flags & ROOM_DRAW_OPA) && isFixedCamera && (roomShape->source != NULL) && + !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_BACKGROUND); + drawOpa = (flags & ROOM_DRAW_OPA) && (entry->opa != NULL) && !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_OPA); + drawXlu = (flags & ROOM_DRAW_XLU) && (entry->xlu != NULL) && !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_XLU); + + if (drawOpa || drawBackground) { + gSPSegment(POLY_OPA_DISP++, 0x03, room->segment); + + if (drawOpa) { + func_8012C28C(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, entry->opa); + } + + if (drawBackground) { + gSPLoadUcodeL(POLY_OPA_DISP++, gspS2DEX2_fifo); + + gfx = POLY_OPA_DISP; + + { + Vec3f quakeOffset; + + Camera_GetQuakeOffset(&quakeOffset, activeCam); + + Prerender_DrawBackground2D( + &gfx, roomShape->source, roomShape->tlut, roomShape->width, roomShape->height, roomShape->fmt, + roomShape->siz, roomShape->tlutMode, roomShape->tlutCount, + (quakeOffset.x + quakeOffset.z) * 1.2f + quakeOffset.y * 0.6f, + quakeOffset.y * 2.4f + (quakeOffset.x + quakeOffset.z) * 0.3f, 1.0f, 1.0f, 0); + } + + POLY_OPA_DISP = gfx; + + gSPLoadUcode(POLY_OPA_DISP++, SysUcode_GetUCode(), SysUcode_GetUCodeData()); + } + } + + if (drawXlu) { + gSPSegment(POLY_XLU_DISP++, 0x03, room->segment); + func_8012C2DC(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_XLU_DISP++, entry->xlu); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +RoomShapeImageMultiBgEntry* Room_GetImageMultiBgEntry(RoomShapeImageMulti* roomShapeImageMulti, PlayState* play) { + Camera* activeCam = GET_ACTIVE_CAM(play); + s32 bgCamIndex = activeCam->bgCamDataId; + s16 overrideBgCamIndex; + Player* player; + RoomShapeImageMultiBgEntry* bgEntry; + s32 i; + + overrideBgCamIndex = ((BgCamFuncData*)BgCheck_GetBgCamFuncDataImpl(&play->colCtx, bgCamIndex, BGCHECK_SCENE)) + ->roomImageOverrideBgCamIndex; + if (overrideBgCamIndex >= 0) { + bgCamIndex = overrideBgCamIndex; + } + + player = GET_PLAYER(play); + player->actor.params = (player->actor.params & 0xFF00) | bgCamIndex; + + bgEntry = Lib_SegmentedToVirtual(roomShapeImageMulti->backgrounds); + for (i = 0; i < roomShapeImageMulti->numBackgrounds; i++) { + if (bgEntry->bgCamIndex == bgCamIndex) { + return bgEntry; + } + bgEntry++; + } + + __assert("../z_room.c", 849); + + return NULL; +} + +void Room_DrawImageMulti(PlayState* play, Room* room, u32 flags) { + Camera* activeCam; + Gfx* gfx; + RoomShapeImageMulti* roomShape; + RoomShapeImageMultiBgEntry* bgEntry; + RoomShapeDListsEntry* dListsEntry; + u32 isFixedCamera; + u32 drawBackground; + u32 drawOpa; + u32 drawXlu; + + OPEN_DISPS(play->state.gfxCtx); + + activeCam = GET_ACTIVE_CAM(play); + isFixedCamera = false; // Condition is inferred from OoT + roomShape = &room->roomShape->image.multi; + dListsEntry = Lib_SegmentedToVirtual(roomShape->base.entry); + + bgEntry = Room_GetImageMultiBgEntry(roomShape, play); + + drawBackground = (flags & ROOM_DRAW_OPA) && isFixedCamera && (bgEntry->source != NULL) && + !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_BACKGROUND); + drawOpa = + (flags & ROOM_DRAW_OPA) && (dListsEntry->opa != NULL) && !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_OPA); + drawXlu = + (flags & ROOM_DRAW_XLU) && (dListsEntry->xlu != NULL) && !(R_ROOM_IMAGE_NODRAW_FLAGS & ROOM_IMAGE_NODRAW_XLU); + + if (drawOpa || drawBackground) { + gSPSegment(POLY_OPA_DISP++, 0x03, room->segment); + + if (drawOpa) { + func_8012C28C(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, dListsEntry->opa); + } + + if (drawBackground) { + gSPLoadUcodeL(POLY_OPA_DISP++, gspS2DEX2_fifo); + + gfx = POLY_OPA_DISP; + + { + Vec3f quakeOffset; + + Camera_GetQuakeOffset(&quakeOffset, activeCam); + Prerender_DrawBackground2D(&gfx, bgEntry->source, bgEntry->tlut, bgEntry->width, bgEntry->height, + bgEntry->fmt, bgEntry->siz, bgEntry->tlutMode, bgEntry->tlutCount, + (quakeOffset.x + quakeOffset.z) * 1.2f + quakeOffset.y * 0.6f, + quakeOffset.y * 2.4f + (quakeOffset.x + quakeOffset.z) * 0.3f, 1.0f, 1.0f, + 0); + } + + POLY_OPA_DISP = gfx; + + gSPLoadUcode(POLY_OPA_DISP++, SysUcode_GetUCode(), SysUcode_GetUCodeData()); + } + } + + if (drawXlu) { + gSPSegment(POLY_XLU_DISP++, 0x03, room->segment); + func_8012C2DC(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_XLU_DISP++, dListsEntry->xlu); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +void Room_DrawImage(PlayState* play, Room* room, u32 flags) { + RoomShapeImageBase* roomShape = &room->roomShape->image.base; + + if (roomShape->amountType == ROOM_SHAPE_IMAGE_AMOUNT_SINGLE) { + Room_DrawImageSingle(play, room, flags); + } else if (roomShape->amountType == ROOM_SHAPE_IMAGE_AMOUNT_MULTI) { + Room_DrawImageMulti(play, room, flags); } else { __assert("../z_room.c", 965); } @@ -64,31 +483,96 @@ void Room_DrawType1Mesh(PlayState* play, Room* room, u32 flags) { void Room_Init(PlayState* play, RoomContext* roomCtx) { s32 i; + roomCtx->curRoom.num = -1; roomCtx->curRoom.segment = NULL; roomCtx->unk78 = 1; roomCtx->unk79 = 0; - for (i = 0; i < 3; i++) { + for (i = 0; i < ARRAY_COUNT(roomCtx->unk7A); i++) { roomCtx->unk7A[i] = 0; } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/Room_AllocateAndLoad.s") +size_t Room_AllocateAndLoad(PlayState* play, RoomContext* roomCtx) { + size_t maxRoomSize = 0; + size_t roomSize; + s32 i; + s32 j; + s32 frontRoom; + s32 backRoom; + size_t frontRoomSize; + size_t backRoomSize; + size_t cumulRoomSize; + s32 pad[2]; + + { + RomFile* roomList = play->roomList; + + for (i = 0; i < play->numRooms; i++) { + roomSize = roomList[i].vromEnd - roomList[i].vromStart; + maxRoomSize = MAX(roomSize, maxRoomSize); + } + } + + if ((u32)play->doorCtx.numTransitionActors != 0) { + RomFile* roomList = play->roomList; + TransitionActorEntry* transitionActor = &play->doorCtx.transitionActorList[0]; + + for (j = 0; j < play->doorCtx.numTransitionActors; j++) { + frontRoom = transitionActor->sides[0].room; + backRoom = transitionActor->sides[1].room; + frontRoomSize = (frontRoom < 0) ? 0 : roomList[frontRoom].vromEnd - roomList[frontRoom].vromStart; + backRoomSize = (backRoom < 0) ? 0 : roomList[backRoom].vromEnd - roomList[backRoom].vromStart; + cumulRoomSize = (frontRoom != backRoom) ? frontRoomSize + backRoomSize : frontRoomSize; + + maxRoomSize = MAX(cumulRoomSize, maxRoomSize); + transitionActor++; + } + } + + roomCtx->roomMemPages[0] = THA_AllocEndAlign16(&play->state.heap, maxRoomSize); + if (roomCtx->roomMemPages[0] == NULL) { + __assert("../z_room.c", 1078); + } + roomCtx->roomMemPages[1] = (void*)((uintptr_t)roomCtx->roomMemPages[0] + maxRoomSize); + roomCtx->activeMemPage = 0; + roomCtx->status = 0; + + if ((gSaveContext.respawnFlag != 0) && (gSaveContext.respawnFlag != -2) && (gSaveContext.respawnFlag != -7)) { + s32 respawnMode; + + if ((gSaveContext.respawnFlag == -8) || (gSaveContext.respawnFlag == -5) || (gSaveContext.respawnFlag == -4) || + ((gSaveContext.respawnFlag < 0) && (gSaveContext.respawnFlag != -1) && (gSaveContext.respawnFlag != -6))) { + respawnMode = RESPAWN_MODE_DOWN; + } else if (gSaveContext.respawnFlag < 0) { + respawnMode = RESPAWN_MODE_TOP; + } else { + respawnMode = gSaveContext.respawnFlag - 1; + } + frontRoom = gSaveContext.respawn[respawnMode].roomIndex; + } else { + frontRoom = play->setupEntranceList[play->curSpawn].room; + } + + Room_StartRoomTransition(play, roomCtx, frontRoom); + + return maxRoomSize; +} s32 Room_StartRoomTransition(PlayState* play, RoomContext* roomCtx, s32 index) { - if (roomCtx->unk31 == 0) { - s32 size; + if (roomCtx->status == 0) { + size_t size; roomCtx->prevRoom = roomCtx->curRoom; roomCtx->curRoom.num = index; roomCtx->curRoom.segment = NULL; - roomCtx->unk31 = 1; + roomCtx->status = 1; size = play->roomList[index].vromEnd - play->roomList[index].vromStart; - roomCtx->activeRoomVram = (void*)(ALIGN16((u32)roomCtx->roomMemPages[roomCtx->activeMemPage] - + roomCtx->activeRoomVram = (void*)(ALIGN16((uintptr_t)roomCtx->roomMemPages[roomCtx->activeMemPage] - (size + 8) * roomCtx->activeMemPage - 7)); - osCreateMesgQueue(&roomCtx->loadQueue, roomCtx->loadMsg, 1); + osCreateMesgQueue(&roomCtx->loadQueue, roomCtx->loadMsg, ARRAY_COUNT(roomCtx->loadMsg)); DmaMgr_SendRequestImpl(&roomCtx->dmaRequest, roomCtx->activeRoomVram, play->roomList[index].vromStart, size, 0, &roomCtx->loadQueue, NULL); roomCtx->activeMemPage ^= 1; @@ -100,14 +584,13 @@ s32 Room_StartRoomTransition(PlayState* play, RoomContext* roomCtx, s32 index) { } s32 Room_HandleLoadCallbacks(PlayState* play, RoomContext* roomCtx) { - if (roomCtx->unk31 == 1) { - if (!osRecvMesg(&roomCtx->loadQueue, NULL, OS_MESG_NOBLOCK)) { - roomCtx->unk31 = 0; + if (roomCtx->status == 1) { + if (osRecvMesg(&roomCtx->loadQueue, NULL, OS_MESG_NOBLOCK) == 0) { + roomCtx->status = 0; roomCtx->curRoom.segment = roomCtx->activeRoomVram; - // TODO: Segment number enum - gSegments[0x03] = VIRTUAL_TO_PHYSICAL(roomCtx->activeRoomVram); + gSegments[3] = VIRTUAL_TO_PHYSICAL(roomCtx->activeRoomVram); - Scene_ProcessHeader(play, (SceneCmd*)roomCtx->curRoom.segment); + Scene_ExecuteCommands(play, roomCtx->curRoom.segment); func_80123140(play, GET_PLAYER(play)); Actor_SpawnTransitionActors(play, &play->actorCtx); @@ -127,11 +610,17 @@ s32 Room_HandleLoadCallbacks(PlayState* play, RoomContext* roomCtx) { return 1; } +RoomDrawHandler sRoomDrawHandlers[] = { + Room_DrawNormal, // ROOM_SHAPE_TYPE_NORMAL + Room_DrawImage, // ROOM_SHAPE_TYPE_IMAGE + Room_DrawCullable, // ROOM_SHAPE_TYPE_CULLABLE + Room_DrawNone, // ROOM_SHAPE_TYPE_NONE +}; + void Room_Draw(PlayState* play, Room* room, u32 flags) { if (room->segment != NULL) { - // TODO: Segment number enum - gSegments[0x03] = VIRTUAL_TO_PHYSICAL(room->segment); - roomDrawFuncs[room->mesh->type0.type](play, room, flags); + gSegments[3] = VIRTUAL_TO_PHYSICAL(room->segment); + sRoomDrawHandlers[room->roomShape->base.type](play, room, flags); } return; } diff --git a/src/code/z_scene.c b/src/code/z_scene.c index 1f431d0e4..13d93c515 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -141,7 +141,7 @@ void* func_8012F73C(ObjectContext* objectCtx, s32 iParm2, s16 id) { } // SceneTableEntry Header Command 0x00: Spawn List -void Scene_HeaderCmdSpawnList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandSpawnList(PlayState* play, SceneCmd* cmd) { s32 loadedCount; s16 playerObjectId; void* nextObject; @@ -168,19 +168,19 @@ void Scene_HeaderCmdSpawnList(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x01: Actor List -void Scene_HeaderCmdActorList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandActorList(PlayState* play, SceneCmd* cmd) { play->numSetupActors = cmd->actorList.num; play->setupActorList = Lib_SegmentedToVirtual(cmd->actorList.segment); play->actorCtx.halfDaysBit = 0; } // SceneTableEntry Header Command 0x02: List of camera data for actor cutscenes -void Scene_HeaderCmdActorCutsceneCamList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandActorCutsceneCamList(PlayState* play, SceneCmd* cmd) { play->actorCsCamList = Lib_SegmentedToVirtual(cmd->actorCsCamList.segment); } // SceneTableEntry Header Command 0x03: Collision Header -void Scene_HeaderCmdColHeader(PlayState* play, SceneCmd* cmd) { +void Scene_CommandCollisionHeader(PlayState* play, SceneCmd* cmd) { CollisionHeader* colHeaderTemp; CollisionHeader* colHeader; @@ -205,18 +205,18 @@ void Scene_HeaderCmdColHeader(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x04: Room List -void Scene_HeaderCmdRoomList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandRoomList(PlayState* play, SceneCmd* cmd) { play->numRooms = cmd->roomList.num; play->roomList = Lib_SegmentedToVirtual(cmd->roomList.segment); } // SceneTableEntry Header Command 0x06: Entrance List -void Scene_HeaderCmdEntranceList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandEntranceList(PlayState* play, SceneCmd* cmd) { play->setupEntranceList = Lib_SegmentedToVirtual(cmd->entranceList.segment); } // SceneTableEntry Header Command 0x07: Special Files -void Scene_HeaderCmdSpecialFiles(PlayState* play, SceneCmd* cmd) { +void Scene_CommandSpecialFiles(PlayState* play, SceneCmd* cmd) { // @note These quest hint files are identical to OoT's. // They are not relevant in this game and the system to process these scripts has been removed. static RomFile naviQuestHintFiles[2] = { @@ -236,9 +236,9 @@ void Scene_HeaderCmdSpecialFiles(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x08: Room Behavior -void Scene_HeaderCmdRoomBehavior(PlayState* play, SceneCmd* cmd) { - play->roomCtx.curRoom.unk3 = cmd->roomBehavior.gpFlag1; - play->roomCtx.curRoom.unk2 = cmd->roomBehavior.gpFlag2 & 0xFF; +void Scene_CommandRoomBehavior(PlayState* play, SceneCmd* cmd) { + play->roomCtx.curRoom.behaviorType1 = cmd->roomBehavior.gpFlag1; + play->roomCtx.curRoom.behaviorType2 = cmd->roomBehavior.gpFlag2 & 0xFF; play->roomCtx.curRoom.lensMode = (cmd->roomBehavior.gpFlag2 >> 8) & 1; play->msgCtx.unk12044 = (cmd->roomBehavior.gpFlag2 >> 0xA) & 1; play->roomCtx.curRoom.enablePosLights = (cmd->roomBehavior.gpFlag2 >> 0xB) & 1; @@ -246,12 +246,12 @@ void Scene_HeaderCmdRoomBehavior(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x0A: Mesh Header -void Scene_HeaderCmdMesh(PlayState* play, SceneCmd* cmd) { - play->roomCtx.curRoom.mesh = Lib_SegmentedToVirtual(cmd->mesh.segment); +void Scene_CommandMesh(PlayState* play, SceneCmd* cmd) { + play->roomCtx.curRoom.roomShape = Lib_SegmentedToVirtual(cmd->mesh.segment); } // SceneTableEntry Header Command 0x0B: Object List -void Scene_HeaderCmdObjectList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandObjectList(PlayState* play, SceneCmd* cmd) { s32 i; s32 j; s32 k; @@ -304,7 +304,7 @@ void Scene_HeaderCmdObjectList(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x0C: Light List -void Scene_HeaderCmdLightList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandLightList(PlayState* play, SceneCmd* cmd) { s32 i; LightInfo* lightInfo = Lib_SegmentedToVirtual(cmd->lightList.segment); @@ -315,12 +315,12 @@ void Scene_HeaderCmdLightList(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x0D: Path List -void Scene_HeaderCmdPathList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandPathList(PlayState* play, SceneCmd* cmd) { play->setupPathList = Lib_SegmentedToVirtual(cmd->pathList.segment); } // SceneTableEntry Header Command 0x0E: Transition Actor List -void Scene_HeaderCmdTransiActorList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandTransiActorList(PlayState* play, SceneCmd* cmd) { play->doorCtx.numTransitionActors = cmd->transiActorList.num; play->doorCtx.transitionActorList = Lib_SegmentedToVirtual(cmd->transiActorList.segment); func_80105818(play, play->doorCtx.numTransitionActors, play->doorCtx.transitionActorList); @@ -332,7 +332,7 @@ void Door_InitContext(GameState* state, DoorContext* doorCtx) { } // SceneTableEntry Header Command 0x0F: Environment Light Settings List -void Scene_HeaderCmdEnvLightSettings(PlayState* play, SceneCmd* cmd) { +void Scene_CommandEnvLightSettings(PlayState* play, SceneCmd* cmd) { play->envCtx.numLightSettings = cmd->lightSettingList.num; play->envCtx.lightSettingsList = Lib_SegmentedToVirtual(cmd->lightSettingList.segment); } @@ -363,7 +363,7 @@ void Scene_LoadAreaTextures(PlayState* play, s32 fileIndex) { } // SceneTableEntry Header Command 0x11: Skybox Settings -void Scene_HeaderCmdSkyboxSettings(PlayState* play, SceneCmd* cmd) { +void Scene_CommandSkyboxSettings(PlayState* play, SceneCmd* cmd) { play->skyboxId = cmd->skyboxSettings.skyboxId & 3; play->envCtx.unk_17 = play->envCtx.unk_18 = cmd->skyboxSettings.unk5; play->envCtx.unk_1E = cmd->skyboxSettings.unk6; @@ -371,13 +371,13 @@ void Scene_HeaderCmdSkyboxSettings(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x12: Skybox Disables -void Scene_HeaderCmdSkyboxDisables(PlayState* play, SceneCmd* cmd) { +void Scene_CommandSkyboxDisables(PlayState* play, SceneCmd* cmd) { play->envCtx.skyboxDisabled = cmd->skyboxDisables.unk4; play->envCtx.sunMoonDisabled = cmd->skyboxDisables.unk5; } // SceneTableEntry Header Command 0x10: Time Settings -void Scene_HeaderCmdTimeSettings(PlayState* play, SceneCmd* cmd) { +void Scene_CommandTimeSettings(PlayState* play, SceneCmd* cmd) { if ((cmd->timeSettings.hour != 0xFF) && (cmd->timeSettings.min != 0xFF)) { gSaveContext.skyboxTime = gSaveContext.save.time = CLOCK_TIME_ALT2_F(cmd->timeSettings.hour, cmd->timeSettings.min); @@ -418,7 +418,7 @@ void Scene_HeaderCmdTimeSettings(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x05: Wind Settings -void Scene_HeaderCmdWindSettings(PlayState* play, SceneCmd* cmd) { +void Scene_CommandWindSettings(PlayState* play, SceneCmd* cmd) { s8 temp1 = cmd->windSettings.west; s8 temp2 = cmd->windSettings.vertical; s8 temp3 = cmd->windSettings.south; @@ -430,16 +430,16 @@ void Scene_HeaderCmdWindSettings(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x13: Exit List -void Scene_HeaderCmdExitList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandExitList(PlayState* play, SceneCmd* cmd) { play->setupExitList = Lib_SegmentedToVirtual(cmd->exitList.segment); } // SceneTableEntry Header Command 0x09: Undefined -void Scene_HeaderCmd09(PlayState* play, SceneCmd* cmd) { +void Scene_Command09(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x15: Sound Settings= -void Scene_HeaderCmdSoundSettings(PlayState* play, SceneCmd* cmd) { +void Scene_CommandSoundSettings(PlayState* play, SceneCmd* cmd) { play->sequenceCtx.seqId = cmd->soundSettings.seqId; play->sequenceCtx.ambienceId = cmd->soundSettings.ambienceId; @@ -450,12 +450,12 @@ void Scene_HeaderCmdSoundSettings(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x16: Echo Setting -void Scene_HeaderCmdEchoSetting(PlayState* play, SceneCmd* cmd) { +void Scene_CommandEchoSetting(PlayState* play, SceneCmd* cmd) { play->roomCtx.curRoom.echo = cmd->echoSettings.echo; } // SceneTableEntry Header Command 0x18: Alternate Header List= -void Scene_HeaderCmdAltHeaderList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandAltHeaderList(PlayState* play, SceneCmd* cmd) { SceneCmd** altHeaderList; SceneCmd* altHeader; @@ -464,40 +464,40 @@ void Scene_HeaderCmdAltHeaderList(PlayState* play, SceneCmd* cmd) { altHeader = altHeaderList[gSaveContext.sceneLayer - 1]; if (altHeader != NULL) { - Scene_ProcessHeader(play, Lib_SegmentedToVirtual(altHeader)); + Scene_ExecuteCommands(play, Lib_SegmentedToVirtual(altHeader)); (cmd + 1)->base.code = 0x14; } } } // SceneTableEntry Header Command 0x17: Cutscene List -void Scene_HeaderCmdCutsceneList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandCutsceneList(PlayState* play, SceneCmd* cmd) { play->csCtx.sceneCsCount = cmd->cutsceneList.sceneCsCount; play->csCtx.sceneCsList = Lib_SegmentedToVirtual(cmd->cutsceneList.segment); } // SceneTableEntry Header Command 0x1B: Actor Cutscene List -void Scene_HeaderCmdActorCutsceneList(PlayState* play, SceneCmd* cmd) { +void Scene_CommandActorCutsceneList(PlayState* play, SceneCmd* cmd) { ActorCutscene_Init(play, Lib_SegmentedToVirtual(cmd->cutsceneActorList.segment), cmd->cutsceneActorList.num); } // SceneTableEntry Header Command 0x1C: Mini Maps -void Scene_HeaderCmdMiniMap(PlayState* play, SceneCmd* cmd) { +void Scene_CommandMiniMap(PlayState* play, SceneCmd* cmd) { func_80104CF4(play); func_8010549C(play, cmd->minimapSettings.segment); } // SceneTableEntry Header Command 0x1D: Undefined -void Scene_HeaderCmd1D(PlayState* play, SceneCmd* cmd) { +void Scene_Command1D(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x1E: Minimap Compass Icon Info -void Scene_HeaderCmdMiniMapCompassInfo(PlayState* play, SceneCmd* cmd) { +void Scene_CommandMiniMapCompassInfo(PlayState* play, SceneCmd* cmd) { func_8010565C(play, cmd->minimapChests.num, cmd->minimapChests.segment); } // SceneTableEntry Header Command 0x19: Sets Region Visited Flag -void Scene_HeaderCmdSetRegionVisitedFlag(PlayState* play, SceneCmd* cmd) { +void Scene_CommandSetRegionVisitedFlag(PlayState* play, SceneCmd* cmd) { s16 j = 0; s16 i = 0; @@ -525,7 +525,7 @@ void Scene_HeaderCmdSetRegionVisitedFlag(PlayState* play, SceneCmd* cmd) { } // SceneTableEntry Header Command 0x1A: Material Animations -void Scene_HeaderCmdAnimatedMaterials(PlayState* play, SceneCmd* cmd) { +void Scene_CommandAnimatedMaterials(PlayState* play, SceneCmd* cmd) { play->sceneMaterialAnims = (AnimatedMaterial*)Lib_SegmentedToVirtual(cmd->textureAnimations.segment); } @@ -536,57 +536,58 @@ void Scene_SetExitFade(PlayState* play) { play->transitionType = Entrance_GetTransitionFlags(play->nextEntrance) & 0x7F; } +void (*sSceneCmdHandlers[])(PlayState*, SceneCmd*) = { + Scene_CommandSpawnList, + Scene_CommandActorList, + Scene_CommandActorCutsceneCamList, + Scene_CommandCollisionHeader, + Scene_CommandRoomList, + Scene_CommandWindSettings, + Scene_CommandEntranceList, + Scene_CommandSpecialFiles, + Scene_CommandRoomBehavior, + Scene_Command09, + Scene_CommandMesh, + Scene_CommandObjectList, + Scene_CommandLightList, + Scene_CommandPathList, + Scene_CommandTransiActorList, + Scene_CommandEnvLightSettings, + Scene_CommandTimeSettings, + Scene_CommandSkyboxSettings, + Scene_CommandSkyboxDisables, + Scene_CommandExitList, + NULL, + Scene_CommandSoundSettings, + Scene_CommandEchoSetting, + Scene_CommandCutsceneList, + Scene_CommandAltHeaderList, + Scene_CommandSetRegionVisitedFlag, + Scene_CommandAnimatedMaterials, + Scene_CommandActorCutsceneList, + Scene_CommandMiniMap, + Scene_Command1D, + Scene_CommandMiniMapCompassInfo, +}; + /** * Executes all of the commands in a scene or room header. */ -s32 Scene_ProcessHeader(PlayState* play, SceneCmd* header) { - static void (*sceneCmdHandlers[])(PlayState*, SceneCmd*) = { - Scene_HeaderCmdSpawnList, - Scene_HeaderCmdActorList, - Scene_HeaderCmdActorCutsceneCamList, - Scene_HeaderCmdColHeader, - Scene_HeaderCmdRoomList, - Scene_HeaderCmdWindSettings, - Scene_HeaderCmdEntranceList, - Scene_HeaderCmdSpecialFiles, - Scene_HeaderCmdRoomBehavior, - Scene_HeaderCmd09, - Scene_HeaderCmdMesh, - Scene_HeaderCmdObjectList, - Scene_HeaderCmdLightList, - Scene_HeaderCmdPathList, - Scene_HeaderCmdTransiActorList, - Scene_HeaderCmdEnvLightSettings, - Scene_HeaderCmdTimeSettings, - Scene_HeaderCmdSkyboxSettings, - Scene_HeaderCmdSkyboxDisables, - Scene_HeaderCmdExitList, - NULL, - Scene_HeaderCmdSoundSettings, - Scene_HeaderCmdEchoSetting, - Scene_HeaderCmdCutsceneList, - Scene_HeaderCmdAltHeaderList, - Scene_HeaderCmdSetRegionVisitedFlag, - Scene_HeaderCmdAnimatedMaterials, - Scene_HeaderCmdActorCutsceneList, - Scene_HeaderCmdMiniMap, - Scene_HeaderCmd1D, - Scene_HeaderCmdMiniMapCompassInfo, - }; +s32 Scene_ExecuteCommands(PlayState* play, SceneCmd* sceneCmd) { u32 cmdId; while (true) { - cmdId = header->base.code; + cmdId = sceneCmd->base.code; if (cmdId == SCENE_CMD_ID_END) { break; } if (cmdId < SCENE_CMD_MAX) { - sceneCmdHandlers[cmdId](play, header); + sSceneCmdHandlers[cmdId](play, sceneCmd); } - header++; + sceneCmd++; } return 0; -- cgit v1.2.3