summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorengineer124 <47598039+engineer124@users.noreply.github.com>2023-03-23 09:36:09 +1100
committerGitHub <noreply@github.com>2023-03-23 09:36:09 +1100
commit2cb01b5b6a69635f7c8f554cf97442268aff28be (patch)
treea0603a4c4827fb4068d806d11638c1503c356650 /src/code
parent9bb978527f619abbedbc5119fa2811385b29c01e (diff)
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
Diffstat (limited to 'src/code')
-rw-r--r--src/code/PreRender.c12
-rw-r--r--src/code/z_actor.c2
-rw-r--r--src/code/z_parameter.c7
-rw-r--r--src/code/z_play.c16
-rw-r--r--src/code/z_player_lib.c4
-rw-r--r--src/code/z_room.c591
-rw-r--r--src/code/z_scene.c143
7 files changed, 633 insertions, 142 deletions
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 = &params;
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;