VisMono OK and documented (#829)

* VisMono OK and documented

* Add some more parentheses

* Fix functions.h

* Respond to hansldm's review
This commit is contained in:
Tom Overton
2022-06-19 02:46:41 +01:00
committed by GitHub
parent b6362cacbe
commit d1b75e4c4b
10 changed files with 200 additions and 34 deletions
+1
View File
@@ -216,6 +216,7 @@
#define GPACK_RGBA5551(r, g, b, a) ((((r)<<8) & 0xf800) | \
(((g)<<3) & 0x7c0) | \
(((b)>>2) & 0x3e) | ((a) & 0x1))
#define GPACK_IA16(i, a) (((i) << 8) | (a))
#define GPACK_ZDZ(z, dz) ((z) << 2 | (dz))
/*
+6 -6
View File
@@ -2534,12 +2534,12 @@ void func_80140E80(void* param_1);
// void func_8014151C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6);
// void func_80141678(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5);
// void func_80141778(void);
void func_801418B0(void* arg0);
void func_80141900(void* arg0);
// void func_80141924(void);
// void func_80141C34(void);
void VisMono_Draw(void* arg0, Gfx** gfx, u32 arg2);
// void func_8014204C(void);
void VisMono_Init(VisMono* this);
void VisMono_Destroy(VisMono* this);
// void VisMono_DesaturateTLUT(u16* tlut);
// void VisMono_DesaturateDList(Gfx* gfx);
void VisMono_Draw(VisMono* this, Gfx** gfxp);
// void VisMono_DrawOld(VisMono* this);
void func_801420C0(void* arg0);
void func_801420F4(void* arg0);
void func_80142100(void* arg0, Gfx** gfx, u32 arg2);
+1 -1
View File
@@ -3562,7 +3562,7 @@ extern u16 gFramebuffer0[SCREEN_HEIGHT][SCREEN_WIDTH];
// other segments
extern GfxMasterList D_0E000000;
extern Mtx D_01000000;
extern UNK_TYPE D_0F000000;
extern u16 D_0F000000[];
#endif
+3 -3
View File
@@ -1404,10 +1404,10 @@ typedef struct {
typedef struct {
/* 0x00 */ u32 unk_00;
/* 0x04 */ u32 setScissor;
/* 0x08 */ Color_RGBA8 primColor;
/* 0x0C */ Color_RGBA8 envColor;
/* 0x08 */ Color_RGBA8_u32 primColor;
/* 0x0C */ Color_RGBA8_u32 envColor;
/* 0x10 */ u16* tlut;
/* 0x14 */ Gfx* monoDl;
/* 0x14 */ Gfx* dList;
} VisMono; // size = 0x18
typedef struct DebugDispObject {
+3 -3
View File
@@ -52,7 +52,7 @@ void GameState_SetFBFilter(Gfx** gfx, u32 arg1) {
sMonoColors.envColor.g = R_FB_FILTER_ENV_COLOR(1);
sMonoColors.envColor.b = R_FB_FILTER_ENV_COLOR(2);
sMonoColors.envColor.a = R_FB_FILTER_A;
VisMono_Draw(&sMonoColors, &dlist, arg1);
VisMono_Draw(&sMonoColors, &dlist);
}
}
}
@@ -213,7 +213,7 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
func_80140CE0(&D_801F8010);
func_801420C0(&D_801F8020);
func_801418B0(&sMonoColors);
VisMono_Init(&sMonoColors);
func_80140898(&D_801F8048);
func_801773A0(&D_801F7FF0);
func_8013ED9C();
@@ -235,7 +235,7 @@ void GameState_Destroy(GameState* gameState) {
func_801773C4(&D_801F7FF0);
func_80140D04(&D_801F8010);
func_801420F4(&D_801F8020);
func_80141900(&sMonoColors);
VisMono_Destroy(&sMonoColors);
func_80140900(&D_801F8048);
THA_Dt(&gameState->heap);
GameAlloc_Cleanup(&gameState->alloc);
+4 -4
View File
@@ -1239,11 +1239,11 @@ void func_8012CF0C(GraphicsContext* gfxCtx, s32 clearFb, s32 clearZb, u8 r, u8 g
gSPDisplayList(&masterGfx[0], D_0E000000.syncSegments);
gSPDisplayList(&masterGfx[1], sFillSetupDL);
gDPSetColorImage(&masterGfx[2], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, &D_0F000000);
gDPSetColorImage(&masterGfx[2], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, D_0F000000);
if (zbuffer != NULL) {
gDPSetDepthImage(&masterGfx[3], zbuffer);
} else {
gDPSetDepthImage(&masterGfx[3], &D_0F000000);
gDPSetDepthImage(&masterGfx[3], D_0F000000);
}
gSPEndDisplayList(&masterGfx[4]);
@@ -1267,7 +1267,7 @@ void func_8012CF0C(GraphicsContext* gfxCtx, s32 clearFb, s32 clearZb, u8 r, u8 g
gDPSetRenderMode(&masterGfx[3], G_RM_NOOP, G_RM_NOOP2);
gDPSetFillColor(&masterGfx[4], (GPACK_RGBA5551(255, 255, 240, 0) << 16) | GPACK_RGBA5551(255, 255, 240, 0));
gSPDisplayList(&masterGfx[5], D_0E000000.clearFillRect);
gDPSetColorImage(&masterGfx[6], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, &D_0F000000);
gDPSetColorImage(&masterGfx[6], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, D_0F000000);
gSPEndDisplayList(&masterGfx[7]);
}
@@ -1275,7 +1275,7 @@ void func_8012CF0C(GraphicsContext* gfxCtx, s32 clearFb, s32 clearZb, u8 r, u8 g
masterGfx = gGfxMasterDL->clearFrameBuffer;
gDPSetColorImage(&masterGfx[0], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, &D_0F000000);
gDPSetColorImage(&masterGfx[0], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, D_0F000000);
gDPSetCycleType(&masterGfx[1], G_CYC_FILL);
gDPSetRenderMode(&masterGfx[2], G_RM_NOOP, G_RM_NOOP2);
gDPSetFillColor(&masterGfx[3], (GPACK_RGBA5551(r, g, b, 1) << 16) | GPACK_RGBA5551(r, g, b, 1));
+171 -6
View File
@@ -1,14 +1,179 @@
/*
* File: z_vismono.c
* Description: Color frame buffer effect to desaturate the colors.
*/
#include "global.h"
#include "system_malloc.h"
#pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/func_801418B0.s")
// 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
// the half of tmem (0x800 bytes) dedicated to color-indexed data.
#define VISMONO_CFBFRAG_HEIGHT (0x800 / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES))
#pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/func_80141900.s")
// Maximum size of the dlist written by `VisMono_DesaturateDList`.
// `VisMono_DesaturateDList` consistently uses `VISMONO_DLSIZE - 2` double words, so this can be 2 less.
#define VISMONO_DLSIZE (3 + SCREEN_HEIGHT / VISMONO_CFBFRAG_HEIGHT * (7 + 2 + 2 + 3) + 2 + 2)
#pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/func_80141924.s")
// How much each color component contributes to the desaturated result.
// These coefficients are close to what the YUV color space defines Y (luminance) as:
// https://en.wikipedia.org/wiki/YUV#Conversion_to/from_RGB
#define VISMONO_FAC_RED 2
#define VISMONO_FAC_GREEN 4
#define VISMONO_FAC_BLUE 1
#define VISMONO_FAC_NORM (0x1F * VISMONO_FAC_RED + 0x1F * VISMONO_FAC_GREEN + 0x1F * VISMONO_FAC_BLUE)
#pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/func_80141C34.s")
void VisMono_Init(VisMono* this) {
bzero(this, sizeof(VisMono));
this->unk_00 = 0;
this->setScissor = false;
this->primColor.r = 255;
this->primColor.g = 255;
this->primColor.b = 255;
this->primColor.a = 255;
this->envColor.r = 0;
this->envColor.g = 0;
this->envColor.b = 0;
this->envColor.a = 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/VisMono_Draw.s")
void VisMono_Destroy(VisMono* this) {
SystemArena_Free(this->dList);
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/func_8014204C.s")
void VisMono_DesaturateTLUT(u16* tlut) {
s32 i;
for (i = 0; i < 256; i++) {
// `tlut[i]` is a IA16 color
// `i` corresponds to either byte of a RGBA16 color RRRR_RGGG GGBB_BBBA from the color frame buffer
// The high byte I (intensity) corresponds to `i` being interpreted as the high byte RRRR_RGGG
// I = (RRRRR * FAC_RED + GGG00 * FAC_GREEN) * (255 / FAC_NORM)
// The low byte A (alpha) corresponds to `i` being interpreted as the low byte GGBB_BBBA
// A = (000GG * FAC_GREEN + BBBBB * FAC_BLUE) * (255 / FAC_NORM)
// Note: I + A = (RRRRR * FAC_RED + GGGGG * FAC_GREEN + BBBBB * FAC_BLUE) * (255 / FAC_NORM)
tlut[i] = GPACK_IA16(
(((i >> 3) & 0x1F) * VISMONO_FAC_RED + ((i << 2) & 0x1F) * VISMONO_FAC_GREEN) * 255 / VISMONO_FAC_NORM,
(((i >> 6) & 0x1F) * VISMONO_FAC_GREEN + ((i >> 1) & 0x1F) * VISMONO_FAC_BLUE) * 255 / VISMONO_FAC_NORM);
}
}
Gfx* VisMono_DesaturateDList(Gfx* gfx) {
s32 y;
s32 height = VISMONO_CFBFRAG_HEIGHT;
u16* cfbFrag = D_0F000000;
gDPPipeSync(gfx++);
// `G_TT_IA16`: use color-indexed images, and IA16 palettes
gDPSetOtherMode(gfx++,
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_IA16 | G_TL_TILE |
G_TD_CLAMP | G_TP_NONE | G_CYC_2CYCLE | G_PM_1PRIMITIVE,
G_AC_NONE | G_ZS_PRIM | GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) | G_RM_CLD_SURF2);
// First color cycle sums texel 1 alpha and texel 0 color
// By using IA16 palettes, this means summing A (from the IA16 color texel 1 maps to)
// with I (from the IA16 color texel 0 maps to)
gDPSetCombineLERP(gfx++, 1, 0, TEXEL1_ALPHA, TEXEL0, 0, 0, 0, 1, PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, 0,
0, 0, PRIMITIVE);
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
// Load a few lines of the color frame buffer
gDPLoadTextureBlock(gfx++, cfbFrag, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2, height, 0,
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD);
// Set texel 0 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 2
gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2 * G_IM_SIZ_8b_LINE_BYTES / 8, 0x0, G_TX_RENDERTILE,
0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0);
gDPSetTileSize(gfx++, G_TX_RENDERTILE, 2 << 2, 0, (SCREEN_WIDTH * 2 + 1) << 2,
(VISMONO_CFBFRAG_HEIGHT - 1) << 2);
// 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
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);
gDPSetTileSize(gfx++, 1, 1 << 2, 0, (SCREEN_WIDTH * 2) << 2, (VISMONO_CFBFRAG_HEIGHT - 1) << 2);
// Draw a `SCREEN_WIDTH` wide, `height` high rectangle.
// Texture coordinate T (vertical) starts at 0 and changes by one each line (dtdy = 1)
// Texture coordinate S (horizontal) starts at 2 and changes by two each column (dsdx = 2)
// Because texel 0 is shifted by 2 and texel 1 only by 1 along +S,
// a pixel at S coordinates s = 2+2*n will look at the 2*n-th byte of texel 0 and the 2*n+1-th byte of texel 1.
// (in "s = 2+2*n" the first "2" is the starting S coordinate and the second "2" is the dsdx value)
// The 2*n-th byte of texel 0 is the high byte of the n-th RGBA16 color of the color frame buffer.
// The 2*n+1-th byte of texel 1 is the low byte of the n-th RGBA16 color of the color frame buffer.
// With the TLUT computed by `VisMono_DesaturateTLUT`:
// The 2*n-th byte of texel 0 maps to a IA16 color where the high byte I (intensity) corresponds to
// the high byte of the n-th RGBA16 color of the color frame buffer.
// The 2*n+1-th byte of texel 1 maps to a IA16 color where the low byte A (alpha) corresponds to
// the low byte of the n-th RGBA16 color of the color frame buffer.
// Since the combiner is in part set up to sum texel 0 color (I, intensity) with texel 1 alpha (A, alpha),
// the resulting color in the drawn rectangle is a desaturated color as defined by the `VISMONO_FAC_*` values.
gSPTextureRectangle(gfx++, 0, y << 2, SCREEN_WIDTH << 2, (y + height) << 2, G_TX_RENDERTILE, 2 << 5, 0, 2 << 10,
1 << 10);
cfbFrag += SCREEN_WIDTH * height;
}
gDPPipeSync(gfx++);
gSPEndDisplayList(gfx++);
return gfx;
}
void VisMono_Draw(VisMono* this, Gfx** gfxp) {
Gfx* gfx = *gfxp;
u16* tlut;
Gfx* dList;
Gfx* dListEnd;
if (this->tlut) {
tlut = this->tlut;
} else {
tlut = Graph_DlistAlloc(&gfx, 256 * G_IM_SIZ_16b_BYTES);
VisMono_DesaturateTLUT(tlut);
}
if (this->dList) {
dList = this->dList;
} else {
dList = Graph_DlistAlloc(&gfx, VISMONO_DLSIZE * sizeof(Gfx));
dListEnd = VisMono_DesaturateDList(dList);
}
gDPPipeSync(gfx++);
if (this->setScissor == true) {
gSPDisplayList(gfx++, D_0E000000.setScissor);
}
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->primColor.rgba);
gDPSetColor(gfx++, G_SETENVCOLOR, this->envColor.rgba);
gDPLoadTLUT_pal256(gfx++, tlut);
gSPDisplayList(gfx++, dList);
gDPPipeSync(gfx++);
*gfxp = gfx;
}
void VisMono_DrawOld(VisMono* this) {
if (this->tlut == NULL) {
this->tlut = SystemArena_Malloc(256 * G_IM_SIZ_16b_BYTES);
VisMono_DesaturateTLUT(this->tlut);
}
if (this->dList == NULL) {
this->dList = SystemArena_Malloc(VISMONO_DLSIZE * sizeof(Gfx));
VisMono_DesaturateDList(this->dList);
}
}
@@ -31,7 +31,7 @@ const TransitionInit TransitionWipe5_InitVars = {
#endif
extern UNK_TYPE D_0F000000;
extern u16 D_0F000000[];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_fbdemo_wipe5/TransitionWipe5_Start.s")
+5 -5
View File
@@ -2769,12 +2769,12 @@
0x8014151C:("func_8014151C",),
0x80141678:("func_80141678",),
0x80141778:("func_80141778",),
0x801418B0:("func_801418B0",),
0x80141900:("func_80141900",),
0x80141924:("func_80141924",),
0x80141C34:("func_80141C34",),
0x801418B0:("VisMono_Init",),
0x80141900:("VisMono_Destroy",),
0x80141924:("VisMono_DesaturateTLUT",),
0x80141C34:("VisMono_DesaturateDList",),
0x80141E60:("VisMono_Draw",),
0x8014204C:("func_8014204C",),
0x8014204C:("VisMono_DrawOld",),
0x801420C0:("func_801420C0",),
0x801420F4:("func_801420F4",),
0x80142100:("func_80142100",),
+5 -5
View File
@@ -2283,12 +2283,12 @@ asm/non_matchings/code/code_80140E80/func_80141200.s,func_80141200,0x80141200,0x
asm/non_matchings/code/code_80140E80/func_8014151C.s,func_8014151C,0x8014151C,0x57
asm/non_matchings/code/code_80140E80/func_80141678.s,func_80141678,0x80141678,0x40
asm/non_matchings/code/code_80140E80/func_80141778.s,func_80141778,0x80141778,0x4E
asm/non_matchings/code/z_vismono/func_801418B0.s,func_801418B0,0x801418B0,0x14
asm/non_matchings/code/z_vismono/func_80141900.s,func_80141900,0x80141900,0x9
asm/non_matchings/code/z_vismono/func_80141924.s,func_80141924,0x80141924,0xC4
asm/non_matchings/code/z_vismono/func_80141C34.s,func_80141C34,0x80141C34,0x8B
asm/non_matchings/code/z_vismono/VisMono_Init.s,VisMono_Init,0x801418B0,0x14
asm/non_matchings/code/z_vismono/VisMono_Destroy.s,VisMono_Destroy,0x80141900,0x9
asm/non_matchings/code/z_vismono/VisMono_DesaturateTLUT.s,VisMono_DesaturateTLUT,0x80141924,0xC4
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/func_8014204C.s,func_8014204C,0x8014204C,0x1D
asm/non_matchings/code/z_vismono/VisMono_DrawOld.s,VisMono_DrawOld,0x8014204C,0x1D
asm/non_matchings/code/code_801420C0/func_801420C0.s,func_801420C0,0x801420C0,0xD
asm/non_matchings/code/code_801420C0/func_801420F4.s,func_801420F4,0x801420F4,0x3
asm/non_matchings/code/code_801420C0/func_80142100.s,func_80142100,0x80142100,0xD0
1 asm/non_matchings/code/z_en_a_keep/EnAObj_Init.s EnAObj_Init 0x800A5AC0 0x2B
2283 asm/non_matchings/code/code_80140E80/func_8014151C.s func_8014151C 0x8014151C 0x57
2284 asm/non_matchings/code/code_80140E80/func_80141678.s func_80141678 0x80141678 0x40
2285 asm/non_matchings/code/code_80140E80/func_80141778.s func_80141778 0x80141778 0x4E
2286 asm/non_matchings/code/z_vismono/func_801418B0.s asm/non_matchings/code/z_vismono/VisMono_Init.s func_801418B0 VisMono_Init 0x801418B0 0x14
2287 asm/non_matchings/code/z_vismono/func_80141900.s asm/non_matchings/code/z_vismono/VisMono_Destroy.s func_80141900 VisMono_Destroy 0x80141900 0x9
2288 asm/non_matchings/code/z_vismono/func_80141924.s asm/non_matchings/code/z_vismono/VisMono_DesaturateTLUT.s func_80141924 VisMono_DesaturateTLUT 0x80141924 0xC4
2289 asm/non_matchings/code/z_vismono/func_80141C34.s asm/non_matchings/code/z_vismono/VisMono_DesaturateDList.s func_80141C34 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/func_8014204C.s asm/non_matchings/code/z_vismono/VisMono_DrawOld.s func_8014204C VisMono_DrawOld 0x8014204C 0x1D
2292 asm/non_matchings/code/code_801420C0/func_801420C0.s func_801420C0 0x801420C0 0xD
2293 asm/non_matchings/code/code_801420C0/func_801420F4.s func_801420F4 0x801420F4 0x3
2294 asm/non_matchings/code/code_801420C0/func_80142100.s func_80142100 0x80142100 0xD0