From 663834cbc087ab7bbc9b20b48d6f06eaae4d4341 Mon Sep 17 00:00:00 2001 From: Derek Hensley Date: Sun, 14 Jan 2024 10:56:19 -0800 Subject: [PATCH] Skybox Docs (#1534) * xml * Docs * 0s --- assets/xml/misc/skyboxes.xml | 21 ++ include/z64skybox.h | 27 +- spec | 6 +- src/code/z_play.c | 6 +- src/code/z_vr_box.c | 331 ++++++++++-------- src/code/z_vr_box_draw.c | 29 +- .../actors/ovl_player_actor/z_player.c | 2 +- .../ovl_kaleido_scope/z_kaleido_scope_NES.c | 3 +- tools/disasm/functions.txt | 6 +- tools/disasm/variables.txt | 14 +- tools/sizes/code_functions.csv | 6 +- 11 files changed, 262 insertions(+), 189 deletions(-) create mode 100644 assets/xml/misc/skyboxes.xml diff --git a/assets/xml/misc/skyboxes.xml b/assets/xml/misc/skyboxes.xml new file mode 100644 index 0000000000..2170fabc99 --- /dev/null +++ b/assets/xml/misc/skyboxes.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/include/z64skybox.h b/include/z64skybox.h index 0a981d23e6..d963e21d8d 100644 --- a/include/z64skybox.h +++ b/include/z64skybox.h @@ -24,16 +24,16 @@ typedef enum SkyboxId { typedef struct SkyboxContext { /* 0x000 */ View view; /* 0x168 */ void* staticSegments[4]; - /* 0x178 */ void* paletteStaticSegment; + /* 0x178 */ void* palette; /* 0x17C */ Gfx (*dListBuf)[150]; - /* 0x180 */ Gfx* roomDL; + /* 0x180 */ Gfx* gfx; /* 0x184 */ Vtx* roomVtx; - /* 0x188 */ DmaRequest unk188; - /* 0x1A8 */ DmaRequest unk1A8; - /* 0x1C8 */ DmaRequest unk1C8; + /* 0x188 */ DmaRequest skybox1DmaRequest; + /* 0x1A8 */ DmaRequest skybox2DmaRequest; + /* 0x1C8 */ DmaRequest paletteDmaRequest; /* 0x1E8 */ OSMesgQueue loadQueue; - /* 0x200 */ OSMesg loadMsg; - /* 0x204 */ s16 skyboxShouldDraw; + /* 0x200 */ OSMesg loadMsg[1]; + /* 0x204 */ s16 shouldDraw; /* 0x208 */ Vec3f rot; /* 0x214 */ Vec3f eye; /* 0x220 */ s16 angle; @@ -41,18 +41,7 @@ typedef struct SkyboxContext { /* 0x225 */ Color_RGB8 env; } SkyboxContext; // size = 0x228 -typedef struct struct_801C5F44 { - /* 0x00 */ s32 unk0; - /* 0x04 */ s32 unk4; - /* 0x08 */ s32 unk8; - /* 0x0C */ s32 unkC; - /* 0x10 */ s32 unk10; -} struct_801C5F44; // size = 0x14 - -s32 func_80142440(SkyboxContext* skyboxCtx, Vtx* roomVtx, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7, s32 arg8); -void func_80143148(SkyboxContext* skyboxCtx, s32 arg1); -void Skybox_Setup(struct GameState* gameState, SkyboxContext* skyboxCtx, s16 skyboxId); -void func_80143324(struct PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId); +void Skybox_Reload(struct PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId); void Skybox_Init(struct GameState* gameState, SkyboxContext* skyboxCtx, s16 skyboxId); Mtx* Skybox_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z); void Skybox_SetColors(SkyboxContext* skyboxCtx, u8 primR, u8 primG, u8 primB, u8 envR, u8 envG, u8 envB); diff --git a/spec b/spec index 65c2b3f0ac..41b5f67dc0 100644 --- a/spec +++ b/spec @@ -8861,21 +8861,21 @@ beginseg name "d2_fine_static" compress romalign 0x1000 - include "build/baserom/d2_fine_static.o" + include "build/assets/misc/skyboxes/d2_fine_static.o" endseg beginseg name "d2_cloud_static" compress romalign 0x1000 - include "build/baserom/d2_cloud_static.o" + include "build/assets/misc/skyboxes/d2_cloud_static.o" endseg beginseg name "d2_fine_pal_static" compress romalign 0x1000 - include "build/baserom/d2_fine_pal_static.o" + include "build/assets/misc/skyboxes/d2_fine_pal_static.o" endseg beginseg diff --git a/src/code/z_play.c b/src/code/z_play.c index 7e285f02f2..a193038d06 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -1140,7 +1140,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.roomShape->base.type == ROOM_SHAPE_TYPE_IMAGE)) { + if (this->skyboxCtx.shouldDraw || (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[0], this->lightCtx.fogColor[1], @@ -1282,7 +1282,7 @@ void Play_DrawMain(PlayState* this) { Environment_UpdateSkybox(this->skyboxId, &this->envCtx, &this->skyboxCtx); Skybox_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, this->envCtx.skyboxBlend, this->view.eye.x, this->view.eye.y, this->view.eye.z); - } else if (!this->skyboxCtx.skyboxShouldDraw) { + } else if (!this->skyboxCtx.shouldDraw) { Skybox_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, 0, this->view.eye.x, this->view.eye.y, this->view.eye.z); } @@ -1310,7 +1310,7 @@ void Play_DrawMain(PlayState* this) { } } - if (this->skyboxCtx.skyboxShouldDraw) { + if (this->skyboxCtx.shouldDraw) { Vec3f quakeOffset; if (1) { diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c index 7819de4df6..2760989efc 100644 --- a/src/code/z_vr_box.c +++ b/src/code/z_vr_box.c @@ -1,95 +1,132 @@ +#include "z64skybox.h" #include "global.h" #include "buffers.h" -u32 D_801C5E30[] = { 0, 0x2000, 0x4000, 0x6000, 0x8000, 0xC000 }; +typedef struct SkyboxFaceParams { + /* 0x00 */ s32 xStart; + /* 0x04 */ s32 yStart; + /* 0x08 */ s32 zStart; + /* 0x0C */ s32 outerIncrVal; + /* 0x10 */ s32 innerIncrVal; +} SkyboxFaceParams; // size = 0x14 -u16 D_801C5E48[] = { +// Converts texture coordinate values to s10.5 fixed point +#define TC(x) ((s16)((x)*32)) + +// Texture offsets for each face in the static segment buffer +u32 sSkybox128TexOffsets[] = { + 128 * 64 * 0, 128 * 64 * 1, 128 * 64 * 2, 128 * 64 * 3, 128 * 64 * 4, 128 * 64 * 4 + 128 * 128, +}; + +// Maps vertex buffer index to coordinate buffer index +u16 sSkybox128VtxBufIndices[] = { 0, 2, 10, 12, 2, 4, 12, 14, 10, 12, 20, 22, 12, 14, 22, 24, 1, 3, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 21, 23, }; -s32 D_801C5E88[] = { 0, 62 << 5, 124 << 5, 186 << 5, 248 << 5 }; -s32 D_801C5E9C[] = { 0, 62 << 5, 124 << 5, 186 << 5, 248 << 5 }; +// S coordinates for all faces +s32 sSkybox128TexSCoords[] = { + TC(62 * 0), TC(62 * 1), TC(62 * 2), TC(62 * 3), TC(62 * 4), +}; -s32 D_801C5EB0[] = { 0, 62 << 5, 124 << 5, 62 << 5, 0 }; +// T coordinates for top and bottom faces +s32 sSkybox128TexTCoordsXZ[] = { + TC(62 * 0), TC(62 * 1), TC(62 * 2), TC(62 * 3), TC(62 * 4), +}; -s16 D_801C5EC4[] = { +// T coordinates for side faces +s32 sSkybox128TexTCoords[] = { + TC(62 * 0), TC(62 * 1), TC(62 * 2), TC(62 * 1), TC(62 * 0), +}; + +// Maps vertex index to vertex buffer index +s16 sSkybox128VtxIndices[] = { 0, 16, 19, 18, 16, 1, 20, 19, 1, 17, 21, 20, 17, 5, 22, 21, 18, 19, 23, 2, 19, 20, 3, 23, 20, 21, 24, 3, 21, 22, 7, 24, 2, 23, 26, 25, 23, 3, 27, 26, 3, 24, 28, 27, 24, 7, 29, 28, 25, 26, 30, 10, 26, 27, 11, 30, 27, 28, 31, 11, 28, 29, 15, 31, }; -s32 func_80142440(SkyboxContext* skyboxCtx, Vtx* roomVtx, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7, - s32 arg8) { +/** + * Build the vertex and display list data for a skybox with 128x128 and 128x64 face textures. + * + * While the textures are nominally 128x128 (128x64) the 4x4 (4x2) tiles that cover it are only 31x31, + * therefore only a 125x125 (125x63) area is ever sampled (125 = 4 * 31 + 1, the additional +1 accounts for bilinear + * filtering) + * + * Each texture dimension is padded to the next power of 2, resulting in a final size of 128x128 (128x64) + */ +s32 Skybox_CalculateFace128(SkyboxContext* skyboxCtx, Vtx* roomVtx, s32 roomVtxStartIndex, s32 xStart, s32 yStart, + s32 zStart, s32 innerIncrVal, s32 outerIncrVal, s32 faceNum) { s32 i; s32 j; s32 k; - s16 phi_a0_4; - s16 phi_t1; - s32 temp1; + s16 uls; + s16 m; + s32 outerIncr; u16 index; - s16 phi_a2_4; - s16 phi_ra; - s16 phi_t2_4; - s32 temp2; - s32 roomVtxPosX[5 * 5]; - s32 roomVtxPosY[5 * 5]; - s32 roomVtxPosZ[5 * 5]; - s32 roomVtxTexU[5 * 5]; - s32 roomVtxTexV[5 * 5]; + s16 ult; + s16 l; + s16 vtxIndex; + s32 innerIncr; + s32 xPoints[5 * 5]; + s32 yPoints[5 * 5]; + s32 zPoints[5 * 5]; + s32 tcS[5 * 5]; + s32 tcT[5 * 5]; s32 pad; - switch (arg8) { - case 0: + // Collect all vertex positions for this face + switch (faceNum) { + case 0: // xy plane case 1: - temp1 = arg4; + outerIncr = yStart; for (i = 0, k = 0; k < 25; i++) { - temp2 = arg3; + innerIncr = xStart; for (j = 0; j < 5; j++, k++) { - roomVtxPosZ[k] = arg5; - roomVtxPosX[k] = temp2; - roomVtxPosY[k] = temp1; - roomVtxTexU[k] = D_801C5E88[j]; - roomVtxTexV[k] = D_801C5EB0[i]; - temp2 += arg6; + zPoints[k] = zStart; + xPoints[k] = innerIncr; + yPoints[k] = outerIncr; + tcS[k] = sSkybox128TexSCoords[j]; + tcT[k] = sSkybox128TexTCoords[i]; + innerIncr += innerIncrVal; } - temp1 += arg7; + outerIncr += outerIncrVal; } break; - case 2: + case 2: // yz plane case 3: - temp1 = arg4; + outerIncr = yStart; for (i = 0, k = 0; k < 25; i++) { - temp2 = arg5; + innerIncr = zStart; for (j = 0; j < 5; j++, k++) { - roomVtxPosX[k] = arg3; - roomVtxPosY[k] = temp1; - roomVtxPosZ[k] = temp2; - roomVtxTexU[k] = D_801C5E88[j]; - roomVtxTexV[k] = D_801C5EB0[i]; - temp2 += arg6; + xPoints[k] = xStart; + yPoints[k] = outerIncr; + zPoints[k] = innerIncr; + tcS[k] = sSkybox128TexSCoords[j]; + tcT[k] = sSkybox128TexTCoords[i]; + innerIncr += innerIncrVal; } - temp1 += arg7; + outerIncr += outerIncrVal; } break; - case 4: + case 4: // xz plane case 5: - temp1 = arg5; + outerIncr = zStart; for (i = 0, k = 0; k < 25; i++) { - temp2 = arg3; + innerIncr = xStart; for (j = 0; j < 5; j++, k++) { - roomVtxPosY[k] = arg4; - roomVtxPosX[k] = temp2; - roomVtxPosZ[k] = temp1; - roomVtxTexU[k] = D_801C5E88[j]; - roomVtxTexV[k] = D_801C5E9C[i]; - temp2 += arg6; + yPoints[k] = yStart; + xPoints[k] = innerIncr; + zPoints[k] = outerIncr; + tcS[k] = sSkybox128TexSCoords[j]; + tcT[k] = sSkybox128TexTCoordsXZ[i]; + innerIncr += innerIncrVal; } - temp1 += arg7; + outerIncr += outerIncrVal; } break; @@ -97,90 +134,106 @@ s32 func_80142440(SkyboxContext* skyboxCtx, Vtx* roomVtx, s32 arg2, s32 arg3, s3 break; } - skyboxCtx->roomDL = &skyboxCtx->dListBuf[2 * arg8][0]; + // Select gfx buffer + skyboxCtx->gfx = &skyboxCtx->dListBuf[2 * faceNum][0]; - for (i = 0; i < 0x20; i++) { - index = D_801C5E48[i]; + // Generate and load Vertex structures + for (i = 0; i < ARRAY_COUNT(sSkybox128VtxBufIndices); i++) { + index = sSkybox128VtxBufIndices[i]; - roomVtx[arg2 + i].v.ob[0] = roomVtxPosX[index]; - roomVtx[arg2 + i].v.ob[1] = roomVtxPosY[index]; - roomVtx[arg2 + i].v.ob[2] = roomVtxPosZ[index]; - roomVtx[arg2 + i].v.flag = 0; - roomVtx[arg2 + i].v.tc[0] = roomVtxTexU[index]; - roomVtx[arg2 + i].v.tc[1] = roomVtxTexV[index]; - roomVtx[arg2 + i].v.cn[1] = 0; - roomVtx[arg2 + i].v.cn[2] = 0; - roomVtx[arg2 + i].v.cn[0] = 255; + roomVtx[roomVtxStartIndex + i].v.ob[0] = xPoints[index]; + roomVtx[roomVtxStartIndex + i].v.ob[1] = yPoints[index]; + roomVtx[roomVtxStartIndex + i].v.ob[2] = zPoints[index]; + roomVtx[roomVtxStartIndex + i].v.flag = 0; + roomVtx[roomVtxStartIndex + i].v.tc[0] = tcS[index]; + roomVtx[roomVtxStartIndex + i].v.tc[1] = tcT[index]; + roomVtx[roomVtxStartIndex + i].v.cn[1] = 0; + roomVtx[roomVtxStartIndex + i].v.cn[2] = 0; + roomVtx[roomVtxStartIndex + i].v.cn[0] = 255; } - gSPVertex(skyboxCtx->roomDL++, &roomVtx[arg2], 32, 0); - arg2 += i; - gSPCullDisplayList(skyboxCtx->roomDL++, 0, 15); + gSPVertex(skyboxCtx->gfx++, &roomVtx[roomVtxStartIndex], 32, 0); + roomVtxStartIndex += i; // += 32 - if ((arg8 == 4) || (arg8 == 5)) { - phi_a2_4 = 0; - for (phi_t2_4 = 0, phi_ra = 0; phi_ra < 4; phi_ra++, phi_a2_4 += 0x1F) { - for (phi_a0_4 = 0, phi_t1 = 0; phi_t1 < 4; phi_t1++, phi_a0_4 += 0x1F, phi_t2_4 += 4) { - gDPLoadMultiTile(skyboxCtx->roomDL++, (uintptr_t)skyboxCtx->staticSegments[0] + D_801C5E30[arg8], 0, - G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, phi_a0_4, phi_a2_4, phi_a0_4 + 0x1F, - phi_a2_4 + 0x1F, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); - gDPLoadMultiTile(skyboxCtx->roomDL++, (uintptr_t)skyboxCtx->staticSegments[1] + D_801C5E30[arg8], 0x80, - 1, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, phi_a0_4, phi_a2_4, phi_a0_4 + 0x1F, - phi_a2_4 + 0x1F, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); - gSP1Quadrangle(skyboxCtx->roomDL++, D_801C5EC4[phi_t2_4 + 1], D_801C5EC4[phi_t2_4 + 2], - D_801C5EC4[phi_t2_4 + 3], D_801C5EC4[phi_t2_4 + 0], 3); + // Cull the face if not within the viewing volume + gSPCullDisplayList(skyboxCtx->gfx++, 0, 15); + + // Draw face, load the texture in several tiles to work around TMEM size limitations + if ((faceNum == 4) || (faceNum == 5)) { + // top/bottom faces, 128x128 texture + ult = 0; + for (vtxIndex = 0, l = 0; l < 4; l++, ult += 31) { + for (uls = 0, m = 0; m < 4; m++, uls += 31, vtxIndex += 4) { + gDPLoadMultiTile(skyboxCtx->gfx++, + (uintptr_t)skyboxCtx->staticSegments[0] + sSkybox128TexOffsets[faceNum], 0, + G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, uls, ult, uls + 31, ult + 31, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOLOD); + gDPLoadMultiTile( + skyboxCtx->gfx++, (uintptr_t)skyboxCtx->staticSegments[1] + sSkybox128TexOffsets[faceNum], 0x80, 1, + G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, uls, ult, uls + 31, ult + 31, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); + gSP1Quadrangle(skyboxCtx->gfx++, sSkybox128VtxIndices[vtxIndex + 1], sSkybox128VtxIndices[vtxIndex + 2], + sSkybox128VtxIndices[vtxIndex + 3], sSkybox128VtxIndices[vtxIndex + 0], 3); } } } else { - phi_a2_4 = 0; - for (phi_t2_4 = 0, phi_ra = 0; phi_ra < 2; phi_ra++, phi_a2_4 += 0x1F) { - for (phi_a0_4 = 0, phi_t1 = 0; phi_t1 < 4; phi_t1++, phi_a0_4 += 0x1F, phi_t2_4 += 4) { - gDPLoadMultiTile(skyboxCtx->roomDL++, (uintptr_t)skyboxCtx->staticSegments[0] + D_801C5E30[arg8], 0, - G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, phi_a0_4, phi_a2_4, phi_a0_4 + 0x1F, - phi_a2_4 + 0x1F, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); - gDPLoadMultiTile(skyboxCtx->roomDL++, (uintptr_t)skyboxCtx->staticSegments[1] + D_801C5E30[arg8], 0x80, - 1, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, phi_a0_4, phi_a2_4, phi_a0_4 + 0x1F, - phi_a2_4 + 0x1F, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); - gSP1Quadrangle(skyboxCtx->roomDL++, D_801C5EC4[phi_t2_4 + 1], D_801C5EC4[phi_t2_4 + 2], - D_801C5EC4[phi_t2_4 + 3], D_801C5EC4[phi_t2_4 + 0], 3); + // other faces, 128x64 texture + ult = 0; + for (vtxIndex = 0, l = 0; l < 2; l++, ult += 31) { + for (uls = 0, m = 0; m < 4; m++, uls += 31, vtxIndex += 4) { + gDPLoadMultiTile(skyboxCtx->gfx++, + (uintptr_t)skyboxCtx->staticSegments[0] + sSkybox128TexOffsets[faceNum], 0, + G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, uls, ult, uls + 31, ult + 31, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOLOD); + gDPLoadMultiTile( + skyboxCtx->gfx++, (uintptr_t)skyboxCtx->staticSegments[1] + sSkybox128TexOffsets[faceNum], 0x80, 1, + G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, uls, ult, uls + 31, ult + 31, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); + gSP1Quadrangle(skyboxCtx->gfx++, sSkybox128VtxIndices[vtxIndex + 1], sSkybox128VtxIndices[vtxIndex + 2], + sSkybox128VtxIndices[vtxIndex + 3], sSkybox128VtxIndices[vtxIndex + 0], 3); } } - phi_a2_4 -= 0x1F; - for (phi_ra = 0; phi_ra < 2; phi_ra++, phi_a2_4 -= 0x1F) { - for (phi_a0_4 = 0, phi_t1 = 0; phi_t1 < 4; phi_t1++, phi_a0_4 += 0x1F, phi_t2_4 += 4) { - gDPLoadMultiTile(skyboxCtx->roomDL++, (uintptr_t)skyboxCtx->staticSegments[0] + D_801C5E30[arg8], 0, - G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, phi_a0_4, phi_a2_4, phi_a0_4 + 0x1F, - phi_a2_4 + 0x1F, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); - gDPLoadMultiTile(skyboxCtx->roomDL++, (uintptr_t)skyboxCtx->staticSegments[1] + D_801C5E30[arg8], 0x80, - 1, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, phi_a0_4, phi_a2_4, phi_a0_4 + 0x1F, - phi_a2_4 + 0x1F, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); - gSP1Quadrangle(skyboxCtx->roomDL++, D_801C5EC4[phi_t2_4 + 1], D_801C5EC4[phi_t2_4 + 2], - D_801C5EC4[phi_t2_4 + 3], D_801C5EC4[phi_t2_4 + 0], 3); + ult -= 31; + for (l = 0; l < 2; l++, ult -= 31) { + for (uls = 0, m = 0; m < 4; m++, uls += 31, vtxIndex += 4) { + gDPLoadMultiTile(skyboxCtx->gfx++, + (uintptr_t)skyboxCtx->staticSegments[0] + sSkybox128TexOffsets[faceNum], 0, + G_TX_RENDERTILE, G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, uls, ult, uls + 31, ult + 31, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOLOD); + gDPLoadMultiTile( + skyboxCtx->gfx++, (uintptr_t)skyboxCtx->staticSegments[1] + sSkybox128TexOffsets[faceNum], 0x80, 1, + G_IM_FMT_CI, G_IM_SIZ_8b, 128, 0, uls, ult, uls + 31, ult + 31, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); + gSP1Quadrangle(skyboxCtx->gfx++, sSkybox128VtxIndices[vtxIndex + 1], sSkybox128VtxIndices[vtxIndex + 2], + sSkybox128VtxIndices[vtxIndex + 3], sSkybox128VtxIndices[vtxIndex + 0], 3); } } } - gSPEndDisplayList(skyboxCtx->roomDL++); - return arg2; + + gSPEndDisplayList(skyboxCtx->gfx++); + return roomVtxStartIndex; } -void func_80143148(SkyboxContext* skyboxCtx, s32 arg1) { - static struct_801C5F44 D_801C5F44[] = { - { -64, 64, -64, 32, -32 }, { 64, 64, 64, -32, -32 }, { -64, 64, 64, -32, -32 }, - { 64, 64, -64, 32, -32 }, { -64, 64, 64, 32, -32 }, { -64, -64, -64, 32, 32 }, - }; - s32 ret = 0; - struct_801C5F44* unkStruct; - s32 face; +SkyboxFaceParams sSkybox128FaceParams[] = { + { -64, 64, -64, 32, -32 }, { 64, 64, 64, -32, -32 }, { -64, 64, 64, -32, -32 }, + { 64, 64, -64, 32, -32 }, { -64, 64, 64, 32, -32 }, { -64, -64, -64, 32, 32 }, +}; - for (face = 0; face < arg1; face++) { - unkStruct = &D_801C5F44[face]; - ret = func_80142440(skyboxCtx, skyboxCtx->roomVtx, ret, unkStruct->unk0, unkStruct->unk4, unkStruct->unk8, - unkStruct->unkC, unkStruct->unk10, face); +/** + * Computes the display list for a skybox with up to 6 faces, where the sides are 128x64 CI8 textures and the + * top/bottom faces are 128x128 CI8 textures. + */ +void Skybox_Calculate128(SkyboxContext* skyboxCtx, s32 nFaces) { + s32 roomVtxStartIndex = 0; + s32 faceNum; + + for (faceNum = 0; faceNum < nFaces; faceNum++) { + roomVtxStartIndex = Skybox_CalculateFace128( + skyboxCtx, skyboxCtx->roomVtx, roomVtxStartIndex, sSkybox128FaceParams[faceNum].xStart, + sSkybox128FaceParams[faceNum].yStart, sSkybox128FaceParams[faceNum].zStart, + sSkybox128FaceParams[faceNum].outerIncrVal, sSkybox128FaceParams[faceNum].innerIncrVal, faceNum); } } @@ -206,10 +259,10 @@ void Skybox_Setup(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyboxId) DmaMgr_RequestSync(skyboxCtx->staticSegments[1], SEGMENT_ROM_START(d2_fine_static), size); // Send a DMA request for the skybox palette - skyboxCtx->paletteStaticSegment = segment; + skyboxCtx->palette = segment; size = SEGMENT_ROM_SIZE(d2_fine_pal_static); segment = (void*)ALIGN8((uintptr_t)segment + size); - DmaMgr_RequestSync(skyboxCtx->paletteStaticSegment, SEGMENT_ROM_START(d2_fine_pal_static), size); + DmaMgr_RequestSync(skyboxCtx->palette, SEGMENT_ROM_START(d2_fine_pal_static), size); skyboxCtx->prim.r = 145; skyboxCtx->prim.g = 120; @@ -233,51 +286,51 @@ void Skybox_Setup(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyboxId) } } -void func_80143324(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) { +void Skybox_Reload(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) { size_t size; switch (skyboxId) { case SKYBOX_NORMAL_SKY: - osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1); + osCreateMesgQueue(&skyboxCtx->loadQueue, skyboxCtx->loadMsg, ARRAY_COUNT(skyboxCtx->loadMsg)); if (play->envCtx.skybox1Index == 0) { // Send a DMA request for the clear sky texture size = SEGMENT_ROM_SIZE(d2_fine_static); - DmaMgr_RequestAsync(&skyboxCtx->unk188, skyboxCtx->staticSegments[0], SEGMENT_ROM_START(d2_fine_static), - size, 0, &skyboxCtx->loadQueue, NULL); + DmaMgr_RequestAsync(&skyboxCtx->skybox1DmaRequest, skyboxCtx->staticSegments[0], + SEGMENT_ROM_START(d2_fine_static), size, 0, &skyboxCtx->loadQueue, NULL); } else { // Send a DMA request for the cloudy sky texture size = SEGMENT_ROM_SIZE(d2_cloud_static); - DmaMgr_RequestAsync(&skyboxCtx->unk188, skyboxCtx->staticSegments[0], + DmaMgr_RequestAsync(&skyboxCtx->skybox1DmaRequest, skyboxCtx->staticSegments[0], SEGMENT_ROM_START(d2_cloud_static), size, 0, &skyboxCtx->loadQueue, NULL); } osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); - osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1); + osCreateMesgQueue(&skyboxCtx->loadQueue, skyboxCtx->loadMsg, ARRAY_COUNT(skyboxCtx->loadMsg)); if (play->envCtx.skybox2Index == 0) { // Send a DMA request for the clear sky texture size = SEGMENT_ROM_SIZE(d2_fine_static); - DmaMgr_RequestAsync(&skyboxCtx->unk1A8, skyboxCtx->staticSegments[1], SEGMENT_ROM_START(d2_fine_static), - size, 0, &skyboxCtx->loadQueue, NULL); + DmaMgr_RequestAsync(&skyboxCtx->skybox2DmaRequest, skyboxCtx->staticSegments[1], + SEGMENT_ROM_START(d2_fine_static), size, 0, &skyboxCtx->loadQueue, NULL); } else { // Send a DMA request for the cloudy sky texture size = SEGMENT_ROM_SIZE(d2_cloud_static); - DmaMgr_RequestAsync(&skyboxCtx->unk1A8, skyboxCtx->staticSegments[1], + DmaMgr_RequestAsync(&skyboxCtx->skybox2DmaRequest, skyboxCtx->staticSegments[1], SEGMENT_ROM_START(d2_cloud_static), size, 0, &skyboxCtx->loadQueue, NULL); } osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); - osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1); + osCreateMesgQueue(&skyboxCtx->loadQueue, skyboxCtx->loadMsg, ARRAY_COUNT(skyboxCtx->loadMsg)); size = SEGMENT_ROM_SIZE(d2_fine_pal_static); // Send a DMA request for the skybox palette - DmaMgr_RequestAsync(&skyboxCtx->unk1C8, skyboxCtx->paletteStaticSegment, + DmaMgr_RequestAsync(&skyboxCtx->paletteDmaRequest, skyboxCtx->palette, SEGMENT_ROM_START(d2_fine_pal_static), size, 0, &skyboxCtx->loadQueue, NULL); osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); @@ -289,22 +342,22 @@ void func_80143324(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) { } void Skybox_Init(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyboxId) { - skyboxCtx->skyboxShouldDraw = false; + skyboxCtx->shouldDraw = false; skyboxCtx->rot.x = skyboxCtx->rot.y = skyboxCtx->rot.z = 0.0f; Skybox_Setup(gameState, skyboxCtx, skyboxId); if (skyboxId != SKYBOX_NONE) { - skyboxCtx->dListBuf = THA_AllocTailAlign16(&gameState->tha, 0x3840); + skyboxCtx->dListBuf = THA_AllocTailAlign16(&gameState->tha, 12 * 150 * sizeof(Gfx)); if (skyboxId == SKYBOX_CUTSCENE_MAP) { // Allocate enough space for the vertices for a 6 sided skybox (cube) - skyboxCtx->roomVtx = THA_AllocTailAlign16(&gameState->tha, sizeof(Vtx) * 32 * 6); - func_80143148(skyboxCtx, 6); + skyboxCtx->roomVtx = THA_AllocTailAlign16(&gameState->tha, 6 * 32 * sizeof(Vtx)); + Skybox_Calculate128(skyboxCtx, 6); } else { // Allocate enough space for the vertices for a 5 sided skybox (bottom is missing) - skyboxCtx->roomVtx = THA_AllocTailAlign16(&gameState->tha, sizeof(Vtx) * 32 * 5); - func_80143148(skyboxCtx, 5); + skyboxCtx->roomVtx = THA_AllocTailAlign16(&gameState->tha, 5 * 32 * sizeof(Vtx)); + Skybox_Calculate128(skyboxCtx, 5); } } } diff --git a/src/code/z_vr_box_draw.c b/src/code/z_vr_box_draw.c index 656f6cad3c..a4066b71ad 100644 --- a/src/code/z_vr_box_draw.c +++ b/src/code/z_vr_box_draw.c @@ -25,37 +25,46 @@ void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId Gfx_SetupDL40_Opa(gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x0B, skyboxCtx->paletteStaticSegment); + gSPSegment(POLY_OPA_DISP++, 0x0B, skyboxCtx->palette); gSPTexture(POLY_OPA_DISP++, 0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON); + // Prepare matrix sSkyboxDrawMatrix = GRAPH_ALLOC(gfxCtx, sizeof(Mtx)); - Matrix_Translate(x, y, z, MTXMODE_NEW); Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); Matrix_RotateXFApply(skyboxCtx->rot.x); Matrix_RotateYF(skyboxCtx->rot.y, MTXMODE_APPLY); Matrix_RotateZF(skyboxCtx->rot.z, MTXMODE_APPLY); Matrix_ToMtx(sSkyboxDrawMatrix); - gSPMatrix(POLY_OPA_DISP++, sSkyboxDrawMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + // Enable magic square RGB dithering and bilinear filtering gDPSetColorDither(POLY_OPA_DISP++, G_CD_MAGICSQ); gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_BILERP); - gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->paletteStaticSegment); + + // All skyboxes use CI8 textures with an RGBA16 palette + gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palette); gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_RGBA16); + + // Enable texture filtering RDP pipeline stages for bilinear filtering gDPSetTextureConvert(POLY_OPA_DISP++, G_TC_FILT); + + // Set skybox color gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, TEXEL0, PRIMITIVE_ALPHA, TEXEL0, TEXEL1, TEXEL0, PRIMITIVE, TEXEL0, PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, 0, 0, 0, COMBINED); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, skyboxCtx->prim.r, skyboxCtx->prim.g, skyboxCtx->prim.b, blend); gDPSetEnvColor(POLY_OPA_DISP++, skyboxCtx->env.r, skyboxCtx->env.g, skyboxCtx->env.b, 0); - gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[0]); - gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[2]); - gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[4]); - gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[6]); - gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[8]); + // Draw each face + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[0]); // -z face + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[2]); // +z face + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[4]); // -x face + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[6]); // +x face + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[8]); // +y face if (skyboxId == SKYBOX_CUTSCENE_MAP) { - gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[10]); + // Skip the bottom face unless in the cutscene map + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[10]); // -y face } gDPPipeSync(POLY_OPA_DISP++); diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c index 78555673aa..6a7dfcc2e0 100644 --- a/src/overlays/actors/ovl_player_actor/z_player.c +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -3,7 +3,7 @@ * Overlay: ovl_player_actor * Description: Player */ - +#include "prevent_bss_reordering.h" #include "global.h" #include "z64horse.h" #include "z64malloc.h" diff --git a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c index 01ab115236..502912da6b 100644 --- a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c +++ b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c @@ -5,6 +5,7 @@ */ #include "z_kaleido_scope.h" +#include "z64skybox.h" #include "z64view.h" #include "overlays/gamestates/ovl_opening/z_opening.h" @@ -3599,7 +3600,7 @@ void KaleidoScope_Update(PlayState* play) { gSaveContext.hudVisibility = HUD_VISIBILITY_IDLE; Interface_SetHudVisibility(HUD_VISIBILITY_ALL); MsgEvent_SendNullTask(); - func_80143324(play, &play->skyboxCtx, play->skyboxId); + Skybox_Reload(play, &play->skyboxCtx, play->skyboxId); if ((msgCtx->msgMode != MSGMODE_NONE) && (msgCtx->currentTextId == 0xFF)) { func_80115844(play, DO_ACTION_STOP); diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index e7c3fceef3..571eef7f9e 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -2778,10 +2778,10 @@ 0x801420C0:("VisZbuf_Init",), 0x801420F4:("VisZbuf_Destroy",), 0x80142100:("VisZbuf_Draw",), - 0x80142440:("func_80142440",), - 0x80143148:("func_80143148",), + 0x80142440:("Skybox_CalculateFace128",), + 0x80143148:("Skybox_Calculate128",), 0x801431E8:("Skybox_Setup",), - 0x80143324:("func_80143324",), + 0x80143324:("Skybox_Reload",), 0x801434E4:("Skybox_Init",), 0x801435A0:("Skybox_UpdateMatrix",), 0x80143624:("Skybox_SetColors",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 6252780ed1..875cba329a 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -1901,13 +1901,13 @@ 0x801C5DE0:("D_801C5DE0","UNK_TYPE1","",0x1), 0x801C5DF0:("D_801C5DF0","UNK_TYPE1","",0x1), 0x801C5E00:("D_801C5E00","UNK_TYPE1","",0x1), - 0x801C5E30:("D_801C5E30","UNK_TYPE1","",0x1), - 0x801C5E48:("D_801C5E48","UNK_TYPE2","",0x2), - 0x801C5E88:("D_801C5E88","UNK_TYPE4","",0x4), - 0x801C5E9C:("D_801C5E9C","UNK_TYPE4","",0x4), - 0x801C5EB0:("D_801C5EB0","UNK_TYPE4","",0x4), - 0x801C5EC4:("D_801C5EC4","UNK_TYPE2","",0x2), - 0x801C5F44:("D_801C5F44","UNK_TYPE4","",0x4), + 0x801C5E30:("sSkybox128TexOffsets","UNK_TYPE1","",0x1), + 0x801C5E48:("sSkybox128VtxBufIndices","UNK_TYPE2","",0x2), + 0x801C5E88:("sSkybox128TexSCoords","UNK_TYPE4","",0x4), + 0x801C5E9C:("sSkybox128TexTCoordsXZ","UNK_TYPE4","",0x4), + 0x801C5EB0:("sSkybox128TexTCoords","UNK_TYPE4","",0x4), + 0x801C5EC4:("sSkybox128VtxIndices","UNK_TYPE2","",0x2), + 0x801C5F44:("sSkybox128FaceParams","UNK_TYPE4","",0x4), 0x801C5FC0:("sPersistentCycleSceneFlags","u32","[452]",0x710), 0x801C66D0:("sPersistentCycleWeekEventRegs","UNK_TYPE2","",0x2), 0x801C6798:("gSramSlotOffsets","UNK_TYPE4","",0x4), diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 7974f14ad5..599ac754e2 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -2292,10 +2292,10 @@ asm/non_matchings/code/z_vismono/VisMono_DrawOld.s,VisMono_DrawOld,0x8014204C,0x asm/non_matchings/code/z_viszbuf/VisZbuf_Init.s,VisZbuf_Init,0x801420C0,0xD asm/non_matchings/code/z_viszbuf/VisZbuf_Destroy.s,VisZbuf_Destroy,0x801420F4,0x3 asm/non_matchings/code/z_viszbuf/VisZbuf_Draw.s,VisZbuf_Draw,0x80142100,0xD0 -asm/non_matchings/code/z_vr_box/func_80142440.s,func_80142440,0x80142440,0x342 -asm/non_matchings/code/z_vr_box/func_80143148.s,func_80143148,0x80143148,0x28 +asm/non_matchings/code/z_vr_box/Skybox_CalculateFace128.s,Skybox_CalculateFace128,0x80142440,0x342 +asm/non_matchings/code/z_vr_box/Skybox_Calculate128.s,Skybox_Calculate128,0x80143148,0x28 asm/non_matchings/code/z_vr_box/Skybox_Setup.s,Skybox_Setup,0x801431E8,0x4F -asm/non_matchings/code/z_vr_box/func_80143324.s,func_80143324,0x80143324,0x70 +asm/non_matchings/code/z_vr_box/Skybox_Reload.s,Skybox_Reload,0x80143324,0x70 asm/non_matchings/code/z_vr_box/Skybox_Init.s,Skybox_Init,0x801434E4,0x2F asm/non_matchings/code/z_vr_box_draw/func_801435A0.s,func_801435A0,0x801435A0,0x21 asm/non_matchings/code/z_vr_box_draw/func_80143624.s,func_80143624,0x80143624,0x11