diff --git a/.vscode/settings.json b/.vscode/settings.json index f569adb244..ef46488309 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,4 +12,7 @@ "*.inc": "c", "*.inc.c": "c", }, + "editor.rulers": [ + 120 + ], } diff --git a/Makefile b/Makefile index a164095705..635c25f953 100644 --- a/Makefile +++ b/Makefile @@ -500,6 +500,7 @@ endif $(V)$(PYTHON) -m ipl3checksum sum --cic 6105 --update $@ $(ELF): $(TEXTURE_FILES_OUT) $(ASSET_FILES_OUT) $(O_FILES) $(OVL_RELOC_FILES) $(UCODE_O_FILES) $(LDSCRIPT) $(BUILD_DIR)/undefined_syms.txt + $(call print,Linking:,,$@) $(V)$(LD) -T $(LDSCRIPT) -T $(BUILD_DIR)/undefined_syms.txt --no-check-sections --accept-unknown-input-arch --emit-relocs -Map $(MAP) -o $@ ## Order-only prerequisites diff --git a/README.md b/README.md index b6d0b91524..9b631178e1 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Note: the [F3DEX3](https://github.com/HackerN64/F3DEX3) microcode is enabled by HackerOoT features are listed in the config headers under ``include/config/``. -This project includes an example scene, available if ``INCLUDE_EXAMPLE_SCENE`` is set to ``true``. It's accessible from the file select. +This project includes an example scene, available if ``INCLUDE_EXAMPLE_SCENE`` is set to ``true``. It's accessible from the map select. This also includes an example cutscene, playable in the example scene when holding ``L`` + ``R`` and pressing ``A``. diff --git a/include/functions.h b/include/functions.h index c819fd3913..7fbf4484e9 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1086,7 +1086,7 @@ Gfx* Gfx_TwoTexScroll(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 wi Gfx* Gfx_TwoTexScrollEnvColor(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 width1, s32 height1, s32 tile2, u32 x2, u32 y2, s32 width2, s32 height2, s32 r, s32 g, s32 b, s32 a); Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a); -void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b); +void Gfx_SetupFrame(GraphicsContext* gfxCtx, s32 clearFB, u8 r, u8 g, u8 b); void func_80095974(GraphicsContext* gfxCtx); void func_80095AA0(PlayState* play, Room* room, Input* input, s32 arg3); void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode, diff --git a/include/z64light.h b/include/z64light.h index 7e11dd32c8..769501216a 100644 --- a/include/z64light.h +++ b/include/z64light.h @@ -46,7 +46,7 @@ typedef struct LightNode { #define ENV_FOGNEAR_MAX 996 #define ENV_ZFAR_MAX 12800 -typedef struct { +typedef struct LightContext { /* 0x0 */ LightNode* listHead; /* 0x4 */ u8 ambientColor[3]; /* 0x7 */ u8 fogColor[3]; diff --git a/include/z64skybox.h b/include/z64skybox.h index 73017cbb37..2e6725bac0 100644 --- a/include/z64skybox.h +++ b/include/z64skybox.h @@ -9,6 +9,7 @@ struct GameState; struct GraphicsContext; +struct LightContext; typedef enum { /* 0x00 */ SKYBOX_NONE, @@ -68,8 +69,8 @@ extern SkyboxFile gNormalSkyFiles[]; void Skybox_Init(struct GameState* state, SkyboxContext* skyboxCtx, s16 skyboxId); Mtx* Skybox_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z); -void Skybox_Draw(SkyboxContext* skyboxCtx, struct GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, - f32 z); +void Skybox_Draw(SkyboxContext* skyboxCtx, struct GraphicsContext* gfxCtx, struct LightContext* lightCtx, s16 skyboxId, + s16 blend, f32 x, f32 y, f32 z); void Skybox_Update(SkyboxContext* skyboxCtx); #endif diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c index 9c0365d2c3..93fb33c2e8 100644 --- a/src/code/z_kankyo.c +++ b/src/code/z_kankyo.c @@ -1393,7 +1393,23 @@ void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContex } void Environment_DrawSunAndMoon(PlayState* play) { - f32 alpha; + // This replace gMoonDL in gameplay_keep. TODO make this gMoonDL once asset replacement is sophisticated enough + static Gfx sMoonDL[] = { + gsSPMatrix(0x01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW), + gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON), + gsSPLoadGeometryMode(G_CULL_BACK), + gsDPSetCombineLERP(PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, 0, TEXEL0, 0, 0, 0, 0, COMBINED, 0, + 0, 0, COMBINED), + 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_2CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PIXEL | G_RM_FOG_PRIM_A | G_RM_XLU_SURF2), + gsDPLoadTextureBlock(gMoonTex, G_IM_FMT_IA, G_IM_SIZ_8b, 64, 64, 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), + gsSPVertex(gameplay_keepVtx_038F70, 4, 0), + gsSP2Triangles(0, 1, 2, 0, 1, 3, 2, 0), + gsSPEndDisplayList(), + }; + s32 alpha; f32 color; f32 y; f32 scale; @@ -1426,14 +1442,8 @@ void Environment_DrawSunAndMoon(PlayState* play) { temp = y / 80.0f; alpha = temp * 255.0f; - if (alpha < 0.0f) { - alpha = 0.0f; - } - if (alpha > 255.0f) { - alpha = 255.0f; - } - - alpha = 255.0f - alpha; + alpha = CLAMP(alpha, 0, 255); + alpha = 255 - alpha; color = temp; if (color < 0.0f) { @@ -1451,6 +1461,7 @@ void Environment_DrawSunAndMoon(PlayState* play) { Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_kankyo.c", 2364), G_MTX_LOAD); Gfx_SetupDL_54Opa(play->state.gfxCtx); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_PRIM_A, G_RM_XLU_SURF2); gSPDisplayList(POLY_OPA_DISP++, gSunDL); Matrix_Translate(play->view.eye.x - play->envCtx.sunPos.x, play->view.eye.y - play->envCtx.sunPos.y, @@ -1467,13 +1478,12 @@ void Environment_DrawSunAndMoon(PlayState* play) { alpha = temp * 255.0f; - if (alpha > 0.0f) { + if (alpha > 0) { gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_kankyo.c", 2406), G_MTX_LOAD); - Gfx_SetupDL_51Opa(play->state.gfxCtx); gDPPipeSync(POLY_OPA_DISP++); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 240, 255, 180, alpha); gDPSetEnvColor(POLY_OPA_DISP++, 80, 70, 20, alpha); - gSPDisplayList(POLY_OPA_DISP++, gMoonDL); + gSPDisplayList(POLY_OPA_DISP++, sMoonDL); } } @@ -1687,12 +1697,15 @@ void Environment_DrawLensFlare(PlayState* play, EnvironmentContext* envCtx, View Math_SmoothStepToF(&envCtx->glareAlpha, 0.0f, 0.5f, 50.0f, 0.1f); } - temp = colorIntensity / 120.0f; - temp = CLAMP_MIN(temp, 0.0f); + // The blender only uses the 5 most significant bits of alpha, ensure at least one of these bits is set + if (envCtx->glareAlpha >= 8.0f) { + temp = colorIntensity / 120.0f; + temp = CLAMP_MIN(temp, 0.0f); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, (u8)(temp * 75.0f) + 180, (u8)(temp * 155.0f) + 100, - (u8)envCtx->glareAlpha); - gDPFillRectangle(POLY_XLU_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, (u8)(temp * 75.0f) + 180, (u8)(temp * 155.0f) + 100, + (u8)envCtx->glareAlpha); + gDPFillRectangle(POLY_XLU_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); + } } else { envCtx->glareAlpha = 0.0f; } @@ -1839,30 +1852,6 @@ void Environment_ChangeLightSetting(PlayState* play, u32 lightSetting) { * An example usage of a filter is to dim the skybox in cloudy conditions. */ void Environment_DrawSkyboxFilters(PlayState* play) { - if (((play->skyboxId != SKYBOX_NONE) && (play->lightCtx.fogNear < 980)) || (play->skyboxId == SKYBOX_UNSET_1D)) { - f32 alpha; - - OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3032); - - Gfx_SetupDL_57Opa(play->state.gfxCtx); - - alpha = (1000 - play->lightCtx.fogNear) * 0.02f; - - if (play->skyboxId == SKYBOX_UNSET_1D) { - alpha = 1.0f; - } - - if (alpha > 1.0f) { - alpha = 1.0f; - } - - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, play->lightCtx.fogColor[0], play->lightCtx.fogColor[1], - play->lightCtx.fogColor[2], 255.0f * alpha); - gDPFillRectangle(POLY_OPA_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); - - CLOSE_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3043); - } - if (play->envCtx.customSkyboxFilter) { OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3048); @@ -2337,32 +2326,36 @@ void Environment_UpdateRain(PlayState* play) { } void Environment_FillScreen(GraphicsContext* gfxCtx, u8 red, u8 green, u8 blue, u8 alpha, u8 drawFlags) { - if (alpha != 0) { - OPEN_DISPS(gfxCtx, "../z_kankyo.c", 3835); + // The blender operates only with the 5 most significant bits of alpha, so we better have at least + // one bit set in that range to bother doing this + if (alpha < 8) { + return; + } - if (drawFlags & FILL_SCREEN_OPA) { - POLY_OPA_DISP = Gfx_SetupDL_57(POLY_OPA_DISP); - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, alpha); - gDPSetAlphaDither(POLY_OPA_DISP++, G_AD_DISABLE); - gDPSetColorDither(POLY_OPA_DISP++, G_CD_DISABLE); - gDPFillRectangle(POLY_OPA_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); - } + OPEN_DISPS(gfxCtx, "../z_kankyo.c", 3835); - if (drawFlags & FILL_SCREEN_XLU) { - POLY_XLU_DISP = Gfx_SetupDL_57(POLY_XLU_DISP); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, red, green, blue, alpha); + if (drawFlags & FILL_SCREEN_OPA) { + POLY_OPA_DISP = Gfx_SetupDL_57(POLY_OPA_DISP); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, alpha); + gDPSetAlphaDither(POLY_OPA_DISP++, G_AD_DISABLE); + gDPSetColorDither(POLY_OPA_DISP++, G_CD_DISABLE); + gDPFillRectangle(POLY_OPA_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); + } - if ((u32)alpha == 255) { - gDPSetRenderMode(POLY_XLU_DISP++, G_RM_OPA_SURF, G_RM_OPA_SURF2); - } + if (drawFlags & FILL_SCREEN_XLU) { + POLY_XLU_DISP = Gfx_SetupDL_57(POLY_XLU_DISP); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, red, green, blue, alpha); - gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE); - gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE); - gDPFillRectangle(POLY_XLU_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); + if ((u32)alpha == 255) { + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_OPA_SURF, G_RM_OPA_SURF2); } - CLOSE_DISPS(gfxCtx, "../z_kankyo.c", 3863); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE); + gDPFillRectangle(POLY_XLU_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1); } + + CLOSE_DISPS(gfxCtx, "../z_kankyo.c", 3863); } Color_RGB8 sSandstormPrimColors[] = { diff --git a/src/code/z_play.c b/src/code/z_play.c index ab380b43c4..984f3f1e2a 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -184,7 +184,12 @@ void func_800BC88C(PlayState* this) { } Gfx* Play_SetFog(PlayState* this, Gfx* gfx) { - return Gfx_SetFog2(gfx, this->lightCtx.fogColor[0], this->lightCtx.fogColor[1], this->lightCtx.fogColor[2], 0, + s32 fogA = 0; + if (this->skyboxId != SKYBOX_NONE && this->lightCtx.fogNear < 980) { + fogA = (255 * (1000 - this->lightCtx.fogNear) + 25) / 50; + fogA = CLAMP(fogA, 0, 255); + } + return Gfx_SetFog2(gfx, this->lightCtx.fogColor[0], this->lightCtx.fogColor[1], this->lightCtx.fogColor[2], fogA, this->lightCtx.fogNear, 1000); } @@ -1253,7 +1258,24 @@ void Play_Draw(PlayState* this) { gSPSegment(POLY_XLU_DISP++, 0x02, this->sceneSegment); gSPSegment(OVERLAY_DISP++, 0x02, this->sceneSegment); - Gfx_SetupFrame(gfxCtx, 0, 0, 0); + { + // Only clear the FB if there is no skybox or it is solid color + s32 clearFB = this->skyboxId == SKYBOX_NONE || this->skyboxId == SKYBOX_UNSET_1D || this->envCtx.skyboxDisabled; + + // For no skybox, black background + u8 clearR = 0; + u8 clearG = 0; + u8 clearB = 0; + + if (this->skyboxId == SKYBOX_UNSET_1D) { + // Solid-color "skybox" matching fog color + clearR = this->lightCtx.fogColor[0]; + clearG = this->lightCtx.fogColor[1]; + clearB = this->lightCtx.fogColor[2]; + } + // Clear the fb only if we aren't drawing a skybox, but always clear zb + Gfx_SetupFrame(gfxCtx, clearFB, clearR, clearG, clearB); + } if (!IS_DEBUG || (R_HREG_MODE != HREG_MODE_PLAY) || R_PLAY_RUN_DRAW) { POLY_OPA_DISP = Play_SetFog(this, POLY_OPA_DISP); @@ -1349,14 +1371,14 @@ void Play_Draw(PlayState* this) { } if (!IS_DEBUG || (R_HREG_MODE != HREG_MODE_PLAY) || R_PLAY_DRAW_SKYBOX) { - if (this->skyboxId && (this->skyboxId != SKYBOX_UNSET_1D) && !this->envCtx.skyboxDisabled) { + if (this->skyboxId != SKYBOX_NONE && (this->skyboxId != SKYBOX_UNSET_1D) && !this->envCtx.skyboxDisabled) { if ((this->skyboxId == SKYBOX_NORMAL_SKY) || (this->skyboxId == SKYBOX_CUTSCENE_MAP)) { 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); + Skybox_Draw(&this->skyboxCtx, gfxCtx, &this->lightCtx, this->skyboxId, this->envCtx.skyboxBlend, + this->view.eye.x, this->view.eye.y, this->view.eye.z); } 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); + Skybox_Draw(&this->skyboxCtx, gfxCtx, &this->lightCtx, this->skyboxId, 0, this->view.eye.x, + this->view.eye.y, this->view.eye.z); } } } @@ -1403,7 +1425,9 @@ void Play_Draw(PlayState* this) { Vec3f quakeOffset; quakeOffset = Camera_GetQuakeOffset(GET_ACTIVE_CAM(this)); - Skybox_Draw(&this->skyboxCtx, gfxCtx, this->skyboxId, 0, this->view.eye.x + quakeOffset.x, + // lightCtx arg is NULL here since this is responsible for prerendered backgrounds, in this case we + // don't want them to be affected by fog + Skybox_Draw(&this->skyboxCtx, gfxCtx, NULL, this->skyboxId, 0, this->view.eye.x + quakeOffset.x, this->view.eye.y + quakeOffset.y, this->view.eye.z + quakeOffset.z); } } diff --git a/src/code/z_prenmi.c b/src/code/z_prenmi.c index 29ea097d68..0e0d2ed2e7 100644 --- a/src/code/z_prenmi.c +++ b/src/code/z_prenmi.c @@ -33,7 +33,7 @@ void PreNMI_Draw(PreNMIState* this) { OPEN_DISPS(gfxCtx, "../z_prenmi.c", 96); gSPSegment(POLY_OPA_DISP++, 0x00, NULL); - Gfx_SetupFrame(gfxCtx, 0, 0, 0); + Gfx_SetupFrame(gfxCtx, true, 0, 0, 0); Gfx_SetupDL_36Opa(gfxCtx); gDPSetFillColor(POLY_OPA_DISP++, (GPACK_RGBA5551(255, 255, 255, 1) << 16) | GPACK_RGBA5551(255, 255, 255, 1)); gDPFillRectangle(POLY_OPA_DISP++, 0, this->timer + 100, SCREEN_WIDTH - 1, this->timer + 100); diff --git a/src/code/z_rcp.c b/src/code/z_rcp.c index 00834cd97c..4b46eb12ec 100644 --- a/src/code/z_rcp.c +++ b/src/code/z_rcp.c @@ -1465,7 +1465,7 @@ Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a) { * The whole screen is filled with the color supplied as arguments. * Letterbox is also applied here, and will share the color of the screen base. */ -void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b) { +void Gfx_SetupFrame(GraphicsContext* gfxCtx, s32 clearFB, u8 r, u8 g, u8 b) { OPEN_DISPS(gfxCtx, "../z_rcp.c", 2386); // Set up the RDP render state for rectangles in FILL mode @@ -1540,27 +1540,25 @@ void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b) { // Set the whole z buffer to maximum depth // Don't bother with pixels that are being covered by the letterbox gDPSetColorImage(POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, gScreenWidth, gZBuffer); - gDPSetCycleType(POLY_OPA_DISP++, G_CYC_FILL); gDPSetRenderMode(POLY_OPA_DISP++, G_RM_NOOP, G_RM_NOOP2); gDPSetFillColor(POLY_OPA_DISP++, (GPACK_ZDZ(G_MAXFBZ, 0) << 16) | GPACK_ZDZ(G_MAXFBZ, 0)); gDPFillRectangle(POLY_OPA_DISP++, 0, letterboxSize, gScreenWidth - 1, gScreenHeight - letterboxSize - 1); gDPPipeSync(POLY_OPA_DISP++); - // Fill the whole screen with the base color + // Fill the whole screen with the base color, only done when there is no skybox or if it is a solid color. // Don't bother with pixels that are being covered by the letterbox gDPSetColorImage(POLY_OPA_DISP++, G_IM_FMT_RGBA, G_IM_SIZ_16b, gScreenWidth, gfxCtx->curFrameBuffer); - gDPSetCycleType(POLY_OPA_DISP++, G_CYC_FILL); - gDPSetRenderMode(POLY_OPA_DISP++, G_RM_NOOP, G_RM_NOOP2); - gDPSetFillColor(POLY_OPA_DISP++, (GPACK_RGBA5551(r, g, b, 1) << 16) | GPACK_RGBA5551(r, g, b, 1)); - gDPFillRectangle(POLY_OPA_DISP++, 0, letterboxSize, gScreenWidth - 1, gScreenHeight - letterboxSize - 1); - gDPPipeSync(POLY_OPA_DISP++); + if (clearFB) { + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_NOOP, G_RM_NOOP2); + gDPSetFillColor(POLY_OPA_DISP++, (GPACK_RGBA5551(r, g, b, 1) << 16) | GPACK_RGBA5551(r, g, b, 1)); + gDPFillRectangle(POLY_OPA_DISP++, 0, letterboxSize, gScreenWidth - 1, gScreenHeight - letterboxSize - 1); + gDPPipeSync(POLY_OPA_DISP++); + } - // Draw the letterbox if applicable (uses the same color as the screen base) + // Draw the letterbox if applicable (always black) if (letterboxSize > 0) { - gDPPipeSync(OVERLAY_DISP++); - gDPSetCycleType(OVERLAY_DISP++, G_CYC_FILL); gDPSetRenderMode(OVERLAY_DISP++, G_RM_NOOP, G_RM_NOOP2); - gDPSetFillColor(OVERLAY_DISP++, (GPACK_RGBA5551(r, g, b, 1) << 16) | GPACK_RGBA5551(r, g, b, 1)); + gDPSetFillColor(OVERLAY_DISP++, (GPACK_RGBA5551(0, 0, 0, 1) << 16) | GPACK_RGBA5551(0, 0, 0, 1)); gDPFillRectangle(OVERLAY_DISP++, 0, 0, gScreenWidth - 1, letterboxSize - 1); gDPFillRectangle(OVERLAY_DISP++, 0, gScreenHeight - letterboxSize, gScreenWidth - 1, gScreenHeight - 1); gDPPipeSync(OVERLAY_DISP++); diff --git a/src/code/z_sample.c b/src/code/z_sample.c index d2469cf404..0f31fc299a 100644 --- a/src/code/z_sample.c +++ b/src/code/z_sample.c @@ -16,7 +16,7 @@ void Sample_Draw(SampleState* this) { gSPSegment(POLY_OPA_DISP++, 0x00, NULL); gSPSegment(POLY_OPA_DISP++, 0x01, this->staticSegment); - Gfx_SetupFrame(gfxCtx, 0, 0, 0); + Gfx_SetupFrame(gfxCtx, true, 0, 0, 0); view->flags = VIEW_VIEWING | VIEW_VIEWPORT | VIEW_PROJECTION_PERSPECTIVE; View_Apply(view, VIEW_ALL); diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c index caebcec0b8..9dfe2bbc58 100644 --- a/src/code/z_vr_box.c +++ b/src/code/z_vr_box.c @@ -1042,17 +1042,10 @@ void Skybox_Init(GameState* state, SkyboxContext* skyboxCtx, s16 skyboxId) { skyboxCtx->dListBuf = GAME_STATE_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 = GAME_STATE_ALLOC(state, 6 * 32 * sizeof(Vtx), "../z_vr_box.c", 1648); - ASSERT(skyboxCtx->roomVtx != NULL, "vr_box->roomVtx != NULL", "../z_vr_box.c", 1649); - - Skybox_Calculate128(skyboxCtx, 6); // compute all 6 faces - } else { - skyboxCtx->roomVtx = GAME_STATE_ALLOC(state, 5 * 32 * sizeof(Vtx), "../z_vr_box.c", 1653); - ASSERT(skyboxCtx->roomVtx != NULL, "vr_box->roomVtx != NULL", "../z_vr_box.c", 1654); - - Skybox_Calculate128(skyboxCtx, 5); // compute 5 faces, excludes the bottom face - } + skyboxCtx->roomVtx = GAME_STATE_ALLOC(state, 6 * 32 * sizeof(Vtx), "../z_vr_box.c", 1648); + ASSERT(skyboxCtx->roomVtx != NULL, "vr_box->roomVtx != NULL", "../z_vr_box.c", 1649); + // compute all 6 faces, may be drawn black or with a texture (see Skybox_Draw) + Skybox_Calculate128(skyboxCtx, 6); } PRINTF(VT_RST); } diff --git a/src/code/z_vr_box_draw.c b/src/code/z_vr_box_draw.c index 45e3237deb..8a3cddef73 100644 --- a/src/code/z_vr_box_draw.c +++ b/src/code/z_vr_box_draw.c @@ -11,10 +11,12 @@ Mtx* Skybox_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z) { return MATRIX_TO_MTX(sSkyboxDrawMatrix, "../z_vr_box_draw.c", 42); } -void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z) { +void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, LightContext* lightCtx, s16 skyboxId, s16 blend, + f32 x, f32 y, f32 z) { OPEN_DISPS(gfxCtx, "../z_vr_box_draw.c", 52); Gfx_SetupDL_40Opa(gfxCtx); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_PRIM_A, G_RM_OPA_SURF2); gSPSegment(POLY_OPA_DISP++, 0x7, skyboxCtx->staticSegments[0]); gSPSegment(POLY_OPA_DISP++, 0x8, skyboxCtx->staticSegments[1]); @@ -65,10 +67,8 @@ void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId 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->drawType != SKYBOX_DRAW_256_3FACE) { + gDPPipeSync(POLY_OPA_DISP++); gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palettes[3]); gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[6]); // -x face upper gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[7]); // -x face lower @@ -85,10 +85,12 @@ void Skybox_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId 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) { - // Skip the bottom face in the cutscene map - gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[10]); // -y face + if (skyboxId != SKYBOX_CUTSCENE_MAP) { + // Render the bottom face black except in the cutscene map + gDPPipeSync(POLY_OPA_DISP++); + gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED); } + gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[10]); // -y face } gDPPipeSync(POLY_OPA_DISP++); diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index f23efde5d6..4a8450fd00 100644 --- a/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -66,6 +66,9 @@ void FileSelect_InitModeUpdate(GameState* thisx) { } void FileSelect_InitModeDraw(GameState* thisx) { + FileSelectState* this = (FileSelectState*)thisx; + + Gfx_SetupFrame(this->state.gfxCtx, true, 0, 0, 0); } /** @@ -1130,7 +1133,9 @@ void FileSelect_ConfigModeDraw(GameState* thisx) { eyeZ = 1000.0f * Math_SinS(ZREG(11)) + 1000.0f * Math_CosS(ZREG(11)); FileSelect_SetView(this, eyeX, eyeY, eyeZ); - Skybox_Draw(&this->skyboxCtx, this->state.gfxCtx, 1, this->envCtx.skyboxBlend, eyeX, eyeY, eyeZ); + Gfx_SetupFrame(this->state.gfxCtx, false, 0, 0, 0); + Skybox_Draw(&this->skyboxCtx, this->state.gfxCtx, NULL, SKYBOX_NORMAL_SKY, this->envCtx.skyboxBlend, eyeX, eyeY, + eyeZ); gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_NONE); ZREG(11) += ZREG(10); Environment_UpdateSkybox(SKYBOX_NORMAL_SKY, &this->envCtx, &this->skyboxCtx); @@ -1543,7 +1548,9 @@ void FileSelect_SelectModeDraw(GameState* thisx) { eyeZ = 1000.0f * Math_SinS(ZREG(11)) + 1000.0f * Math_CosS(ZREG(11)); FileSelect_SetView(this, eyeX, eyeY, eyeZ); - Skybox_Draw(&this->skyboxCtx, this->state.gfxCtx, 1, this->envCtx.skyboxBlend, eyeX, eyeY, eyeZ); + Gfx_SetupFrame(this->state.gfxCtx, false, 0, 0, 0); + Skybox_Draw(&this->skyboxCtx, this->state.gfxCtx, NULL, SKYBOX_NORMAL_SKY, this->envCtx.skyboxBlend, eyeX, eyeY, + eyeZ); gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_NONE); ZREG(11) += ZREG(10); Environment_UpdateSkybox(SKYBOX_NORMAL_SKY, &this->envCtx, &this->skyboxCtx); @@ -1609,8 +1616,6 @@ void FileSelect_Main(GameState* thisx) { gSPSegment(POLY_OPA_DISP++, 0x01, this->staticSegment); gSPSegment(POLY_OPA_DISP++, 0x02, this->parameterSegment); - Gfx_SetupFrame(this->state.gfxCtx, 0, 0, 0); - this->stickAdjX = input->rel.stick_x; this->stickAdjY = input->rel.stick_y; diff --git a/src/overlays/gamestates/ovl_opening/z_opening.c b/src/overlays/gamestates/ovl_opening/z_opening.c index c6e24e310a..3ba1db3718 100644 --- a/src/overlays/gamestates/ovl_opening/z_opening.c +++ b/src/overlays/gamestates/ovl_opening/z_opening.c @@ -68,7 +68,7 @@ void func_80803C5C(TitleSetupState* this) { void TitleSetup_Main(GameState* thisx) { TitleSetupState* this = (TitleSetupState*)thisx; - Gfx_SetupFrame(this->state.gfxCtx, 0, 0, 0); + Gfx_SetupFrame(this->state.gfxCtx, true, 0, 0, 0); TitleSetup_SetupTitleScreen(this); func_80803C5C(this); } diff --git a/src/overlays/gamestates/ovl_select/z_select.c b/src/overlays/gamestates/ovl_select/z_select.c index 70b3a290a9..ac7dafc626 100644 --- a/src/overlays/gamestates/ovl_select/z_select.c +++ b/src/overlays/gamestates/ovl_select/z_select.c @@ -89,7 +89,7 @@ void MapSelect_Draw(MapSelectState* this) { OPEN_DISPS(gfxCtx, __FILE__, __LINE__); gSPSegment(POLY_OPA_DISP++, 0x00, NULL); - Gfx_SetupFrame(gfxCtx, 0, 0, 0); + Gfx_SetupFrame(gfxCtx, true, 0, 0, 0); SET_FULLSCREEN_VIEWPORT(&this->view); View_Apply(&this->view, VIEW_ALL); @@ -334,7 +334,7 @@ void MapSelect_DrawMenu(MapSelectState* this) { OPEN_DISPS(gfxCtx, __FILE__, __LINE__); gSPSegment(POLY_OPA_DISP++, 0x00, NULL); - Gfx_SetupFrame(gfxCtx, 0, 0, 0); + Gfx_SetupFrame(gfxCtx, true, 0, 0, 0); SET_FULLSCREEN_VIEWPORT(&this->view); View_Apply(&this->view, VIEW_ALL); Gfx_SetupDL_28Opa(gfxCtx); @@ -367,7 +367,7 @@ void MapSelect_DrawLoadingScreen(MapSelectState* this) { OPEN_DISPS(gfxCtx, __FILE__, __LINE__); gSPSegment(POLY_OPA_DISP++, 0x00, NULL); - Gfx_SetupFrame(gfxCtx, 0, 0, 0); + Gfx_SetupFrame(gfxCtx, true, 0, 0, 0); SET_FULLSCREEN_VIEWPORT(&this->view); View_Apply(&this->view, VIEW_ALL); Gfx_SetupDL_28Opa(gfxCtx); diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c index 628677079f..7d7fd5b54b 100644 --- a/src/overlays/gamestates/ovl_title/z_title.c +++ b/src/overlays/gamestates/ovl_title/z_title.c @@ -154,7 +154,7 @@ void ConsoleLogo_Main(GameState* thisx) { gSPSegment(POLY_OPA_DISP++, 0, NULL); gSPSegment(POLY_OPA_DISP++, 1, this->staticSegment); - Gfx_SetupFrame(this->state.gfxCtx, 0, 0, 0); + Gfx_SetupFrame(this->state.gfxCtx, true, 0, 0, 0); ConsoleLogo_Calc(this); ConsoleLogo_Draw(this);