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
This commit is contained in:
engineer124
2023-03-23 09:36:09 +11:00
committed by GitHub
parent 9bb978527f
commit 2cb01b5b6a
26 changed files with 907 additions and 404 deletions
+6 -6
View File
@@ -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;
+1 -1
View File
@@ -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)) {
+4 -3
View File
@@ -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());
+8 -8
View File
@@ -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);
}
+2 -2
View File
@@ -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;
+539 -50
View File
@@ -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;
#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/func_8012DEE8.s")
typedef struct RoomShapeCullableEntryLinked {
/* 0x00 */ RoomShapeCullableEntry* entry;
/* 0x04 */ f32 boundsNearZ;
/* 0x08 */ struct RoomShapeCullableEntryLinked* prev;
/* 0x0C */ struct RoomShapeCullableEntryLinked* next;
} RoomShapeCullableEntryLinked; // size = 0x10
#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/func_8012E254.s")
// TODO: 127 is an arbitrarily chosen number to make the stack sorta work
#define ROOM_SHAPE_CULLABLE_MAX_ENTRIES 127
#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/func_8012E32C.s")
#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;
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);
OPEN_DISPS(play->state.gfxCtx);
if (flags & ROOM_DRAW_OPA) {
func_800BCBF4(&sZeroVec, play);
//! TODO: Fake
if (1) {}
if (1) {}
if (1) {}
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);
}
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;
}
+72 -71
View File
@@ -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;