summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rw-r--r--src/code/PreRender.c18
-rw-r--r--src/code/z_actor.c13
-rw-r--r--src/code/z_rcp.c12
-rw-r--r--src/code/z_room.c6
4 files changed, 37 insertions, 12 deletions
diff --git a/src/code/PreRender.c b/src/code/PreRender.c
index ddf6b473e..d240f6c80 100644
--- a/src/code/PreRender.c
+++ b/src/code/PreRender.c
@@ -431,7 +431,8 @@ void PreRender_RestoreZBuffer(PreRender* this, Gfx** gfxP) {
/**
* Draws a full-screen image to the current framebuffer, that sources the rgb channel from `this->fbufSave` and
- * the alpha channel from `this->cvgSave` modulated by environment color.
+ * the alpha channel from `this->cvgSave` modulated by environment color. The alpha channel becomes the framebuffer's
+ * coverage content.
*/
void func_800C213C(PreRender* this, Gfx** gfxP) {
Gfx* gfx;
@@ -450,6 +451,7 @@ void func_800C213C(PreRender* this, Gfx** gfxP) {
gDPSetEnvColor(gfx++, 255, 255, 255, 32);
// Effectively disable blending in both cycles. It's 2-cycle so that TEXEL1 can be used to point to a different
// texture tile.
+ // CVG_X_ALPHA in this mode transfers combined alpha to coverage.
gDPSetOtherMode(gfx++,
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_2CYCLE | G_PM_NPRIMITIVE,
@@ -460,7 +462,12 @@ void func_800C213C(PreRender* this, Gfx** gfxP) {
// Set up the color combiner: first cycle: TEXEL0, TEXEL1 + ENVIRONMENT; second cycle: G_CC_PASS2
gDPSetCombineLERP(gfx++, 0, 0, 0, TEXEL0, 1, 0, TEXEL1, ENVIRONMENT, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED);
- nRows = 4;
+ // The first 0xA00 bytes of TMEM are reserved for framebuffer data (TEXEL0, RGBA16)
+ // The last 0x500 bytes of the remaining 0x600 bytes of TMEM is for coverage data (TEXEL1, I8)
+ // In total it needs to simultaneously fit
+ // SCREEN_WIDTH * (RGBA16 pixel + I8 pixel) = SCREEN_WIDTH * (2 bytes + 1 byte)
+#define FB_ROWS (TMEM_SIZE / (3 * SCREEN_WIDTH))
+ nRows = FB_ROWS;
rowsRemaining = this->height;
curRow = 0;
@@ -486,9 +493,9 @@ void func_800C213C(PreRender* this, Gfx** gfxP) {
rtile = rtile; // Fake match?
// Load the coverage line
- gDPLoadMultiTile(gfx++, this->cvgSave, 0x0160, rtile, G_IM_FMT_I, G_IM_SIZ_8b, this->width, this->height,
- uls, ult, lrs, lrt, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
- G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
+ gDPLoadMultiTile(gfx++, this->cvgSave, (TMEM_SIZE - SCREEN_WIDTH * FB_ROWS) / 8, rtile, G_IM_FMT_I,
+ G_IM_SIZ_8b, this->width, this->height, uls, ult, lrs, lrt, 0, G_TX_NOMIRROR | G_TX_WRAP,
+ G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
rtile = rtile; // Fake match?
@@ -500,6 +507,7 @@ void func_800C213C(PreRender* this, Gfx** gfxP) {
curRow += nRows;
rowsRemaining -= nRows;
}
+#undef FB_ROWS
gDPPipeSync(gfx++);
*gfxP = gfx;
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index ce2b883b0..109bc4acb 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -2709,6 +2709,14 @@ void Actor_DrawLensActors(PlayState* play, s32 numInvisibleActors, Actor** invis
// the z-buffer will later only allow drawing inside the lens circle
} else {
// Update the z-buffer but not the color frame buffer
+ // The render mode here sets the following modes for framebuffer and z-buffer access:
+ // - Framebuffer reads & writes
+ // - Z-Buffer writes only, value from primitive Z
+ // - Framebuffer coverage is unchanged
+ // Since the goal is to mask the z-buffer, there are two options:
+ // - Set the FB to the ZB and render a texture over it
+ // - Read and write the FB without changes to its contents, since ZB writes only happen when FB writes happen
+ // Here the second option is used.
gDPSetOtherMode(POLY_XLU_DISP++,
G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
@@ -4512,7 +4520,7 @@ Gfx* func_80034B54(GraphicsContext* gfxCtx) {
displayList = displayListHead = GRAPH_ALLOC(gfxCtx, 2 * sizeof(Gfx));
- gDPSetRenderMode(displayListHead++, G_RM_FOG_SHADE_A, Z_UPD | G_RM_AA_ZB_XLU_SURF2);
+ gDPSetRenderMode(displayListHead++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2 | Z_UPD);
gSPEndDisplayList(displayListHead++);
@@ -4710,8 +4718,7 @@ Vec3f D_80116268 = { 0.0f, -1.5f, 0.0f };
Vec3f D_80116274 = { 0.0f, -0.2f, 0.0f };
Gfx D_80116280[] = {
- gsDPSetRenderMode(G_RM_FOG_SHADE_A, AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU |
- FORCE_BL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
+ gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2 | Z_UPD),
gsDPSetAlphaCompare(G_AC_THRESHOLD),
gsSPEndDisplayList(),
};
diff --git a/src/code/z_rcp.c b/src/code/z_rcp.c
index 657bd9e56..76cc6c467 100644
--- a/src/code/z_rcp.c
+++ b/src/code/z_rcp.c
@@ -223,6 +223,9 @@ Gfx sSetupDL[SETUPDL_MAX][6] = {
gsDPPipeSync(),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPSetCombineMode(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM),
+ // This render mode uses CVG_X_ALPHA to transfer texture alpha to coverage, but the coverage written to the
+ // framebuffer is always full. It also doesn't write depth, but uses an opaque Z mode. It's hard to say what
+ // the intention was here.
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PIXEL | AA_EN | Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
@@ -723,9 +726,7 @@ Gfx sSetupDL[SETUPDL_MAX][6] = {
gsDPSetCombineMode(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM),
gsDPSetOtherMode(G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
- G_AC_THRESHOLD | G_ZS_PIXEL | Z_UPD | IM_RD | CVG_DST_SAVE | ZMODE_OPA | FORCE_BL |
- GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) |
- GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)),
+ G_AC_THRESHOLD | G_ZS_PIXEL | G_RM_CLD_SURF | G_RM_CLD_SURF2 | Z_UPD),
gsSPLoadGeometryMode(G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH),
gsSPEndDisplayList(),
},
@@ -756,6 +757,8 @@ Gfx sSetupDL[SETUPDL_MAX][6] = {
gsDPPipeSync(),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
+ // This render mode is a non-AA texture edge mode that writes full coverage to the framebuffer for all pixels.
+ // The c2 render mode would be G_RM_PASS2 if it were defined.
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PIXEL | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
@@ -768,6 +771,7 @@ Gfx sSetupDL[SETUPDL_MAX][6] = {
gsDPPipeSync(),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPSetCombineMode(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM),
+ // Same as SETUPDL_66
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PIXEL | Z_CMP | Z_UPD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
@@ -780,6 +784,7 @@ Gfx sSetupDL[SETUPDL_MAX][6] = {
gsDPPipeSync(),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
+ // This render mode would be RM_ZB_SUB_SURF if it were defined.
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PIXEL | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
@@ -793,6 +798,7 @@ Gfx sSetupDL[SETUPDL_MAX][6] = {
gsDPPipeSync(),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPSetCombineMode(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM),
+ // This render mode would be RM_ZB_SUB_SURF if it were defined.
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PIXEL | Z_CMP | Z_UPD | IM_RD | CVG_DST_FULL | ZMODE_OPA | CVG_X_ALPHA |
diff --git a/src/code/z_room.c b/src/code/z_room.c
index 29f23ebe0..ebcb9de74 100644
--- a/src/code/z_room.c
+++ b/src/code/z_room.c
@@ -348,13 +348,17 @@ void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 hei
gDPSetOtherMode(gfx++, tlutMode | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_COPY | G_PM_NPRIMITIVE,
G_AC_THRESHOLD | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2);
gSPBgRectCopy(gfx++, bg);
-
} else {
bg->s.frameW = width * (1 << 2);
bg->s.frameH = height * (1 << 2);
bg->s.scaleW = 1 << 10;
bg->s.scaleH = 1 << 10;
bg->s.imageYorig = bg->b.imageY;
+ // The render mode used here is like TEX_EDGE modes except it doesn't blend against memcolor, it instead blends
+ // against the current blend color which is 0 here. Since this is in 1-Cycle mode, AA_EN is set, and FORCE_BL
+ // is unset, blending only occurs on partially covered edge pixels. However the image is specified in
+ // whole-pixel units so no partially covered edges arise in rendering, the odd blending formula is not used.
+ // If there were edge pixels, the alpha value sent to the blender would be the coverage value.
gDPSetOtherMode(gfx++,
tlutMode | G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,