mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-06-19 01:20:08 -07:00
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:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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")
|
||||
|
||||
|
||||
@@ -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",),
|
||||
|
||||
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user