Framebuffer filter docs (#1528)

* Framebuffer filter docs

* PR

* Format

* Leading 0s
This commit is contained in:
Derek Hensley 2024-01-20 16:04:28 -08:00 committed by GitHub
parent 665353f344
commit 9c10ee1d28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 305 additions and 183 deletions

View File

@ -1432,7 +1432,7 @@ extern void (*sKaleidoScopeUpdateFunc)(PlayState* play);
extern void (*sKaleidoScopeDrawFunc)(PlayState* play); extern void (*sKaleidoScopeDrawFunc)(PlayState* play);
extern s32 gTransitionTileState; extern s32 gTransitionTileState;
extern Color_RGBA8_u32 gVisMonoColor; extern Color_RGBA8_u32 gPlayVisMonoColor;
extern GfxMasterList* gGfxMasterDL; extern GfxMasterList* gGfxMasterDL;

87
include/z64vis.h Normal file
View File

@ -0,0 +1,87 @@
#ifndef Z64_VIS_H
#define Z64_VIS_H
#include "ultra64.h"
#include "color.h"
typedef enum FramebufferFilterType {
/* 0 */ FB_FILTER_NONE,
/* 1 */ FB_FILTER_CVG_RGB,
/* 2 */ FB_FILTER_CVG_RGB_UNIFORM,
/* 3 */ FB_FILTER_CVG_ONLY,
/* 4 */ FB_FILTER_CVG_RGB_FOG, // Not recommended, easily overflows blender
/* 5 */ FB_FILTER_ZBUF_IA,
/* 6 */ FB_FILTER_ZBUF_RGBA,
/* 7 */ FB_FILTER_MONO
} FramebufferFilterType;
typedef enum VisScissorType {
/* 0 */ VIS_NO_SETSCISSOR,
/* 1 */ VIS_SETSCISSOR
} VisScissorType;
typedef struct Vis {
/* 0x0 */ u32 type;
/* 0x4 */ u32 scissorType;
/* 0x8 */ Color_RGBA8_u32 primColor;
/* 0xC */ Color_RGBA8_u32 envColor;
} Vis; // size = 0x10
/* Cvg: Coverage */
#define FB_FILTER_TO_CVG_TYPE(filter) (filter)
typedef enum VisCvgType {
/* 0 */ VIS_CVG_TYPE_NONE = FB_FILTER_TO_CVG_TYPE(FB_FILTER_NONE),
/* 1 */ VIS_CVG_TYPE_CVG_RGB = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB),
/* 2 */ VIS_CVG_TYPE_CVG_RGB_UNIFORM = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB_UNIFORM),
/* 3 */ VIS_CVG_TYPE_CVG_ONLY = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_ONLY),
/* 4 */ VIS_CVG_TYPE_CVG_RGB_FOG = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB_FOG)
} VisCvgType;
typedef struct VisCvg {
/* 0x0 */ Vis vis;
} VisCvg; // size = 0x10
void VisCvg_Init(VisCvg* this);
void VisCvg_Destroy(VisCvg* this);
void VisCvg_Draw(VisCvg* this, Gfx** gfxP);
/* Mono: Desaturation */
// Only one type
typedef struct VisMono {
/* 0x00 */ Vis vis;
/* 0x10 */ u16* tlut;
/* 0x14 */ Gfx* dList;
} VisMono; // size = 0x18
void VisMono_Init(VisMono* this);
void VisMono_Destroy(VisMono* this);
void VisMono_Draw(VisMono* this, Gfx** gfxP);
/* ZBuf: Z-Buffer */
#define FB_FILTER_TO_ZBUF_TYPE(filter) ((filter) - FB_FILTER_ZBUF_IA)
typedef enum VisZBufType {
/* 0 */ VIS_ZBUF_TYPE_IA = FB_FILTER_TO_ZBUF_TYPE(FB_FILTER_ZBUF_IA),
/* 1 */ VIS_ZBUF_TYPE_RGBA = FB_FILTER_TO_ZBUF_TYPE(FB_FILTER_ZBUF_RGBA)
} VisZBufType;
typedef struct VisZBuf {
/* 0x0 */ Vis vis;
} VisZBuf; // size = 0x10
void VisZBuf_Init(VisZBuf* this);
void VisZBuf_Destroy(VisZBuf* this);
void VisZBuf_Draw(VisZBuf* this, Gfx** gfxP, void* zbuffer);
#endif

View File

@ -1,18 +0,0 @@
#ifndef Z64_VISCVG_H
#define Z64_VISCVG_H
#include "ultra64.h"
#include "color.h"
typedef struct VisCvg {
/* 0x0 */ u32 type;
/* 0x4 */ u32 setScissor;
/* 0x8 */ Color_RGBA8_u32 color;
/* 0xC */ Color_RGBA8 envColor;
} VisCvg; // size = 0x10
void VisCvg_Init(VisCvg* this);
void VisCvg_Destroy(VisCvg* this);
void VisCvg_Draw(VisCvg* this, Gfx** gfxp);
#endif

View File

@ -1,20 +0,0 @@
#ifndef Z64_VISMONO_H
#define Z64_VISMONO_H
#include "ultra64.h"
#include "color.h"
typedef struct VisMono {
/* 0x00 */ u32 unk_00;
/* 0x04 */ u32 setScissor;
/* 0x08 */ Color_RGBA8_u32 primColor;
/* 0x0C */ Color_RGBA8_u32 envColor;
/* 0x10 */ u16* tlut;
/* 0x14 */ Gfx* dList;
} VisMono; // size = 0x18
void VisMono_Init(VisMono* this);
void VisMono_Destroy(VisMono* this);
void VisMono_Draw(VisMono* this, Gfx** gfxp);
#endif

View File

@ -1,18 +0,0 @@
#ifndef Z64_VISZBUF_H
#define Z64_VISZBUF_H
#include "ultra64.h"
#include "color.h"
typedef struct VisZbuf {
/* 0x0 */ u32 useRgba;
/* 0x4 */ u32 setScissor;
/* 0x8 */ Color_RGBA8_u32 primColor;
/* 0xC */ Color_RGBA8_u32 envColor;
} VisZbuf; // size = 0x10
void VisZbuf_Init(VisZbuf* this);
void VisZbuf_Destroy(VisZbuf* this);
void VisZbuf_Draw(VisZbuf* this, Gfx** gfxP, void* zbuffer);
#endif

View File

@ -7,9 +7,7 @@
#include "z64rumble.h" #include "z64rumble.h"
#include "z64speed_meter.h" #include "z64speed_meter.h"
#include "z64vimode.h" #include "z64vimode.h"
#include "z64viscvg.h" #include "z64vis.h"
#include "z64vismono.h"
#include "z64viszbuf.h"
#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h" #include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
#include "debug.h" #include "debug.h"
@ -20,7 +18,7 @@ f32 gFramerateDivisorThird = 1.0f / 3.0f;
SpeedMeter sGameSpeedMeter; SpeedMeter sGameSpeedMeter;
VisCvg sGameVisCvg; VisCvg sGameVisCvg;
VisZbuf sGameVisZbuf; VisZBuf sGameVisZBuf;
VisMono sGameVisMono; VisMono sGameVisMono;
ViMode sGameViMode; ViMode sGameViMode;
@ -40,34 +38,37 @@ void GameState_SetFramerateDivisor(GameState* gameState, s32 divisor) {
void GameState_SetFBFilter(Gfx** gfxP, void* zbuffer) { void GameState_SetFBFilter(Gfx** gfxP, void* zbuffer) {
Gfx* gfx = *gfxP; Gfx* gfx = *gfxP;
if ((R_FB_FILTER_TYPE > 0) && (R_FB_FILTER_TYPE < 5)) { if ((R_FB_FILTER_TYPE >= FB_FILTER_CVG_RGB) && (R_FB_FILTER_TYPE <= FB_FILTER_CVG_RGB_FOG)) {
sGameVisCvg.type = R_FB_FILTER_TYPE; // Visualize coverage
sGameVisCvg.color.r = R_FB_FILTER_PRIM_COLOR(0); sGameVisCvg.vis.type = FB_FILTER_TO_CVG_TYPE(R_FB_FILTER_TYPE);
sGameVisCvg.color.g = R_FB_FILTER_PRIM_COLOR(1); sGameVisCvg.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
sGameVisCvg.color.b = R_FB_FILTER_PRIM_COLOR(2); sGameVisCvg.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
sGameVisCvg.color.a = R_FB_FILTER_A; sGameVisCvg.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
sGameVisCvg.vis.primColor.a = R_FB_FILTER_A;
VisCvg_Draw(&sGameVisCvg, &gfx); VisCvg_Draw(&sGameVisCvg, &gfx);
} else if ((R_FB_FILTER_TYPE == 5) || (R_FB_FILTER_TYPE == 6)) { } else if ((R_FB_FILTER_TYPE == FB_FILTER_ZBUF_IA) || (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA)) {
sGameVisZbuf.useRgba = (R_FB_FILTER_TYPE == 6); // Visualize z-buffer
sGameVisZbuf.primColor.r = R_FB_FILTER_PRIM_COLOR(0); sGameVisZBuf.vis.type = (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA);
sGameVisZbuf.primColor.g = R_FB_FILTER_PRIM_COLOR(1); sGameVisZBuf.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
sGameVisZbuf.primColor.b = R_FB_FILTER_PRIM_COLOR(2); sGameVisZBuf.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
sGameVisZbuf.primColor.a = R_FB_FILTER_A; sGameVisZBuf.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
sGameVisZbuf.envColor.r = R_FB_FILTER_ENV_COLOR(0); sGameVisZBuf.vis.primColor.a = R_FB_FILTER_A;
sGameVisZbuf.envColor.g = R_FB_FILTER_ENV_COLOR(1); sGameVisZBuf.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0);
sGameVisZbuf.envColor.b = R_FB_FILTER_ENV_COLOR(2); sGameVisZBuf.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1);
sGameVisZbuf.envColor.a = R_FB_FILTER_A; sGameVisZBuf.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2);
VisZbuf_Draw(&sGameVisZbuf, &gfx, zbuffer); sGameVisZBuf.vis.envColor.a = R_FB_FILTER_A;
} else if (R_FB_FILTER_TYPE == 7) { VisZBuf_Draw(&sGameVisZBuf, &gfx, zbuffer);
sGameVisMono.unk_00 = 0; } else if (R_FB_FILTER_TYPE == FB_FILTER_MONO) {
sGameVisMono.primColor.r = R_FB_FILTER_PRIM_COLOR(0); // Monochrome filter
sGameVisMono.primColor.g = R_FB_FILTER_PRIM_COLOR(1); sGameVisMono.vis.type = 0;
sGameVisMono.primColor.b = R_FB_FILTER_PRIM_COLOR(2); sGameVisMono.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
sGameVisMono.primColor.a = R_FB_FILTER_A; sGameVisMono.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
sGameVisMono.envColor.r = R_FB_FILTER_ENV_COLOR(0); sGameVisMono.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
sGameVisMono.envColor.g = R_FB_FILTER_ENV_COLOR(1); sGameVisMono.vis.primColor.a = R_FB_FILTER_A;
sGameVisMono.envColor.b = R_FB_FILTER_ENV_COLOR(2); sGameVisMono.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0);
sGameVisMono.envColor.a = R_FB_FILTER_A; sGameVisMono.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1);
sGameVisMono.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2);
sGameVisMono.vis.envColor.a = R_FB_FILTER_A;
VisMono_Draw(&sGameVisMono, &gfx); VisMono_Draw(&sGameVisMono, &gfx);
} }
@ -222,7 +223,7 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
init(gameState); init(gameState);
VisCvg_Init(&sGameVisCvg); VisCvg_Init(&sGameVisCvg);
VisZbuf_Init(&sGameVisZbuf); VisZBuf_Init(&sGameVisZBuf);
VisMono_Init(&sGameVisMono); VisMono_Init(&sGameVisMono);
ViMode_Init(&sGameViMode); ViMode_Init(&sGameViMode);
SpeedMeter_Init(&sGameSpeedMeter); SpeedMeter_Init(&sGameSpeedMeter);
@ -243,7 +244,7 @@ void GameState_Destroy(GameState* gameState) {
Rumble_Destroy(); Rumble_Destroy();
SpeedMeter_Destroy(&sGameSpeedMeter); SpeedMeter_Destroy(&sGameSpeedMeter);
VisCvg_Destroy(&sGameVisCvg); VisCvg_Destroy(&sGameVisCvg);
VisZbuf_Destroy(&sGameVisZbuf); VisZBuf_Destroy(&sGameVisZBuf);
VisMono_Destroy(&sGameVisMono); VisMono_Destroy(&sGameVisMono);
ViMode_Destroy(&sGameViMode); ViMode_Destroy(&sGameViMode);
THA_Destroy(&gameState->tha); THA_Destroy(&gameState->tha);

View File

@ -219,17 +219,17 @@ void CutsceneCmd_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdMisc* cmd) {
break; break;
case CS_MISC_VISMONO_BLACK_AND_WHITE: case CS_MISC_VISMONO_BLACK_AND_WHITE:
gVisMonoColor.r = 255; gPlayVisMonoColor.r = 255;
gVisMonoColor.g = 255; gPlayVisMonoColor.g = 255;
gVisMonoColor.b = 255; gPlayVisMonoColor.b = 255;
gVisMonoColor.a = 255 * lerp; gPlayVisMonoColor.a = 255 * lerp;
break; break;
case CS_MISC_VISMONO_SEPIA: case CS_MISC_VISMONO_SEPIA:
gVisMonoColor.r = 255; gPlayVisMonoColor.r = 255;
gVisMonoColor.g = 180; gPlayVisMonoColor.g = 180;
gVisMonoColor.b = 100; gPlayVisMonoColor.b = 100;
gVisMonoColor.a = 255 * lerp; gPlayVisMonoColor.a = 255 * lerp;
break; break;
case CS_MISC_HIDE_ROOM: case CS_MISC_HIDE_ROOM:

View File

@ -2,7 +2,7 @@
#include "regs.h" #include "regs.h"
#include "functions.h" #include "functions.h"
#include "z64malloc.h" #include "z64malloc.h"
#include "z64vismono.h" #include "z64vis.h"
#include "z64visfbuf.h" #include "z64visfbuf.h"
// Variables are put before most headers as a hacky way to bypass bss reordering // Variables are put before most headers as a hacky way to bypass bss reordering
@ -11,7 +11,7 @@ Input D_801F6C18;
TransitionTile sTransitionTile; TransitionTile sTransitionTile;
s32 gTransitionTileState; s32 gTransitionTileState;
VisMono sPlayVisMono; VisMono sPlayVisMono;
Color_RGBA8_u32 gVisMonoColor; Color_RGBA8_u32 gPlayVisMonoColor;
VisFbuf sPlayVisFbuf; VisFbuf sPlayVisFbuf;
VisFbuf* sPlayVisFbufInstance; VisFbuf* sPlayVisFbufInstance;
BombersNotebook sBombersNotebook; BombersNotebook sBombersNotebook;
@ -1232,8 +1232,8 @@ void Play_DrawMain(PlayState* this) {
TransitionFade_Draw(&this->unk_18E48, &sp218); TransitionFade_Draw(&this->unk_18E48, &sp218);
if (gVisMonoColor.a != 0) { if (gPlayVisMonoColor.a != 0) {
sPlayVisMono.primColor.rgba = gVisMonoColor.rgba; sPlayVisMono.vis.primColor.rgba = gPlayVisMonoColor.rgba;
VisMono_Draw(&sPlayVisMono, &sp218); VisMono_Draw(&sPlayVisMono, &sp218);
} }
@ -2301,7 +2301,7 @@ void Play_Init(GameState* thisx) {
TransitionFade_Start(&this->unk_18E48); TransitionFade_Start(&this->unk_18E48);
VisMono_Init(&sPlayVisMono); VisMono_Init(&sPlayVisMono);
gVisMonoColor.a = 0; gPlayVisMonoColor.a = 0;
sPlayVisFbufInstance = &sPlayVisFbuf; sPlayVisFbufInstance = &sPlayVisFbuf;
VisFbuf_Init(sPlayVisFbufInstance); VisFbuf_Init(sPlayVisFbufInstance);
sPlayVisFbufInstance->lodProportion = 0.0f; sPlayVisFbufInstance->lodProportion = 0.0f;

View File

@ -1,14 +1,43 @@
/**
* @file z_viscvg.c
*
* This file implements full-screen frame buffer effects involving the visualization of Coverage in various ways.
*
* Coverage is roughly how much of a pixel is covered by a primitive; the final coverage for a frame is stored in the
* color image alpha component where it is used for antialiasing, see PreRender.c and §15 of the programming manual for
* details.
*
* To understand this file, it is helpful to remember that A_MEM is essentially synonymous with coverage, and that
* `GBL_c1/2(p, a, m, b)` usually represents the RDP blender calculation `(p * a + m * b)`.
* Note the division step that is often included in the blender calculation is omitted; the division is skipped if
* force blending (FORCE_BL) is set, which is the case for all render modes used in this file.
*
* Coverage is full when not on an edge, while on an edge it is usually lower. Since coverage is treated as an alpha
* value, edges of primitives where coverage is lower will show up darker than primitive interiors in all of the
* available modes.
*
* Coverage is abbreviated to "cvg"; "FB RGB" ("framebuffer red/green/blue") is the color the pixel originally had
* before the filter is applied.
*/
#include "z64vis.h"
#include "global.h" #include "global.h"
#include "z64viscvg.h"
Gfx D_801C5DD0[] = { /**
* Draws only coverage: does not retain any of the original pixel RGB, primColor is used as background color.
*/
Gfx sCoverageOnlyDL[] = {
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2), G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2),
gsSPBranchList(D_0E000000.fillRect), gsSPBranchList(D_0E000000.fillRect),
}; };
Gfx D_801C5DE0[] = { /**
* Draws fog + coverage * RGB of pixels
*
* @bug This easily overflows the blender because the fog value is added to the coverage value.
*/
Gfx sCoverageRGBFogDL[] = {
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
@ -17,7 +46,10 @@ Gfx D_801C5DE0[] = {
gsSPBranchList(D_0E000000.fillRect), gsSPBranchList(D_0E000000.fillRect),
}; };
Gfx D_801C5DF0[] = { /**
* Draws coverage and RGB of pixels
*/
Gfx sCoverageRGBDL[] = {
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
@ -26,7 +58,14 @@ Gfx D_801C5DF0[] = {
gsSPBranchList(D_0E000000.fillRect), gsSPBranchList(D_0E000000.fillRect),
}; };
Gfx D_801C5E00[] = { /**
* Two stage filtering:
*
* 1. Apply a uniform color filter by transparently blending primColor with original frame. The "cloud surface"
* RenderMode is used to preserve the coverage for the second stage.
* 2. Second half is the same as `sCoverageRGBDL`'s, i.e. (RGB from stage 1) * cvg
*/
Gfx sCoverageRGBUniformDL[] = {
gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE), gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE),
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_DISABLE | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_DISABLE | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
@ -41,45 +80,45 @@ Gfx D_801C5E00[] = {
}; };
void VisCvg_Init(VisCvg* this) { void VisCvg_Init(VisCvg* this) {
this->type = 0; this->vis.type = VIS_CVG_TYPE_NONE;
this->setScissor = false; this->vis.scissorType = VIS_NO_SETSCISSOR;
this->color.r = 255; this->vis.primColor.r = 255;
this->color.g = 255; this->vis.primColor.g = 255;
this->color.b = 255; this->vis.primColor.b = 255;
this->color.a = 255; this->vis.primColor.a = 255;
} }
void VisCvg_Destroy(VisCvg* this) { void VisCvg_Destroy(VisCvg* this) {
} }
void VisCvg_Draw(VisCvg* this, Gfx** gfxp) { void VisCvg_Draw(VisCvg* this, Gfx** gfxP) {
Gfx* gfx = *gfxp; Gfx* gfx = *gfxP;
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
gDPSetPrimDepth(gfx++, -1, -1); gDPSetPrimDepth(gfx++, -1, -1);
if (this->setScissor == true) { if (this->vis.scissorType == VIS_SETSCISSOR) {
gSPDisplayList(gfx++, D_0E000000.setScissor); gSPDisplayList(gfx++, D_0E000000.setScissor);
} }
switch (this->type) { switch (this->vis.type) {
case 1: case VIS_CVG_TYPE_CVG_RGB:
gSPDisplayList(gfx++, D_801C5DF0); gSPDisplayList(gfx++, sCoverageRGBDL);
break; break;
case 2: case VIS_CVG_TYPE_CVG_RGB_UNIFORM:
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->color.rgba); gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
gSPDisplayList(gfx++, D_801C5E00); gSPDisplayList(gfx++, sCoverageRGBUniformDL);
break; break;
case 3: case VIS_CVG_TYPE_CVG_ONLY:
gDPSetColor(gfx++, G_SETBLENDCOLOR, this->color.rgba); gDPSetColor(gfx++, G_SETBLENDCOLOR, this->vis.primColor.rgba);
gSPDisplayList(gfx++, D_801C5DD0); gSPDisplayList(gfx++, sCoverageOnlyDL);
break; break;
case 4: case VIS_CVG_TYPE_CVG_RGB_FOG:
gDPSetColor(gfx++, G_SETFOGCOLOR, this->color.rgba); gDPSetColor(gfx++, G_SETFOGCOLOR, this->vis.primColor.rgba);
gSPDisplayList(gfx++, D_801C5DE0); gSPDisplayList(gfx++, sCoverageRGBFogDL);
break; break;
default: default:
@ -87,5 +126,5 @@ void VisCvg_Draw(VisCvg* this, Gfx** gfxp) {
} }
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
*gfxp = gfx; *gfxP = gfx;
} }

View File

@ -1,16 +1,20 @@
/* /**
* File: z_vismono.c * @file z_vismono.c
* Description: Color frame buffer effect to desaturate the colors. *
* This file implements a full-screen framebuffer effect for desaturating the contents of the framebuffer image.
*
* Broadly, this effect is achieved by reinterpreting the contents of the RGBA16 color image as indices into an IA16
* color palette that converts each color into the desaturated equivalent. More precise details can be found in inline
* comments.
*/ */
#include "z64vis.h"
#include "global.h" #include "global.h"
#include "z64vismono.h"
#include "libc64/malloc.h" #include "libc64/malloc.h"
// Height of the fragments the color frame buffer (CFB) is split into. // Height of the fragments the color frame buffer (CFB) is split into.
// It is the maximum amount of lines such that all rgba16 SCREEN_WIDTH-long lines fit into // It is the maximum amount of lines such that all rgba16 SCREEN_WIDTH-long lines fit into
// the half of tmem (0x800 bytes) dedicated to color-indexed data. // the half of TMEM dedicated to color-indexed data.
#define VISMONO_CFBFRAG_HEIGHT (0x800 / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES)) #define VISMONO_CFBFRAG_HEIGHT ((TMEM_SIZE / 2) / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES))
// Maximum size of the dlist written by `VisMono_DesaturateDList`. // Maximum size of the dlist written by `VisMono_DesaturateDList`.
// `VisMono_DesaturateDList` consistently uses `VISMONO_DLSIZE - 2` double words, so this can be 2 less. // `VisMono_DesaturateDList` consistently uses `VISMONO_DLSIZE - 2` double words, so this can be 2 less.
@ -26,16 +30,16 @@
void VisMono_Init(VisMono* this) { void VisMono_Init(VisMono* this) {
bzero(this, sizeof(VisMono)); bzero(this, sizeof(VisMono));
this->unk_00 = 0; this->vis.type = 0;
this->setScissor = false; this->vis.scissorType = VIS_NO_SETSCISSOR;
this->primColor.r = 255; this->vis.primColor.r = 255;
this->primColor.g = 255; this->vis.primColor.g = 255;
this->primColor.b = 255; this->vis.primColor.b = 255;
this->primColor.a = 255; this->vis.primColor.a = 255;
this->envColor.r = 0; this->vis.envColor.r = 0;
this->envColor.g = 0; this->vis.envColor.g = 0;
this->envColor.b = 0; this->vis.envColor.b = 0;
this->envColor.a = 0; this->vis.envColor.a = 0;
} }
void VisMono_Destroy(VisMono* this) { void VisMono_Destroy(VisMono* this) {
@ -95,6 +99,8 @@ Gfx* VisMono_DesaturateDList(Gfx* gfx) {
// Set texel 1 to be a CI8 image with width `SCREEN_WIDTH * 2` and height `VISMONO_CFBFRAG_HEIGHT` // Set texel 1 to be a CI8 image with width `SCREEN_WIDTH * 2` and height `VISMONO_CFBFRAG_HEIGHT`
// Its position in texture image space is shifted along +S by 1 // Its position in texture image space is shifted along +S by 1
// Note the palette index for this tile has also been incremented from 0 to 1, however the palette index is
// ignored for CI8 texture sampling.
gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2 * G_IM_SIZ_8b_LINE_BYTES / 8, 0x0, 1, 1, gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2 * G_IM_SIZ_8b_LINE_BYTES / 8, 0x0, 1, 1,
G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0); G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0);
gDPSetTileSize(gfx++, 1, 1 << 2, 0, (SCREEN_WIDTH * 2) << 2, (VISMONO_CFBFRAG_HEIGHT - 1) << 2); gDPSetTileSize(gfx++, 1, 1 << 2, 0, (SCREEN_WIDTH * 2) << 2, (VISMONO_CFBFRAG_HEIGHT - 1) << 2);
@ -129,8 +135,8 @@ Gfx* VisMono_DesaturateDList(Gfx* gfx) {
return gfx; return gfx;
} }
void VisMono_Draw(VisMono* this, Gfx** gfxp) { void VisMono_Draw(VisMono* this, Gfx** gfxP) {
Gfx* gfx = *gfxp; Gfx* gfx = *gfxP;
u16* tlut; u16* tlut;
Gfx* dList; Gfx* dList;
Gfx* dListEnd; Gfx* dListEnd;
@ -151,12 +157,12 @@ void VisMono_Draw(VisMono* this, Gfx** gfxp) {
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
if (this->setScissor == true) { if (this->vis.scissorType == VIS_SETSCISSOR) {
gSPDisplayList(gfx++, D_0E000000.setScissor); gSPDisplayList(gfx++, D_0E000000.setScissor);
} }
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->primColor.rgba); gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
gDPSetColor(gfx++, G_SETENVCOLOR, this->envColor.rgba); gDPSetColor(gfx++, G_SETENVCOLOR, this->vis.envColor.rgba);
gDPLoadTLUT_pal256(gfx++, tlut); gDPLoadTLUT_pal256(gfx++, tlut);
@ -164,7 +170,7 @@ void VisMono_Draw(VisMono* this, Gfx** gfxp) {
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
*gfxp = gfx; *gfxP = gfx;
} }
void VisMono_DrawOld(VisMono* this) { void VisMono_DrawOld(VisMono* this) {

View File

@ -1,55 +1,100 @@
/**
* @file z_viszbuf.c
*
* This file implements a full-screen framebuffer effect for visualizing the z-buffer (AKA depth buffer), using either
* cycling RGBA or a single fading color.
*
* This is done by reading the z-buffer as if it were a color image, the format of which is specified by the selected
* vis type:
* - VIS_ZBUF_TYPE_IA : Produces a monotonic fade from primColor to envColor as depth increases.
* - VIS_ZBUF_TYPE_RGBA : Produces vibrant almost-periodic-looking bands.
*
* In both cases this occurs because of the format the depth information takes: it is 18-bit, and is a nonnegative
* floating-point number with
* bbb mmmmmmmmmmm dd|dd
* exponent mantissa dz value (only first 16 bits visible to CPU, the least significant 2 bits of dz are ignored)
*
* Reading z-buffer as IA16:
* bbbmmmmm mmmmmmdd
* iiiiiiii aaaaaaaa
*
* Since floating-point numbers of this format have the same ordering as their binary/hex representation, increasing
* the depth also increases the intensity in the IA16 representation and hence the interpolation parameter used to
* combine primColor and envColor. The alpha is ignored by the RenderMode.
*
* Reading z-buffer as RGBA16:
* bbbmm mmmmm mmmmd d
* rrrrr ggggg bbbbb a
*
* The red increases monotonically with the depth. The significant visible oscillation is the green component, because
* it rolls over every time the second-most-significant bit of the mantissa increments. The blue component oscillates
* too rapidly to be particularly visible (it rolls over when the 7th-most-significant bit increments). The alpha is
* again ignored by the RenderMode.
*/
#include "z64vis.h"
#include "global.h" #include "global.h"
#include "z64viszbuf.h"
#include "sys_cfb.h" #include "sys_cfb.h"
#include "libc/stdbool.h" #include "libc/stdbool.h"
// Height of the fragments the z-buffer is split into.
// It is the maximum amount of lines such that all rgba16 SCREEN_WIDTH-long lines fit into TMEM.
#define VISZBUF_ZBUFFRAG_HEIGHT (TMEM_SIZE / (gCfbWidth * G_IM_SIZ_16b_BYTES)) #define VISZBUF_ZBUFFRAG_HEIGHT (TMEM_SIZE / (gCfbWidth * G_IM_SIZ_16b_BYTES))
void VisZbuf_Init(VisZbuf* this) { /**
this->useRgba = false; * Initialise to IA type with white and black as default colors.
this->setScissor = false; */
this->primColor.r = 255; void VisZBuf_Init(VisZBuf* this) {
this->primColor.g = 255; this->vis.type = VIS_ZBUF_TYPE_IA;
this->primColor.b = 255; this->vis.scissorType = VIS_NO_SETSCISSOR;
this->primColor.a = 255; this->vis.primColor.r = 255;
this->envColor.r = 0; this->vis.primColor.g = 255;
this->envColor.g = 0; this->vis.primColor.b = 255;
this->envColor.b = 0; this->vis.primColor.a = 255;
this->envColor.a = 255; this->vis.envColor.r = 0;
this->vis.envColor.g = 0;
this->vis.envColor.b = 0;
this->vis.envColor.a = 255;
} }
void VisZbuf_Destroy(VisZbuf* this) { void VisZBuf_Destroy(VisZBuf* this) {
} }
void VisZbuf_Draw(VisZbuf* this, Gfx** gfxP, void* zbuffer) { void VisZBuf_Draw(VisZBuf* this, Gfx** gfxP, void* zbuffer) {
Gfx* gfx = *gfxP; Gfx* gfx = *gfxP;
s32 height = VISZBUF_ZBUFFRAG_HEIGHT; s32 height = VISZBUF_ZBUFFRAG_HEIGHT;
s32 y; s32 y;
s32 fmt = !this->useRgba ? G_IM_FMT_IA : G_IM_FMT_RGBA; s32 fmt = (this->vis.type == VIS_ZBUF_TYPE_IA) ? G_IM_FMT_IA : G_IM_FMT_RGBA;
if (zbuffer == NULL) { if (zbuffer == NULL) {
return; return;
} }
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
if (this->setScissor == true) { if (this->vis.scissorType == VIS_SETSCISSOR) {
gSPDisplayList(gfx++, D_0E000000.setScissor); gSPDisplayList(gfx++, D_0E000000.setScissor);
} }
// No palette so can use all of TMEM.
// G_RM_OPA_SURF discards all information previously in the pixel, and the current alpha, leaving only the color
// from this filter.
gDPSetOtherMode(gfx++, gDPSetOtherMode(gfx++,
G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2); G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2);
// LERP between primColor and envColor in 1-cycle mode using the z-buffer value.
gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT,
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT); PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT);
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->primColor.rgba); gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
gDPSetColor(gfx++, G_SETENVCOLOR, this->envColor.rgba); gDPSetColor(gfx++, G_SETENVCOLOR, this->vis.envColor.rgba);
for (y = 0; y < (gCfbHeight - height) + 1; y += height) { for (y = 0; y < (gCfbHeight - height) + 1; y += height) {
// Load a few lines of the z-buffer, as many as can fit in TMEM at once.
gDPLoadTextureTile(gfx++, zbuffer, fmt, G_IM_SIZ_16b, gCfbWidth, 0, 0, y, gCfbWidth - 1, (y + height) - 1, 0, gDPLoadTextureTile(gfx++, zbuffer, fmt, G_IM_SIZ_16b, gCfbWidth, 0, 0, y, gCfbWidth - 1, (y + height) - 1, 0,
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD); G_TX_NOLOD);
// Overwrite them with the calculated colors.
gSPTextureRectangle(gfx++, 0, y << 2, gCfbWidth << 2, (y + height) << 2, G_TX_RENDERTILE, 0, y << 5, 1 << 10, gSPTextureRectangle(gfx++, 0, y << 2, gCfbWidth << 2, (y + height) << 2, G_TX_RENDERTILE, 0, y << 5, 1 << 10,
1 << 10); 1 << 10);
} }

View File

@ -2775,9 +2775,9 @@
0x80141C34:("VisMono_DesaturateDList",), 0x80141C34:("VisMono_DesaturateDList",),
0x80141E60:("VisMono_Draw",), 0x80141E60:("VisMono_Draw",),
0x8014204C:("VisMono_DrawOld",), 0x8014204C:("VisMono_DrawOld",),
0x801420C0:("VisZbuf_Init",), 0x801420C0:("VisZBuf_Init",),
0x801420F4:("VisZbuf_Destroy",), 0x801420F4:("VisZBuf_Destroy",),
0x80142100:("VisZbuf_Draw",), 0x80142100:("VisZBuf_Draw",),
0x80142440:("Skybox_CalculateFace128",), 0x80142440:("Skybox_CalculateFace128",),
0x80143148:("Skybox_Calculate128",), 0x80143148:("Skybox_Calculate128",),
0x801431E8:("Skybox_Setup",), 0x801431E8:("Skybox_Setup",),

View File

@ -1897,10 +1897,10 @@
0x801C5D60:("gShadowMaterialDL","UNK_TYPE1","",0x1), 0x801C5D60:("gShadowMaterialDL","UNK_TYPE1","",0x1),
0x801C5D80:("gShadowModelDL","UNK_TYPE1","",0x1), 0x801C5D80:("gShadowModelDL","UNK_TYPE1","",0x1),
0x801C5DB0:("gOneVec3f","UNK_TYPE1","",0x1), 0x801C5DB0:("gOneVec3f","UNK_TYPE1","",0x1),
0x801C5DD0:("D_801C5DD0","UNK_TYPE1","",0x1), 0x801C5DD0:("sCoverageOnlyDL","UNK_TYPE1","",0x1),
0x801C5DE0:("D_801C5DE0","UNK_TYPE1","",0x1), 0x801C5DE0:("sCoverageRGBFogDL","UNK_TYPE1","",0x1),
0x801C5DF0:("D_801C5DF0","UNK_TYPE1","",0x1), 0x801C5DF0:("sCoverageRGBDL","UNK_TYPE1","",0x1),
0x801C5E00:("D_801C5E00","UNK_TYPE1","",0x1), 0x801C5E00:("sCoverageRGBUniformDL","UNK_TYPE1","",0x1),
0x801C5E30:("sSkybox128TexOffsets","UNK_TYPE1","",0x1), 0x801C5E30:("sSkybox128TexOffsets","UNK_TYPE1","",0x1),
0x801C5E48:("sSkybox128VtxBufIndices","UNK_TYPE2","",0x2), 0x801C5E48:("sSkybox128VtxBufIndices","UNK_TYPE2","",0x2),
0x801C5E88:("sSkybox128TexSCoords","UNK_TYPE4","",0x4), 0x801C5E88:("sSkybox128TexSCoords","UNK_TYPE4","",0x4),
@ -3973,7 +3973,7 @@
0x801F6C30:("sTransitionTile","TransitionTile","",0xE0), 0x801F6C30:("sTransitionTile","TransitionTile","",0xE0),
0x801F6D10:("gTransitionTileState","UNK_TYPE4","",0x4), 0x801F6D10:("gTransitionTileState","UNK_TYPE4","",0x4),
0x801F6D18:("sPlayVisMono","VisMono","",0x18), 0x801F6D18:("sPlayVisMono","VisMono","",0x18),
0x801F6D30:("gVisMonoColor","Color_RGBA8","",0x4), 0x801F6D30:("gPlayVisMonoColor","Color_RGBA8","",0x4),
0x801F6D38:("sPlayVisFbuf","UNK_TYPE1","",0x1), 0x801F6D38:("sPlayVisFbuf","UNK_TYPE1","",0x1),
0x801F6D4C:("sPlayVisFbufInstance","UNK_TYPE4","",0x4), 0x801F6D4C:("sPlayVisFbufInstance","UNK_TYPE4","",0x4),
0x801F6D50:("sBombersNotebook","UNK_TYPE1","",0x1), 0x801F6D50:("sBombersNotebook","UNK_TYPE1","",0x1),
@ -3985,7 +3985,7 @@
0x801F6FE8:("sSlowlyStack","u8","[4096]",0x1000), 0x801F6FE8:("sSlowlyStack","u8","[4096]",0x1000),
0x801F7FF0:("sGameSpeedMeter","SpeedMeter","", 0x20), 0x801F7FF0:("sGameSpeedMeter","SpeedMeter","", 0x20),
0x801F8010:("sGameVisCvg","VisCvg","",0x10), 0x801F8010:("sGameVisCvg","VisCvg","",0x10),
0x801F8020:("sGameVisZbuf","VisZbuf","",0x10), 0x801F8020:("sGameVisZBuf","VisZBuf","",0x10),
0x801F8030:("sGameVisMono","VisMono","",0x18), 0x801F8030:("sGameVisMono","VisMono","",0x18),
0x801F8048:("sGameViMode","ViMode","",0x88), 0x801F8048:("sGameViMode","ViMode","",0x88),
0x801F80D0:("sGraphFaultAddrConvClient","FaultAddrConvClient","",0xc), 0x801F80D0:("sGraphFaultAddrConvClient","FaultAddrConvClient","",0xc),

View File

@ -2289,9 +2289,9 @@ asm/non_matchings/code/z_vismono/VisMono_DesaturateTLUT.s,VisMono_DesaturateTLUT
asm/non_matchings/code/z_vismono/VisMono_DesaturateDList.s,VisMono_DesaturateDList,0x80141C34,0x8B asm/non_matchings/code/z_vismono/VisMono_DesaturateDList.s,VisMono_DesaturateDList,0x80141C34,0x8B
asm/non_matchings/code/z_vismono/VisMono_Draw.s,VisMono_Draw,0x80141E60,0x7B asm/non_matchings/code/z_vismono/VisMono_Draw.s,VisMono_Draw,0x80141E60,0x7B
asm/non_matchings/code/z_vismono/VisMono_DrawOld.s,VisMono_DrawOld,0x8014204C,0x1D asm/non_matchings/code/z_vismono/VisMono_DrawOld.s,VisMono_DrawOld,0x8014204C,0x1D
asm/non_matchings/code/z_viszbuf/VisZbuf_Init.s,VisZbuf_Init,0x801420C0,0xD asm/non_matchings/code/z_viszbuf/VisZBuf_Init.s,VisZBuf_Init,0x801420C0,0xD
asm/non_matchings/code/z_viszbuf/VisZbuf_Destroy.s,VisZbuf_Destroy,0x801420F4,0x3 asm/non_matchings/code/z_viszbuf/VisZBuf_Destroy.s,VisZBuf_Destroy,0x801420F4,0x3
asm/non_matchings/code/z_viszbuf/VisZbuf_Draw.s,VisZbuf_Draw,0x80142100,0xD0 asm/non_matchings/code/z_viszbuf/VisZBuf_Draw.s,VisZBuf_Draw,0x80142100,0xD0
asm/non_matchings/code/z_vr_box/Skybox_CalculateFace128.s,Skybox_CalculateFace128,0x80142440,0x342 asm/non_matchings/code/z_vr_box/Skybox_CalculateFace128.s,Skybox_CalculateFace128,0x80142440,0x342
asm/non_matchings/code/z_vr_box/Skybox_Calculate128.s,Skybox_Calculate128,0x80143148,0x28 asm/non_matchings/code/z_vr_box/Skybox_Calculate128.s,Skybox_Calculate128,0x80143148,0x28
asm/non_matchings/code/z_vr_box/Skybox_Setup.s,Skybox_Setup,0x801431E8,0x4F asm/non_matchings/code/z_vr_box/Skybox_Setup.s,Skybox_Setup,0x801431E8,0x4F

1 asm/non_matchings/code/z_en_a_keep/EnAObj_Init.s EnAObj_Init 0x800A5AC0 0x2B
2289 asm/non_matchings/code/z_vismono/VisMono_DesaturateDList.s VisMono_DesaturateDList 0x80141C34 0x8B
2290 asm/non_matchings/code/z_vismono/VisMono_Draw.s VisMono_Draw 0x80141E60 0x7B
2291 asm/non_matchings/code/z_vismono/VisMono_DrawOld.s VisMono_DrawOld 0x8014204C 0x1D
2292 asm/non_matchings/code/z_viszbuf/VisZbuf_Init.s asm/non_matchings/code/z_viszbuf/VisZBuf_Init.s VisZbuf_Init VisZBuf_Init 0x801420C0 0xD
2293 asm/non_matchings/code/z_viszbuf/VisZbuf_Destroy.s asm/non_matchings/code/z_viszbuf/VisZBuf_Destroy.s VisZbuf_Destroy VisZBuf_Destroy 0x801420F4 0x3
2294 asm/non_matchings/code/z_viszbuf/VisZbuf_Draw.s asm/non_matchings/code/z_viszbuf/VisZBuf_Draw.s VisZbuf_Draw VisZBuf_Draw 0x80142100 0xD0
2295 asm/non_matchings/code/z_vr_box/Skybox_CalculateFace128.s Skybox_CalculateFace128 0x80142440 0x342
2296 asm/non_matchings/code/z_vr_box/Skybox_Calculate128.s Skybox_Calculate128 0x80143148 0x28
2297 asm/non_matchings/code/z_vr_box/Skybox_Setup.s Skybox_Setup 0x801431E8 0x4F