summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDerek Hensley <hensley.derek58@gmail.com>2024-01-14 10:56:19 -0800
committerGitHub <noreply@github.com>2024-01-14 15:56:19 -0300
commit663834cbc087ab7bbc9b20b48d6f06eaae4d4341 (patch)
tree0190f7985536687036148325d5d9e86419e5a710 /src
parentb2c3cc6a11d2a8e9d310fc15c11f1f25efed8a33 (diff)
Skybox Docs (#1534)
* xml * Docs * 0s
Diffstat (limited to 'src')
-rw-r--r--src/code/z_play.c6
-rw-r--r--src/code/z_vr_box.c339
-rw-r--r--src/code/z_vr_box_draw.c29
-rw-r--r--src/overlays/actors/ovl_player_actor/z_player.c2
-rw-r--r--src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c3
5 files changed, 221 insertions, 158 deletions
diff --git a/src/code/z_play.c b/src/code/z_play.c
index 7e285f02f..a193038d0 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 7819de4df..2760989ef 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),
+};
+
+// T coordinates for top and bottom faces
+s32 sSkybox128TexTCoordsXZ[] = {
+ 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 side faces
+s32 sSkybox128TexTCoords[] = {
+ TC(62 * 0), TC(62 * 1), TC(62 * 2), TC(62 * 1), TC(62 * 0),
+};
-s16 D_801C5EC4[] = {
+// 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];
-
- for (i = 0; i < 0x20; i++) {
- index = D_801C5E48[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;
+ // Select gfx buffer
+ skyboxCtx->gfx = &skyboxCtx->dListBuf[2 * faceNum][0];
+
+ // Generate and load Vertex structures
+ for (i = 0; i < ARRAY_COUNT(sSkybox128VtxBufIndices); i++) {
+ index = sSkybox128VtxBufIndices[i];
+
+ 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);
-
- 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);
+ gSPVertex(skyboxCtx->gfx++, &roomVtx[roomVtxStartIndex], 32, 0);
+ roomVtxStartIndex += i; // += 32
+
+ // 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;
-
- 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);
+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 },
+};
+
+/**
+ * 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 656f6cad3..a4066b71a 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 78555673a..6a7dfcc2e 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 01ab11523..502912da6 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);