diff --git a/src/core2/fx/weather_snow.c b/src/core2/fx/weather_snow.c index 7148b5046..894ecfe53 100644 --- a/src/core2/fx/weather_snow.c +++ b/src/core2/fx/weather_snow.c @@ -29,22 +29,22 @@ Gfx D_80369290[] = gsSPEndDisplayList(), }; -Gfx D_803692B0[] = +// [port] The flake model reaches these render modes through segment 3 at fixed byte +// offsets; one 2D array guarantees the contiguity three separate globals did not. +Gfx D_803692B0[][2] = { - gsDPSetRenderMode(Z_CMP | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | G_RM_PASS, Z_CMP | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)), - gsSPEndDisplayList(), -}; - -Gfx D_803692C0[] = -{ - gsDPSetRenderMode(AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | G_RM_PASS, AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)), - gsSPEndDisplayList(), -}; - -Gfx D_803692D0[] = -{ - gsDPSetRenderMode(Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_OPA | FORCE_BL | G_RM_PASS, Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_OPA | FORCE_BL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)), - gsSPEndDisplayList(), + { + gsDPSetRenderMode(Z_CMP | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | G_RM_PASS, Z_CMP | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)), + gsSPEndDisplayList(), + }, + { + gsDPSetRenderMode(AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | G_RM_PASS, AA_EN | Z_CMP | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | ALPHA_CVG_SEL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)), + gsSPEndDisplayList(), + }, + { + gsDPSetRenderMode(Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_OPA | FORCE_BL | G_RM_PASS, Z_CMP | IM_RD | CVG_DST_FULL | ZMODE_OPA | FORCE_BL | GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)), + gsSPEndDisplayList(), + }, }; /* .bss */ @@ -208,9 +208,13 @@ void func_802F962C(Gfx **gfx, Mtx **mtx, Vtx **vtx) { func_80349AD0(); gSPSegment((*gfx)++, 1, osVirtualToPhysical(temp_s3 + 1)); gSPSegment((*gfx)++, 0x02, osVirtualToPhysical((void*)((uintptr_t)D_80369288 + D_80369288->texture_list_offset + sizeof(BKTextureList) + sizeof(BKTextureInfo)))); - gSPSetGeometryMode((*gfx)++, G_ZBUFFER); + // [port] Vanilla only sets G_ZBUFFER here, inheriting the rest of the RSP/RDP state + // from whatever drew last. GraphicsPatches.cpp substitutes a self-contained preamble. + if (EventSystem_Should(VB_SNOW_RENDER_STATE, true, gfx)) { + gSPSetGeometryMode((*gfx)++, G_ZBUFFER); + } gSPDisplayList((*gfx)++, D_80369290); - gSPSegment((*gfx)++, 0x03, osVirtualToPhysical(&D_803692B0)); + gSPSegment((*gfx)++, 0x03, osVirtualToPhysical(D_803692B0)); D_80381094 = (Struct_core2_72060_0 *)((uintptr_t)D_80369288 + D_80369288->geo_list_offset); diff --git a/src/core2/model/modelRender.c b/src/core2/model/modelRender.c index 8618a4641..d701fb000 100644 --- a/src/core2/model/modelRender.c +++ b/src/core2/model/modelRender.c @@ -711,6 +711,7 @@ void modelRender_geoCmd_Unk0(Gfx **gfx, Mtx **mtx, struct bk_geo_cmd_s *arg2){ f32 sp30[3]; if(cmd->unk8){ + FrameInterpolation_RecordOpenChildHash3("billboard", (uintptr_t)cmd, 0, 0); mlMtx_apply_vec3f(sp30, cmd->unkC); mlMtx_push_translation(sp30[0], sp30[1], sp30[2]); mlMtxRotYaw(modelRenderCameraRotation[1]); @@ -724,6 +725,7 @@ void modelRender_geoCmd_Unk0(Gfx **gfx, Mtx **mtx, struct bk_geo_cmd_s *arg2){ modelRender_executeGeoCmds(gfx, mtx, (BKGeoCmd*)((u8*)cmd + cmd->unk8)); mlMtxPop(); gSPPopMatrix((*gfx)++, G_MTX_MODELVIEW); + FrameInterpolation_RecordCloseChild(); } } @@ -1157,6 +1159,7 @@ BKModelBin *modelRender_draw(Gfx **gfx, Mtx **mtx, f32 position[3], f32 rotation tmp_f0 = D_80383708 - 500.0f; if(tmp_f0 < camera_focus_distance){ alpha = (s32)((1.0f - (camera_focus_distance - tmp_f0)/500.0f)*255.0f); + EventSystem_Should(VB_MODEL_DRAWDIST_FADE_ALPHA, true, &alpha); if(modelRenderColorMode == COLOR_MODE_DYNAMIC_PRIM_AND_ENV){ modelRenderDynColors.prim[3] = (modelRenderDynColors.prim[3] * alpha) / 0xff; } diff --git a/src/core2/sprite/screenoverlay.c b/src/core2/sprite/screenoverlay.c index 132012a8f..55a166e8e 100644 --- a/src/core2/sprite/screenoverlay.c +++ b/src/core2/sprite/screenoverlay.c @@ -206,7 +206,9 @@ void codeAEDA0_drawSprite( Gfx **gfx ) D_80370338[0] = 1; } - if(D_80383634 == 0x0E){ + // [port] Vanilla only disarms G_AC_THRESHOLD when the draw-mode global still reads + // 0x0E. SpritePatches.cpp forces it so a mode change cannot leak it into later draws. + if (EventSystem_Should(VB_SPRITE_RESTORE_ALPHA_COMPARE, D_80383634 == 0x0E, gfx)) { gDPSetAlphaCompare((*gfx)++, G_AC_NONE); } } diff --git a/src/port/Enhancements/Events/Hooks/Events.h b/src/port/Enhancements/Events/Hooks/Events.h index bb2970576..8c82af2b3 100644 --- a/src/port/Enhancements/Events/Hooks/Events.h +++ b/src/port/Enhancements/Events/Hooks/Events.h @@ -69,6 +69,9 @@ typedef enum VBehaviorID { VB_CUBE_PROP_SORT, VB_GCLIGHTS_RECOLOR, VB_SNOW_CAMERA_ROTATION, + VB_SNOW_RENDER_STATE, + VB_MODEL_DRAWDIST_FADE_ALPHA, + VB_SPRITE_RESTORE_ALPHA_COMPARE, VB_DRAWDIST_BOX_CULL, VB_PICTUREBOX_TARGET_FB, diff --git a/src/port/Patches/GraphicsPatches.cpp b/src/port/Patches/GraphicsPatches.cpp index 01cb14cae..ecfc17109 100644 --- a/src/port/Patches/GraphicsPatches.cpp +++ b/src/port/Patches/GraphicsPatches.cpp @@ -267,3 +267,35 @@ static void RegisterStaleTileFix_Init() { } static RegisterShipInitFunc staleTileFixInit(RegisterStaleTileFix_Init, { CVAR_FP_LOBBY_DOOR_TILE }); + +// ============================ +// INHERITED RENDER STATE +// ============================ + +static void ApplySnowRenderState(Gfx** gfx) { + gSPClearGeometryMode((*gfx)++, G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | + G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH); + gSPSetGeometryMode((*gfx)++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); + gDPSetAlphaCompare((*gfx)++, G_AC_NONE); + gDPSetPrimColor((*gfx)++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF); + gDPSetEnvColor((*gfx)++, 0xFF, 0xFF, 0xFF, 0xFF); + gDPSetBlendColor((*gfx)++, 0x00, 0x00, 0x00, 0x80); +} + +static void RegisterSnowRenderState_Init() { + COND_VB_SHOULD(VB_SNOW_RENDER_STATE, EVENT_PRIORITY_NORMAL, true, { + ApplySnowRenderState(va_arg(args, Gfx**)); + *should = false; + }); +} + +static RegisterShipInitFunc sSnowRenderStateInit(RegisterSnowRenderState_Init); + +static void RegisterModelDrawDistFadeAlpha_Init() { + COND_VB_SHOULD(VB_MODEL_DRAWDIST_FADE_ALPHA, EVENT_PRIORITY_NORMAL, true, { + s32* alpha = va_arg(args, s32*); + *alpha = std::clamp(*alpha, 0, 0xFF); + }); +} + +static RegisterShipInitFunc sModelDrawDistFadeAlphaInit(RegisterModelDrawDistFadeAlpha_Init); diff --git a/src/port/Patches/SpritePatches.cpp b/src/port/Patches/SpritePatches.cpp index 9f5df2199..5f225d5d2 100644 --- a/src/port/Patches/SpritePatches.cpp +++ b/src/port/Patches/SpritePatches.cpp @@ -4,7 +4,9 @@ #include +#include "port/Enhancements/Events/Hooks/Events.h" #include "port/Patches/Patches.h" +#include "port/ShipInit.hpp" extern "C" { @@ -222,3 +224,9 @@ void port_pauseBannerFree(void) { } } // extern "C" + +static void RegisterSpriteRestoreAlphaCompare_Init() { + COND_VB_SHOULD(VB_SPRITE_RESTORE_ALPHA_COMPARE, EVENT_PRIORITY_NORMAL, true, { *should = true; }); +} + +static RegisterShipInitFunc sSpriteRestoreAlphaCompareInit(RegisterSpriteRestoreAlphaCompare_Init);