summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rw-r--r--src/code/z_play.c5
-rw-r--r--src/code/z_vr_box.c677
-rw-r--r--src/code/z_vr_box_draw.c52
3 files changed, 417 insertions, 317 deletions
diff --git a/src/code/z_play.c b/src/code/z_play.c
index 4eeaa8111..b3d4447f5 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -1151,7 +1151,7 @@ void Play_Draw(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.unk_140 == 0) {
+ } else if (this->skyboxCtx.drawType == SKYBOX_DRAW_128) {
Skybox_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, 0, this->view.eye.x, this->view.eye.y,
this->view.eye.z);
}
@@ -1193,7 +1193,8 @@ void Play_Draw(PlayState* this) {
}
if ((R_HREG_MODE != HREG_MODE_PLAY) || R_PLAY_DRAW_SKYBOX) {
- if ((this->skyboxCtx.unk_140 != 0) && (GET_ACTIVE_CAM(this)->setting != CAM_SET_PREREND_FIXED)) {
+ if ((this->skyboxCtx.drawType != SKYBOX_DRAW_128) &&
+ (GET_ACTIVE_CAM(this)->setting != CAM_SET_PREREND_FIXED)) {
Vec3f quakeOffset;
Camera_GetQuakeOffset(&quakeOffset, GET_ACTIVE_CAM(this));
diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c
index 56cd74cb3..1b1079148 100644
--- a/src/code/z_vr_box.c
+++ b/src/code/z_vr_box.c
@@ -2,371 +2,452 @@
#include "terminal.h"
#include "z64environment.h"
-u32 D_8012AC90[4] = {
- 0x00000000,
- 0x00010000,
- 0x00020000,
- 0x00030000,
-};
-
-u16 D_8012ACA0[2][0x20] = {
- { 0x00, 0x02, 0x0A, 0x0C, 0x02, 0x04, 0x0C, 0x0E, 0x0A, 0x0C, 0x14, 0x16, 0x0C, 0x0E, 0x16, 0x18,
- 0x01, 0x03, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0B, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x15, 0x17 },
- { 0x14, 0x16, 0x1E, 0x20, 0x16, 0x18, 0x20, 0x22, 0x1E, 0x20, 0x28, 0x2A, 0x20, 0x22, 0x2A, 0x2C,
- 0x15, 0x17, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1F, 0x21, 0x23, 0x24, 0x25, 0x26, 0x27, 0x29, 0x2B },
-};
-
-s16 D_8012AD20[5] = {
- 0x0000, 0x0FC0, 0x1F80, 0x2F40, 0x3F00,
-};
-
-s16 D_8012AD2C[9] = {
- 0x0000, 0x07C0, 0x0F80, 0x1740, 0x1F00, 0x26C0, 0x2E80, 0x3640, 0x3E00,
-};
-
-s16 D_8012AD40[0x40] = {
- 0x00, 0x10, 0x13, 0x12, 0x10, 0x01, 0x14, 0x13, 0x01, 0x11, 0x15, 0x14, 0x11, 0x05, 0x16, 0x15,
- 0x12, 0x13, 0x17, 0x02, 0x13, 0x14, 0x03, 0x17, 0x14, 0x15, 0x18, 0x03, 0x15, 0x16, 0x07, 0x18,
- 0x02, 0x17, 0x1A, 0x19, 0x17, 0x03, 0x1B, 0x1A, 0x03, 0x18, 0x1C, 0x1B, 0x18, 0x07, 0x1D, 0x1C,
- 0x19, 0x1A, 0x1E, 0x0A, 0x1A, 0x1B, 0x0B, 0x1E, 0x1B, 0x1C, 0x1F, 0x0B, 0x1C, 0x1D, 0x0F, 0x1F,
-};
-
-u32 D_8012ADC0[6] = {
- 0x00000000, 0x00002000, 0x00004000, 0x00006000, 0x00008000, 0x0000C000,
-};
-
-u16 D_8012ADD8[0x20] = {
- 0x00, 0x02, 0x0A, 0x0C, 0x02, 0x04, 0x0C, 0x0E, 0x0A, 0x0C, 0x14, 0x16, 0x0C, 0x0E, 0x16, 0x18,
- 0x01, 0x03, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0B, 0x0D, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x15, 0x17,
-};
-
-s16 D_8012AE18[5] = {
- 0x0000, 0x07C0, 0x0F80, 0x1740, 0x1F00,
-};
-
-s16 D_8012AE24[5] = {
- 0x0000, 0x07C0, 0x0F80, 0x1740, 0x1F00,
+typedef struct {
+ /* 0x000 */ s32 xStart;
+ /* 0x004 */ s32 yStart;
+ /* 0x008 */ s32 zStart;
+ /* 0x00C */ s32 outerIncrVal;
+ /* 0x010 */ s32 innerIncrVal;
+} SkyboxFaceParams; // size = 0x14
+
+// 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 sSkybox256TexOffsets[4] = {
+ 256 * 256 * 0,
+ 256 * 256 * 1,
+ 256 * 256 * 2,
+ 256 * 256 * 3,
};
-s16 D_8012AE30[5] = {
- 0x0000, 0x07C0, 0x0F80, 0x07C0, 0x0000,
+// Maps vertex buffer index to coordinate buffer index
+u16 sSkybox256VtxBufIndices[2][32] = {
+ {
+ 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,
+ },
+ {
+ 20, 22, 30, 32, 22, 24, 32, 34, 30, 32, 40, 42, 32, 34, 42, 44,
+ 21, 23, 25, 26, 27, 28, 29, 31, 33, 35, 36, 37, 38, 39, 41, 43,
+ },
};
-s16 D_8012AE3C[0x40] = {
- 0x00, 0x10, 0x13, 0x12, 0x10, 0x01, 0x14, 0x13, 0x01, 0x11, 0x15, 0x14, 0x11, 0x05, 0x16, 0x15,
- 0x12, 0x13, 0x17, 0x02, 0x13, 0x14, 0x03, 0x17, 0x14, 0x15, 0x18, 0x03, 0x15, 0x16, 0x07, 0x18,
- 0x02, 0x17, 0x1A, 0x19, 0x17, 0x03, 0x1B, 0x1A, 0x03, 0x18, 0x1C, 0x1B, 0x18, 0x07, 0x1D, 0x1C,
- 0x19, 0x1A, 0x1E, 0x0A, 0x1A, 0x1B, 0x0B, 0x1E, 0x1B, 0x1C, 0x1F, 0x0B, 0x1C, 0x1D, 0x0F, 0x1F,
+// S coordinates for all faces
+s16 sSkybox256TexSCoords[5] = {
+ TC(126 * 0), TC(126 * 1), TC(126 * 2), TC(126 * 3), TC(126 * 4),
};
-typedef struct {
- /* 0x000 */ s32 unk_0;
- /* 0x004 */ s32 unk_4;
- /* 0x008 */ s32 unk_8;
- /* 0x00C */ s32 unk_C;
- /* 0x010 */ s32 unk_10;
-} Struct_8012AF0C; // size = 0x14
-
-Struct_8012AF0C D_8012AEBC[4] = {
- { -0x7E, 0x7C, -0x7E, 0x3F, -0x1F },
- { 0x7E, 0x7C, -0x7E, 0x3F, -0x1F },
- { 0x7E, 0x7C, 0x7E, -0x3F, -0x1F },
- { -0x7E, 0x7C, 0x7E, -0x3F, -0x1F },
+// T coordinates for all faces
+s16 sSkybox256TexTCoords[9] = {
+ TC(62 * 0), TC(62 * 1), TC(62 * 2), TC(62 * 3), TC(62 * 4), TC(62 * 5), TC(62 * 6), TC(62 * 7), TC(62 * 8),
};
-Struct_8012AF0C D_8012AF0C[6] = {
- { -0x40, 0x40, -0x40, 0x20, -0x20 }, { 0x40, 0x40, 0x40, -0x20, -0x20 }, { -0x40, 0x40, 0x40, -0x20, -0x20 },
- { 0x40, 0x40, -0x40, 0x20, -0x20 }, { -0x40, 0x40, 0x40, 0x20, -0x20 }, { -0x40, -0x40, -0x40, 0x20, 0x20 },
+// Maps vertex index to vertex buffer index
+s16 sSkybox256VtxIndices[64] = {
+ 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_800ADBB0(SkyboxContext* skyboxCtx, Vtx* roomVtx, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7,
- s32 arg8, s32 arg9) {
- u32 pad42C;
- s32 pad428;
- s32 sp424;
+/**
+ * Build the vertex and display list data for a skybox with 256x256 face textures.
+ *
+ * While the textures are nominally 256x256 the 4x8 tiles that cover it are only 63x31, therefore only a
+ * 253x249 area is ever sampled (253 = 4 * 63 + 1, the additional +1 accounts for bilinear filtering,
+ * similarly 249 = 8 * 31 + 1)
+ *
+ * Each texture dimension is padded to the next power of 2, resulting in a final size of 256x256.
+ */
+s32 Skybox_CalculateFace256(SkyboxContext* skyboxCtx, Vtx* roomVtx, s32 roomVtxStartIndex, s32 xStart, s32 yStart,
+ s32 zStart, s32 innerIncrVal, s32 outerIncrVal, s32 faceNum, s32 dlistBufStartIndex) {
+ u32 innerIncr;
+ s32 outerIncr;
+ s32 n;
s32 i;
s32 j;
s32 k;
u16 index;
- s16 phi_t1;
- s16 phi_a2_4;
- s16 phi_a0_4;
- s16 phi_t2_4;
- s16 phi_ra;
- s32 sp358[9 * 5];
- s32 sp2A4[9 * 5];
- s32 sp1F0[9 * 5];
- s32 sp13C[9 * 5];
- s32 sp88[9 * 5];
+ s16 m;
+ s16 ult;
+ s16 uls;
+ s16 vtxIdx;
+ s16 l;
+ s32 xPoints[9 * 5];
+ s32 yPoints[9 * 5];
+ s32 zPoints[9 * 5];
+ s32 tcS[9 * 5];
+ s32 tcT[9 * 5];
s32 pad;
- switch (arg8) {
- case 0:
+ // Collect all vertex positions for this face
+ switch (faceNum) {
+ case 0: // xy plane
case 2:
- pad428 = arg4;
+ outerIncr = yStart;
+
+ for (i = 0, k = 0; k < 9 * 5; i++) {
+ innerIncr = xStart;
- for (i = 0, k = 0; k < 45; i++) {
- pad42C = arg3;
for (j = 0; j < 5; j++, k++) {
- sp1F0[k] = arg5;
- sp358[k] = pad42C;
- sp2A4[k] = pad428;
- sp13C[k] = D_8012AD20[j];
- sp88[k] = D_8012AD2C[i];
- pad42C += arg6;
+ zPoints[k] = zStart;
+ xPoints[k] = innerIncr;
+ yPoints[k] = outerIncr;
+ tcS[k] = sSkybox256TexSCoords[j];
+ tcT[k] = sSkybox256TexTCoords[i];
+ innerIncr += innerIncrVal;
}
- pad428 += arg7;
+ outerIncr += outerIncrVal;
}
break;
- case 1:
+ case 1: // yz plane
case 3:
- pad428 = arg4;
+ outerIncr = yStart;
+
+ for (i = 0, k = 0; k < 9 * 5; i++) {
+ innerIncr = zStart;
- for (i = 0, k = 0; k < 45; i++) {
- pad42C = arg5;
for (j = 0; j < 5; j++, k++) {
- sp358[k] = arg3;
- sp2A4[k] = pad428;
- sp1F0[k] = pad42C;
- sp13C[k] = D_8012AD20[j];
- sp88[k] = D_8012AD2C[i];
- pad42C += arg6;
+ xPoints[k] = xStart;
+ yPoints[k] = outerIncr;
+ zPoints[k] = innerIncr;
+ tcS[k] = sSkybox256TexSCoords[j];
+ tcT[k] = sSkybox256TexTCoords[i];
+ innerIncr += innerIncrVal;
}
- pad428 += arg7;
+ outerIncr += outerIncrVal;
}
break;
- case 4:
+ case 4: // xz plane
case 5:
- pad428 = arg5;
+ outerIncr = zStart;
+
+ for (i = 0, k = 0; k < 9 * 5; i++) {
+ innerIncr = xStart;
- for (i = 0, k = 0; k < 45; i++) {
- pad42C = arg3;
for (j = 0; j < 5; j++, k++) {
- sp2A4[k] = arg4;
- sp358[k] = pad42C;
- sp1F0[k] = pad428;
- sp13C[k] = D_8012AD20[j];
- sp88[k] = D_8012AD2C[i];
- pad42C += arg6;
+ yPoints[k] = yStart;
+ xPoints[k] = innerIncr;
+ zPoints[k] = outerIncr;
+ tcS[k] = sSkybox256TexSCoords[j];
+ tcT[k] = sSkybox256TexTCoords[i];
+ innerIncr += innerIncrVal;
}
- pad428 += arg7;
+ outerIncr += outerIncrVal;
}
break;
}
- for (phi_a2_4 = 0, sp424 = 0; sp424 < 2; sp424++) {
- skyboxCtx->unk_138 = skyboxCtx->dListBuf[arg9 + sp424];
-
- for (i = 0; i < 0x20; i++) {
- index = D_8012ACA0[sp424][i];
-
- roomVtx[arg2 + i].v.ob[0] = sp358[index];
- roomVtx[arg2 + i].v.ob[1] = sp2A4[index];
- roomVtx[arg2 + i].v.ob[2] = sp1F0[index];
- roomVtx[arg2 + i].v.flag = 0;
- roomVtx[arg2 + i].v.tc[0] = sp13C[index];
- roomVtx[arg2 + i].v.tc[1] = sp88[index];
- roomVtx[arg2 + i].v.cn[1] = 0;
- roomVtx[arg2 + i].v.cn[2] = 0;
- roomVtx[arg2 + i].v.cn[0] = 255;
+ // For a 256x256 texture with 63x31 tiles there are 32 tiles which requires at least 45 vertices,
+ // 45 > 32 (the maximum number of vertices that can be loaded at once) so it is split into two passes
+ for (ult = 0, n = 0; n < 2; n++) {
+ // Each iteration is 16 tiles of the texture, first iteration is the top 16 tiles
+
+ // Select gfx buffer
+ skyboxCtx->gfx = skyboxCtx->dListBuf[dlistBufStartIndex + n];
+
+ // Generate and load Vertex structures
+ for (i = 0; i < 32; i++) {
+ index = sSkybox256VtxBufIndices[n][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->unk_138++, &roomVtx[arg2], 32, 0);
- arg2 += i;
- gSPCullDisplayList(skyboxCtx->unk_138++, 0, 15);
-
- 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 += 0x3F, phi_t2_4 += 4) {
- gDPLoadTextureTile(skyboxCtx->unk_138++, (u32)skyboxCtx->staticSegments[0] + D_8012AC90[arg8],
- G_IM_FMT_CI, G_IM_SIZ_8b, 256, 0, phi_a0_4, phi_a2_4, phi_a0_4 + 0x3F,
- 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->unk_138++, D_8012AD40[phi_t2_4 + 1], D_8012AD40[phi_t2_4 + 2],
- D_8012AD40[phi_t2_4 + 3], D_8012AD40[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
+ for (vtxIdx = 0, l = 0; l < 4; l++, ult += 31) {
+ for (uls = 0, m = 0; m < 4; m++, uls += 63, vtxIdx += 4) {
+ gDPLoadTextureTile(skyboxCtx->gfx++, (u32)skyboxCtx->staticSegments[0] + sSkybox256TexOffsets[faceNum],
+ G_IM_FMT_CI, G_IM_SIZ_8b, 256, 0, uls, ult, uls + 63, 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++, sSkybox256VtxIndices[vtxIdx + 1], sSkybox256VtxIndices[vtxIdx + 2],
+ sSkybox256VtxIndices[vtxIdx + 3], sSkybox256VtxIndices[vtxIdx + 0], 3);
}
}
- gSPEndDisplayList(skyboxCtx->unk_138++);
+ gSPEndDisplayList(skyboxCtx->gfx++);
}
- return arg2;
+ return roomVtxStartIndex;
}
-s32 func_800AE2C0(SkyboxContext* skyboxCtx, Vtx* roomVtx, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7,
- s32 arg8) {
+// Texture offsets for each face in the static segment buffer
+u32 sSkybox128TexOffsets[6] = {
+ 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[32] = {
+ 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,
+};
+
+// S coordinates for all faces
+s16 sSkybox128TexSCoords[5] = {
+ TC(62 * 0), TC(62 * 1), TC(62 * 2), TC(62 * 3), TC(62 * 4),
+};
+
+// T coordinates for top and bottom faces
+s16 sSkybox128TexTCoordsXZ[5] = {
+ TC(62 * 0), TC(62 * 1), TC(62 * 2), TC(62 * 3), TC(62 * 4),
+};
+
+// T coordinates for side faces
+s16 sSkybox128TexTCoords[5] = {
+ TC(62 * 0), TC(62 * 1), TC(62 * 2), TC(62 * 1), TC(62 * 0),
+};
+
+// Maps vertex index to vertex buffer index
+s16 sSkybox128VtxIndices[64] = {
+ 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,
+};
+
+/**
+ * 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 (see `Skybox_CalculateFace256` for more details)
+ *
+ * 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 sp2B4[5 * 5];
- s32 sp250[5 * 5];
- s32 sp1EC[5 * 5];
- s32 sp188[5 * 5];
- s32 sp124[5 * 5];
+ s16 ult;
+ s16 l;
+ s16 vtxIdx;
+ 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++) {
- sp1EC[k] = arg5;
- sp2B4[k] = temp2;
- sp250[k] = temp1;
- sp188[k] = D_8012AE18[j];
- sp124[k] = D_8012AE30[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++) {
- sp2B4[k] = arg3;
- sp250[k] = temp1;
- sp1EC[k] = temp2;
- sp188[k] = D_8012AE18[j];
- sp124[k] = D_8012AE30[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++) {
- sp250[k] = arg4;
- sp2B4[k] = temp2;
- sp1EC[k] = temp1;
- sp188[k] = D_8012AE18[j];
- sp124[k] = D_8012AE24[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;
}
- skyboxCtx->unk_138 = &skyboxCtx->dListBuf[2 * arg8][0];
-
- for (i = 0; i < 0x20; i++) {
- index = D_8012ADD8[i];
-
- roomVtx[arg2 + i].v.ob[0] = sp2B4[index];
- roomVtx[arg2 + i].v.ob[1] = sp250[index];
- roomVtx[arg2 + i].v.ob[2] = sp1EC[index];
- roomVtx[arg2 + i].v.flag = 0;
- roomVtx[arg2 + i].v.tc[0] = sp188[index];
- roomVtx[arg2 + i].v.tc[1] = sp124[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 < 32; 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->unk_138++, &roomVtx[arg2], 32, 0);
- arg2 += i;
- gSPCullDisplayList(skyboxCtx->unk_138++, 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->unk_138++, (u32)skyboxCtx->staticSegments[0] + D_8012ADC0[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->unk_138++, (u32)skyboxCtx->staticSegments[1] + D_8012ADC0[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,
+ gSPVertex(skyboxCtx->gfx++, &roomVtx[roomVtxStartIndex], 32, 0);
+ roomVtxStartIndex += i;
+
+ // 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 (vtxIdx = 0, l = 0; l < 4; l++, ult += 31) {
+ for (uls = 0, m = 0; m < 4; m++, uls += 31, vtxIdx += 4) {
+ gDPLoadMultiTile(skyboxCtx->gfx++, (u32)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);
- gSP1Quadrangle(skyboxCtx->unk_138++, D_8012AE3C[phi_t2_4 + 1], D_8012AE3C[phi_t2_4 + 2],
- D_8012AE3C[phi_t2_4 + 3], D_8012AE3C[phi_t2_4 + 0], 3);
+ gDPLoadMultiTile(skyboxCtx->gfx++, (u32)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[vtxIdx + 1], sSkybox128VtxIndices[vtxIdx + 2],
+ sSkybox128VtxIndices[vtxIdx + 3], sSkybox128VtxIndices[vtxIdx + 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->unk_138++, (u32)skyboxCtx->staticSegments[0] + D_8012ADC0[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->unk_138++, (u32)skyboxCtx->staticSegments[1] + D_8012ADC0[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,
+ // other faces, 128x64 texture
+
+ ult = 0;
+ for (vtxIdx = 0, l = 0; l < 2; l++, ult += 31) {
+ for (uls = 0, m = 0; m < 4; m++, uls += 31, vtxIdx += 4) {
+ gDPLoadMultiTile(skyboxCtx->gfx++, (u32)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++, (u32)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->unk_138++, D_8012AE3C[phi_t2_4 + 1], D_8012AE3C[phi_t2_4 + 2],
- D_8012AE3C[phi_t2_4 + 3], D_8012AE3C[phi_t2_4 + 0], 3);
+ gSP1Quadrangle(skyboxCtx->gfx++, sSkybox128VtxIndices[vtxIdx + 1], sSkybox128VtxIndices[vtxIdx + 2],
+ sSkybox128VtxIndices[vtxIdx + 3], sSkybox128VtxIndices[vtxIdx + 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->unk_138++, (u32)skyboxCtx->staticSegments[0] + D_8012ADC0[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->unk_138++, (u32)skyboxCtx->staticSegments[1] + D_8012ADC0[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,
+ ult -= 31;
+ for (l = 0; l < 2; l++, ult -= 31) {
+ for (uls = 0, m = 0; m < 4; m++, uls += 31, vtxIdx += 4) {
+ gDPLoadMultiTile(skyboxCtx->gfx++, (u32)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++, (u32)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->unk_138++, D_8012AE3C[phi_t2_4 + 1], D_8012AE3C[phi_t2_4 + 2],
- D_8012AE3C[phi_t2_4 + 3], D_8012AE3C[phi_t2_4 + 0], 3);
+ gSP1Quadrangle(skyboxCtx->gfx++, sSkybox128VtxIndices[vtxIdx + 1], sSkybox128VtxIndices[vtxIdx + 2],
+ sSkybox128VtxIndices[vtxIdx + 3], sSkybox128VtxIndices[vtxIdx + 0], 3);
}
}
}
- gSPEndDisplayList(skyboxCtx->unk_138++);
- return arg2;
+ gSPEndDisplayList(skyboxCtx->gfx++);
+ return roomVtxStartIndex;
}
-void func_800AEFC8(SkyboxContext* skyboxCtx, s16 skyboxId) {
- s32 i;
- s32 j;
- s32 phi_s3 = 0;
+SkyboxFaceParams sSkybox256FaceParams[4] = {
+ { -126, 124, -126, 63, -31 },
+ { 126, 124, -126, 63, -31 },
+ { 126, 124, 126, -63, -31 },
+ { -126, 124, 126, -63, -31 },
+};
+
+/**
+ * Computes the display list for a skybox where each face is a 256x256 CI8 texture.
+ * The number of faces is determined by the skybox id or from the drawType field in SkyboxContext.
+ */
+void Skybox_Calculate256(SkyboxContext* skyboxCtx, s16 skyboxId) {
+ s32 faceNum;
+ s32 dlistBufStartIndex;
+ s32 roomVtxStartIndex = 0;
if (skyboxId == SKYBOX_BAZAAR || (skyboxId > SKYBOX_HOUSE_KAKARIKO && skyboxId <= SKYBOX_BOMBCHU_SHOP)) {
- for (j = 0, i = 0; i < 2; i++, j += 2) {
- phi_s3 = func_800ADBB0(skyboxCtx, skyboxCtx->roomVtx, phi_s3, D_8012AEBC[i].unk_0, D_8012AEBC[i].unk_4,
- D_8012AEBC[i].unk_8, D_8012AEBC[i].unk_C, D_8012AEBC[i].unk_10, i, j);
+ // 2 faces, one in xy plane and one in yz plane
+ for (dlistBufStartIndex = 0, faceNum = 0; faceNum < 2; faceNum++, dlistBufStartIndex += 2) {
+ roomVtxStartIndex = Skybox_CalculateFace256(
+ skyboxCtx, skyboxCtx->roomVtx, roomVtxStartIndex, sSkybox256FaceParams[faceNum].xStart,
+ sSkybox256FaceParams[faceNum].yStart, sSkybox256FaceParams[faceNum].zStart,
+ sSkybox256FaceParams[faceNum].outerIncrVal, sSkybox256FaceParams[faceNum].innerIncrVal, faceNum,
+ dlistBufStartIndex);
}
- } else if (skyboxCtx->unk_140 == 2) {
- for (j = 0, i = 0; i < 3; i++, j += 2) {
- phi_s3 = func_800ADBB0(skyboxCtx, skyboxCtx->roomVtx, phi_s3, D_8012AEBC[i].unk_0, D_8012AEBC[i].unk_4,
- D_8012AEBC[i].unk_8, D_8012AEBC[i].unk_C, D_8012AEBC[i].unk_10, i, j);
+ } else if (skyboxCtx->drawType == SKYBOX_DRAW_256_3FACE) {
+ // 3 faces, 2 in xy plane and 1 in yz plane
+ for (dlistBufStartIndex = 0, faceNum = 0; faceNum < 3; faceNum++, dlistBufStartIndex += 2) {
+ roomVtxStartIndex = Skybox_CalculateFace256(
+ skyboxCtx, skyboxCtx->roomVtx, roomVtxStartIndex, sSkybox256FaceParams[faceNum].xStart,
+ sSkybox256FaceParams[faceNum].yStart, sSkybox256FaceParams[faceNum].zStart,
+ sSkybox256FaceParams[faceNum].outerIncrVal, sSkybox256FaceParams[faceNum].innerIncrVal, faceNum,
+ dlistBufStartIndex);
}
} else {
- for (j = 0, i = 0; i < 4; i++, j += 2) {
- phi_s3 = func_800ADBB0(skyboxCtx, skyboxCtx->roomVtx, phi_s3, D_8012AEBC[i].unk_0, D_8012AEBC[i].unk_4,
- D_8012AEBC[i].unk_8, D_8012AEBC[i].unk_C, D_8012AEBC[i].unk_10, i, j);
+ // 4 faces, 2 in xy plane and 2 in yz plane
+ for (dlistBufStartIndex = 0, faceNum = 0; faceNum < 4; faceNum++, dlistBufStartIndex += 2) {
+ roomVtxStartIndex = Skybox_CalculateFace256(
+ skyboxCtx, skyboxCtx->roomVtx, roomVtxStartIndex, sSkybox256FaceParams[faceNum].xStart,
+ sSkybox256FaceParams[faceNum].yStart, sSkybox256FaceParams[faceNum].zStart,
+ sSkybox256FaceParams[faceNum].outerIncrVal, sSkybox256FaceParams[faceNum].innerIncrVal, faceNum,
+ dlistBufStartIndex);
}
}
}
-void func_800AF178(SkyboxContext* skyboxCtx, s32 arg1) {
- s32 phi_s2 = 0;
- s32 i;
+SkyboxFaceParams sSkybox128FaceParams[6] = {
+ { -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 (i = 0; i < arg1; i++) {
- phi_s2 = func_800AE2C0(skyboxCtx, skyboxCtx->roomVtx, phi_s2, D_8012AF0C[i].unk_0, D_8012AF0C[i].unk_4,
- D_8012AF0C[i].unk_8, D_8012AF0C[i].unk_C, D_8012AF0C[i].unk_10, i);
+/**
+ * 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);
}
}
@@ -447,7 +528,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
break;
case SKYBOX_BAZAAR:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_SP1a_staticSegmentRomStart;
size = (uintptr_t)_vr_SP1a_staticSegmentRomEnd - start;
@@ -489,7 +570,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug((u8*)skyboxCtx->palettes + size, start, size, "../z_vr_box.c", 1175);
break;
case SKYBOX_MARKET_ADULT:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_RUVR_staticSegmentRomStart;
size = (uintptr_t)_vr_RUVR_staticSegmentRomEnd - start;
@@ -535,7 +616,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
size, "../z_vr_box.c", 1216);
break;
case SKYBOX_HOUSE_LINK:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_LHVR_staticSegmentRomStart;
size = (uintptr_t)_vr_LHVR_staticSegmentRomEnd - start;
@@ -553,7 +634,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1233);
break;
case SKYBOX_MARKET_CHILD_DAY:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_MDVR_staticSegmentRomStart;
size = (uintptr_t)_vr_MDVR_staticSegmentRomEnd - start;
@@ -571,7 +652,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1264);
break;
case SKYBOX_MARKET_CHILD_NIGHT:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_MNVR_staticSegmentRomStart;
size = (uintptr_t)_vr_MNVR_staticSegmentRomEnd - start;
@@ -591,7 +672,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1279);
break;
case SKYBOX_HAPPY_MASK_SHOP:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_FCVR_staticSegmentRomStart;
size = (uintptr_t)_vr_FCVR_staticSegmentRomEnd - start;
@@ -610,7 +691,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
skyboxCtx->rot.y = 0.8f;
break;
case SKYBOX_HOUSE_KNOW_IT_ALL_BROTHERS:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_KHVR_staticSegmentRomStart;
size = (uintptr_t)_vr_KHVR_staticSegmentRomEnd - start;
@@ -628,7 +709,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1308);
break;
case SKYBOX_HOUSE_OF_TWINS:
- skyboxCtx->unk_140 = 2;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_3FACE;
start = (uintptr_t)_vr_K3VR_staticSegmentRomStart;
size = (uintptr_t)_vr_K3VR_staticSegmentRomEnd - start;
@@ -646,7 +727,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1338);
break;
case SKYBOX_STABLES:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_MLVR_staticSegmentRomStart;
size = (uintptr_t)_vr_MLVR_staticSegmentRomEnd - start;
@@ -664,7 +745,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1352);
break;
case SKYBOX_HOUSE_KAKARIKO:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_KKRVR_staticSegmentRomStart;
size = (uintptr_t)_vr_KKRVR_staticSegmentRomEnd - start;
@@ -682,7 +763,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1366);
break;
case SKYBOX_KOKIRI_SHOP:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_KSVR_staticSegmentRomStart;
size = (uintptr_t)_vr_KSVR_staticSegmentRomEnd - start;
@@ -701,7 +782,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
skyboxCtx->rot.y = 0.8f;
break;
case SKYBOX_GORON_SHOP:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_GLVR_staticSegmentRomStart;
size = (uintptr_t)_vr_GLVR_staticSegmentRomEnd - start;
@@ -720,7 +801,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
skyboxCtx->rot.y = 0.8f;
break;
case SKYBOX_ZORA_SHOP:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_ZRVR_staticSegmentRomStart;
size = (uintptr_t)_vr_ZRVR_staticSegmentRomEnd - start;
@@ -739,7 +820,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
skyboxCtx->rot.y = 0.8f;
break;
case SKYBOX_POTION_SHOP_KAKARIKO:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_DGVR_staticSegmentRomStart;
size = (uintptr_t)_vr_DGVR_staticSegmentRomEnd - start;
@@ -758,7 +839,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
skyboxCtx->rot.y = 0.8f;
break;
case SKYBOX_POTION_SHOP_MARKET:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_ALVR_staticSegmentRomStart;
size = (uintptr_t)_vr_ALVR_staticSegmentRomEnd - start;
@@ -777,7 +858,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
skyboxCtx->rot.y = 0.8f;
break;
case SKYBOX_BOMBCHU_SHOP:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_NSVR_staticSegmentRomStart;
size = (uintptr_t)_vr_NSVR_staticSegmentRomEnd - start;
@@ -796,7 +877,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
skyboxCtx->rot.y = 0.8f;
break;
case SKYBOX_HOUSE_RICHARD:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_IPVR_staticSegmentRomStart;
size = (uintptr_t)_vr_IPVR_staticSegmentRomEnd - start;
@@ -814,7 +895,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1519);
break;
case SKYBOX_HOUSE_IMPA:
- skyboxCtx->unk_140 = 1;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_4FACE;
start = (uintptr_t)_vr_LBVR_staticSegmentRomStart;
size = (uintptr_t)_vr_LBVR_staticSegmentRomEnd - start;
@@ -832,7 +913,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1533);
break;
case SKYBOX_TENT:
- skyboxCtx->unk_140 = 2;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_3FACE;
start = (uintptr_t)_vr_TTVR_staticSegmentRomStart;
size = (uintptr_t)_vr_TTVR_staticSegmentRomEnd - start;
@@ -850,7 +931,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1547);
break;
case SKYBOX_HOUSE_MIDO:
- skyboxCtx->unk_140 = 2;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_3FACE;
start = (uintptr_t)_vr_K4VR_staticSegmentRomStart;
size = (uintptr_t)_vr_K4VR_staticSegmentRomEnd - start;
@@ -868,7 +949,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1567);
break;
case SKYBOX_HOUSE_SARIA:
- skyboxCtx->unk_140 = 2;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_3FACE;
start = (uintptr_t)_vr_K5VR_staticSegmentRomStart;
size = (uintptr_t)_vr_K5VR_staticSegmentRomEnd - start;
@@ -886,7 +967,7 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
DmaMgr_RequestSyncDebug(skyboxCtx->palettes, start, size, "../z_vr_box.c", 1581);
break;
case SKYBOX_HOUSE_ALLEY:
- skyboxCtx->unk_140 = 2;
+ skyboxCtx->drawType = SKYBOX_DRAW_256_3FACE;
start = (uintptr_t)_vr_KR3VR_staticSegmentRomStart;
size = (uintptr_t)_vr_KR3VR_staticSegmentRomEnd - start;
@@ -911,40 +992,42 @@ void Skybox_Setup(PlayState* play, SkyboxContext* skyboxCtx, s16 skyboxId) {
void Skybox_Init(GameState* state, SkyboxContext* skyboxCtx, s16 skyboxId) {
PlayState* play = (PlayState*)state;
- skyboxCtx->unk_140 = 0;
+ skyboxCtx->drawType = SKYBOX_DRAW_128;
skyboxCtx->rot.x = skyboxCtx->rot.y = skyboxCtx->rot.z = 0.0f;
+ // DMA required assets based on skybox id
Skybox_Setup(play, skyboxCtx, skyboxId);
osSyncPrintf("\n\n\n********************\n\n\n"
"TYPE=%d"
"\n\n\n********************\n\n\n",
skyboxId);
+ // Precompute vertices and display lists for drawing the skybox
if (skyboxId != SKYBOX_NONE) {
osSyncPrintf(VT_FGCOL(GREEN));
- if (skyboxCtx->unk_140 != 0) {
+ if (skyboxCtx->drawType != SKYBOX_DRAW_128) {
skyboxCtx->dListBuf = GameState_Alloc(state, 8 * 150 * sizeof(Gfx), "../z_vr_box.c", 1636);
ASSERT(skyboxCtx->dListBuf != NULL, "vr_box->dpList != NULL", "../z_vr_box.c", 1637);
- skyboxCtx->roomVtx = GameState_Alloc(state, 256 * sizeof(Vtx), "../z_vr_box.c", 1639);
+ skyboxCtx->roomVtx = GameState_Alloc(state, 8 * 32 * sizeof(Vtx), "../z_vr_box.c", 1639);
ASSERT(skyboxCtx->roomVtx != NULL, "vr_box->roomVtx != NULL", "../z_vr_box.c", 1640);
- func_800AEFC8(skyboxCtx, skyboxId);
+ Skybox_Calculate256(skyboxCtx, skyboxId);
} else {
skyboxCtx->dListBuf = GameState_Alloc(state, 12 * 150 * sizeof(Gfx), "../z_vr_box.c", 1643);
ASSERT(skyboxCtx->dListBuf != NULL, "vr_box->dpList != NULL", "../z_vr_box.c", 1644);
if (skyboxId == SKYBOX_CUTSCENE_MAP) {
- skyboxCtx->roomVtx = GameState_Alloc(state, 192 * sizeof(Vtx), "../z_vr_box.c", 1648);
+ skyboxCtx->roomVtx = GameState_Alloc(state, 6 * 32 * sizeof(Vtx), "../z_vr_box.c", 1648);
ASSERT(skyboxCtx->roomVtx != NULL, "vr_box->roomVtx != NULL", "../z_vr_box.c", 1649);
- func_800AF178(skyboxCtx, 6);
+ Skybox_Calculate128(skyboxCtx, 6); // compute all 6 faces
} else {
- skyboxCtx->roomVtx = GameState_Alloc(state, 160 * sizeof(Vtx), "../z_vr_box.c", 1653);
+ skyboxCtx->roomVtx = GameState_Alloc(state, 5 * 32 * sizeof(Vtx), "../z_vr_box.c", 1653);
ASSERT(skyboxCtx->roomVtx != NULL, "vr_box->roomVtx != NULL", "../z_vr_box.c", 1654);
- func_800AF178(skyboxCtx, 5);
+ Skybox_Calculate128(skyboxCtx, 5); // compute 5 faces, excludes the bottom face
}
}
osSyncPrintf(VT_RST);
diff --git a/src/code/z_vr_box_draw.c b/src/code/z_vr_box_draw.c
index 60fa408d0..96a785118 100644
--- a/src/code/z_vr_box_draw.c
+++ b/src/code/z_vr_box_draw.c
@@ -23,8 +23,8 @@ void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId
gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 0, 0, 0, blend);
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_RotateX(skyboxCtx->rot.x, MTXMODE_APPLY);
@@ -33,45 +33,61 @@ void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId
Matrix_ToMtx(sSkyboxDrawMatrix, "../z_vr_box_draw.c", 76);
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);
+ // All skyboxes use CI8 textures with an RGBA16 palette
gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palettes[0]);
gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_RGBA16);
+
+ // Enable texture filtering RDP pipeline stages for bilinear filtering
gDPSetTextureConvert(POLY_OPA_DISP++, G_TC_FILT);
- if (skyboxCtx->unk_140) {
- gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[0]);
- gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[1]);
+ if (skyboxCtx->drawType != SKYBOX_DRAW_128) {
+ // 256x256 textures, per-face palettes
+ // 2, 3 or 4 faces
+
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[0]); // -z face upper
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[1]); // -z face lower
gDPPipeSync(POLY_OPA_DISP++);
gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palettes[1]);
- gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[2]);
- gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[3]);
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[2]); // +x face upper
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[3]); // +x face lower
if (skyboxId != SKYBOX_BAZAAR) {
- if (skyboxId <= SKYBOX_HOUSE_KAKARIKO || skyboxId > SKYBOX_BOMBCHU_SHOP) {
+ if (skyboxId < SKYBOX_KOKIRI_SHOP || skyboxId > SKYBOX_BOMBCHU_SHOP) {
+ // Skip remaining faces for most shop skyboxes
+
gDPPipeSync(POLY_OPA_DISP++);
gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palettes[2]);
- gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[4]);
- gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[5]);
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[4]); // +z face upper
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[5]); // +z face lower
+ // Note this pipesync is slightly misplaced and would be better off inside the condition
gDPPipeSync(POLY_OPA_DISP++);
- if (skyboxCtx->unk_140 != 2) {
+
+ if (skyboxCtx->drawType != SKYBOX_DRAW_256_3FACE) {
gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palettes[3]);
- gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[6]);
- gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[7]);
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[6]); // -x face upper
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[7]); // -x face lower
}
}
}
} else {
- 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]);
+ // 128x128 and 128x64 textures
+ // 5 or 6 faces
+
+ // 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 in the cutscene map
+ gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[10]); // -y face
}
}