mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-18 06:12:20 -05:00
Port over decomp updates for vis* and reimplement vismono fb (#4533)
* Port over decomp updates for vis* * move vismono framebuffer handling to file
This commit is contained in:
parent
2603b97366
commit
f12a2bbbb7
@ -1419,18 +1419,6 @@ void ViMode_Init(ViMode* viMode);
|
|||||||
void ViMode_Destroy(ViMode* viMode);
|
void ViMode_Destroy(ViMode* viMode);
|
||||||
void ViMode_ConfigureFeatures(ViMode* viMode, s32 viFeatures);
|
void ViMode_ConfigureFeatures(ViMode* viMode, s32 viFeatures);
|
||||||
void ViMode_Update(ViMode* viMode, Input* input);
|
void ViMode_Update(ViMode* viMode, Input* input);
|
||||||
void func_800ACE70(struct_801664F0* this);
|
|
||||||
void func_800ACE90(struct_801664F0* this);
|
|
||||||
void func_800ACE98(struct_801664F0* this, Gfx** gfxp);
|
|
||||||
void VisMono_Init(VisMono* this);
|
|
||||||
void VisMono_Destroy(VisMono* this);
|
|
||||||
void VisMono_UpdateTexture(VisMono* this, u16* tex);
|
|
||||||
Gfx* VisMono_DrawTexture(VisMono* this, Gfx* gfx);
|
|
||||||
void VisMono_Draw(VisMono* this, Gfx** gfxp);
|
|
||||||
void VisMono_DrawOld(VisMono* this);
|
|
||||||
void func_800AD920(struct_80166500* this);
|
|
||||||
void func_800AD950(struct_80166500* this);
|
|
||||||
void func_800AD958(struct_80166500* this, Gfx** gfxp);
|
|
||||||
void Skybox_Init(GameState* state, SkyboxContext* skyboxCtx, s16 skyboxId);
|
void Skybox_Init(GameState* state, SkyboxContext* skyboxCtx, s16 skyboxId);
|
||||||
Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z);
|
Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z);
|
||||||
void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z);
|
void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z);
|
||||||
|
9
soh/include/gfx.h
Normal file
9
soh/include/gfx.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef GFX_H
|
||||||
|
#define GFX_H
|
||||||
|
|
||||||
|
// Texture memory size, 4 KiB
|
||||||
|
#define TMEM_SIZE 0x1000
|
||||||
|
|
||||||
|
// Upstream TODO: Rest of this file
|
||||||
|
|
||||||
|
#endif
|
@ -299,6 +299,10 @@ extern GraphicsContext* __gfxCtx;
|
|||||||
#define BGCHECK_POS_ERROR_CHECK(vec3f) BgCheck_PosErrorCheck(vec3f, __FILE__, __LINE__)
|
#define BGCHECK_POS_ERROR_CHECK(vec3f) BgCheck_PosErrorCheck(vec3f, __FILE__, __LINE__)
|
||||||
|
|
||||||
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
|
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
|
||||||
|
|
||||||
|
// Upstream TODO: Bring back decomp file/line macro use in src (but ignore the args for our needs)
|
||||||
|
#define SYSTEM_ARENA_MALLOC(size, file, line) SystemArena_MallocDebug(size, __FILE__, __LINE__)
|
||||||
|
#define SYSTEM_ARENA_FREE(ptr, file, line) SystemArena_FreeDebug(ptr, __FILE__, __LINE__)
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
#define DPAD_ITEM(button) ((gSaveContext.buttonStatus[(button) + 5] != BTN_DISABLED) \
|
#define DPAD_ITEM(button) ((gSaveContext.buttonStatus[(button) + 5] != BTN_DISABLED) \
|
||||||
|
@ -203,7 +203,7 @@ extern "C"
|
|||||||
extern f32 gBossMarkScale;
|
extern f32 gBossMarkScale;
|
||||||
extern PauseMapMarksData* gLoadedPauseMarkDataTable;
|
extern PauseMapMarksData* gLoadedPauseMarkDataTable;
|
||||||
extern s32 gTrnsnUnkState;
|
extern s32 gTrnsnUnkState;
|
||||||
extern Color_RGBA8_u32 D_801614B0;
|
extern Color_RGBA8_u32 gVisMonoColor;
|
||||||
extern PreNmiBuff* gAppNmiBufferPtr;
|
extern PreNmiBuff* gAppNmiBufferPtr;
|
||||||
extern SchedContext gSchedContext;
|
extern SchedContext gSchedContext;
|
||||||
extern PadMgr gPadMgr;
|
extern PadMgr gPadMgr;
|
||||||
|
@ -25,12 +25,14 @@
|
|||||||
#include "z64skin.h"
|
#include "z64skin.h"
|
||||||
#include "z64transition.h"
|
#include "z64transition.h"
|
||||||
#include "z64interface.h"
|
#include "z64interface.h"
|
||||||
|
#include "z64vis.h"
|
||||||
#include "alignment.h"
|
#include "alignment.h"
|
||||||
#include "sequence.h"
|
#include "sequence.h"
|
||||||
#include "sfx.h"
|
#include "sfx.h"
|
||||||
#include <libultraship/color.h>
|
#include <libultraship/color.h>
|
||||||
#include "ichain.h"
|
#include "ichain.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
#if defined(__LP64__)
|
#if defined(__LP64__)
|
||||||
#define _SOH64
|
#define _SOH64
|
||||||
@ -2225,31 +2227,6 @@ typedef struct {
|
|||||||
/* 0x0084 */ u32 unk_84;
|
/* 0x0084 */ u32 unk_84;
|
||||||
} ViMode;
|
} ViMode;
|
||||||
|
|
||||||
// Vis...
|
|
||||||
typedef struct {
|
|
||||||
/* 0x00 */ u32 type;
|
|
||||||
/* 0x04 */ u32 setScissor;
|
|
||||||
/* 0x08 */ Color_RGBA8_u32 color;
|
|
||||||
/* 0x0C */ Color_RGBA8_u32 envColor;
|
|
||||||
} struct_801664F0; // size = 0x10
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* 0x00 */ u32 unk_00;
|
|
||||||
/* 0x04 */ u32 setScissor;
|
|
||||||
/* 0x08 */ Color_RGBA8_u32 primColor;
|
|
||||||
/* 0x0C */ Color_RGBA8_u32 envColor;
|
|
||||||
/* 0x10 */ u16* tlut;
|
|
||||||
/* 0x14 */ Gfx* monoDl;
|
|
||||||
} VisMono; // size = 0x18
|
|
||||||
|
|
||||||
// Vis...
|
|
||||||
typedef struct {
|
|
||||||
/* 0x00 */ u32 useRgba;
|
|
||||||
/* 0x04 */ u32 setScissor;
|
|
||||||
/* 0x08 */ Color_RGBA8_u32 primColor;
|
|
||||||
/* 0x08 */ Color_RGBA8_u32 envColor;
|
|
||||||
} struct_80166500; // size = 0x10
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x000 */ u8 rumbleEnable[4];
|
/* 0x000 */ u8 rumbleEnable[4];
|
||||||
/* 0x004 */ u8 unk_04[0x40];
|
/* 0x004 */ u8 unk_04[0x40];
|
||||||
|
101
soh/include/z64vis.h
Normal file
101
soh/include/z64vis.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#ifndef Z64_VIS_H
|
||||||
|
#define Z64_VIS_H
|
||||||
|
|
||||||
|
// #include "ultra64.h"
|
||||||
|
// #include "color.h"
|
||||||
|
#include <libultraship/libultra.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define this thisx
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 {
|
||||||
|
/* 0x00 */ u32 type;
|
||||||
|
/* 0x04 */ u32 scissorType;
|
||||||
|
/* 0x08 */ Color_RGBA8_u32 primColor;
|
||||||
|
/* 0x0C */ 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 {
|
||||||
|
/* 0x00 */ 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 {
|
||||||
|
/* 0x00 */ Vis vis;
|
||||||
|
} VisZBuf; // size = 0x10
|
||||||
|
|
||||||
|
void VisZBuf_Init(VisZBuf* this);
|
||||||
|
void VisZBuf_Destroy(VisZBuf* this);
|
||||||
|
void VisZBuf_Draw(VisZBuf* this, Gfx** gfxP);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#undef this
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -23,6 +23,10 @@ u16 gAudioSEFlagSwapSource[64];
|
|||||||
u16 gAudioSEFlagSwapTarget[64];
|
u16 gAudioSEFlagSwapTarget[64];
|
||||||
u8 gAudioSEFlagSwapMode[64];
|
u8 gAudioSEFlagSwapMode[64];
|
||||||
|
|
||||||
|
// Zbuffer and Color framebuffer
|
||||||
|
u16 D_0E000000[SCREEN_WIDTH * SCREEN_HEIGHT];
|
||||||
|
u16 D_0F000000[SCREEN_WIDTH * SCREEN_HEIGHT];
|
||||||
|
|
||||||
u8 osAppNmiBuffer[2048];
|
u8 osAppNmiBuffer[2048];
|
||||||
|
|
||||||
f32 qNaN0x10000 = 0x7F810000;
|
f32 qNaN0x10000 = 0x7F810000;
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
|
|
||||||
// Note : This file is related to z_vismono, the original name was probably z_vis<something before "mono"
|
|
||||||
// alphabetically>
|
|
||||||
|
|
||||||
Gfx D_8012AC00[] = {
|
|
||||||
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_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2),
|
|
||||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
|
||||||
gsDPPipeSync(),
|
|
||||||
gsDPSetBlendColor(0, 0, 0, 8),
|
|
||||||
gsSPEndDisplayList(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Gfx D_8012AC28[] = {
|
|
||||||
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_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
|
||||||
GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM) |
|
|
||||||
GBL_c2(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM)),
|
|
||||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
|
||||||
gsSPEndDisplayList(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Gfx D_8012AC40[] = {
|
|
||||||
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_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
|
||||||
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
|
|
||||||
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
|
|
||||||
|
|
||||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
|
||||||
gsSPEndDisplayList(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Gfx D_8012AC58[] = {
|
|
||||||
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 |
|
|
||||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
|
||||||
G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2),
|
|
||||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
|
||||||
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_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
|
||||||
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
|
|
||||||
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
|
|
||||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
|
||||||
gsSPEndDisplayList(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Init
|
|
||||||
void func_800ACE70(struct_801664F0* this) {
|
|
||||||
this->type = 0;
|
|
||||||
this->setScissor = false;
|
|
||||||
this->color.r = 255;
|
|
||||||
this->color.g = 255;
|
|
||||||
this->color.b = 255;
|
|
||||||
this->color.a = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy
|
|
||||||
void func_800ACE90(struct_801664F0* this) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw
|
|
||||||
void func_800ACE98(struct_801664F0* this, Gfx** gfxp) {
|
|
||||||
Gfx* gfx = *gfxp;
|
|
||||||
|
|
||||||
gDPPipeSync(gfx++);
|
|
||||||
gDPSetPrimDepth(gfx++, -1, -1);
|
|
||||||
|
|
||||||
if (this->setScissor == true) {
|
|
||||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (this->type) {
|
|
||||||
case 1:
|
|
||||||
gSPDisplayList(gfx++, D_8012AC40);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->color.rgba);
|
|
||||||
gSPDisplayList(gfx++, D_8012AC58);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gDPSetColor(gfx++, G_SETBLENDCOLOR, this->color.rgba);
|
|
||||||
gSPDisplayList(gfx++, D_8012AC00);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
gDPSetColor(gfx++, G_SETFOGCOLOR, this->color.rgba);
|
|
||||||
gSPDisplayList(gfx++, D_8012AC28);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gDPPipeSync(gfx++);
|
|
||||||
*gfxp = gfx;
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
|
|
||||||
// Note : This file is related to z_vismono, the original name was probably z_vis<something after "mono" alphabetically>
|
|
||||||
|
|
||||||
// z-buffer
|
|
||||||
extern u16 D_0E000000[];
|
|
||||||
|
|
||||||
// Init
|
|
||||||
void func_800AD920(struct_80166500* this) {
|
|
||||||
this->useRgba = false;
|
|
||||||
this->setScissor = false;
|
|
||||||
this->primColor.r = 255;
|
|
||||||
this->primColor.g = 255;
|
|
||||||
this->primColor.b = 255;
|
|
||||||
this->primColor.a = 255;
|
|
||||||
this->envColor.a = 255;
|
|
||||||
this->envColor.r = 0;
|
|
||||||
this->envColor.g = 0;
|
|
||||||
this->envColor.b = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy
|
|
||||||
void func_800AD950(struct_80166500* this) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw
|
|
||||||
void func_800AD958(struct_80166500* this, Gfx** gfxp) {
|
|
||||||
Gfx* gfx = *gfxp;
|
|
||||||
|
|
||||||
// OTRTODO
|
|
||||||
#if 0
|
|
||||||
u16* tex = D_0E000000;
|
|
||||||
s32 fmt = this->useRgba == false ? G_IM_FMT_IA : G_IM_FMT_RGBA;
|
|
||||||
s32 y;
|
|
||||||
s32 height = 6;
|
|
||||||
|
|
||||||
gDPPipeSync(gfx++);
|
|
||||||
if (this->setScissor == true) {
|
|
||||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
gDPSetOtherMode(gfx++,
|
|
||||||
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_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2);
|
|
||||||
gDPSetCombineLERP(gfx++, 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_SETENVCOLOR, this->envColor.rgba);
|
|
||||||
|
|
||||||
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
|
|
||||||
gDPLoadTextureBlock(gfx++, tex, fmt, G_IM_SIZ_16b, SCREEN_WIDTH, 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);
|
|
||||||
|
|
||||||
gSPTextureRectangle(gfx++, 0, (y) << 2, (SCREEN_WIDTH << 2), (y + height) << 2, G_TX_RENDERTILE, 0, 0,
|
|
||||||
(1 << 10), (1 << 10));
|
|
||||||
tex += SCREEN_WIDTH * height;
|
|
||||||
}
|
|
||||||
|
|
||||||
gDPPipeSync(gfx++);
|
|
||||||
*gfxp = gfx;
|
|
||||||
#endif
|
|
||||||
}
|
|
@ -6,9 +6,9 @@
|
|||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
|
||||||
SpeedMeter D_801664D0;
|
SpeedMeter D_801664D0;
|
||||||
struct_801664F0 D_801664F0;
|
VisCvg sVisCvg;
|
||||||
struct_80166500 D_80166500;
|
VisZBuf sVisZBuf;
|
||||||
VisMono sMonoColors;
|
VisMono sVisMono;
|
||||||
ViMode sViMode;
|
ViMode sViMode;
|
||||||
FaultClient sGameFaultClient;
|
FaultClient sGameFaultClient;
|
||||||
u16 sLastButtonPressed;
|
u16 sLastButtonPressed;
|
||||||
@ -31,41 +31,43 @@ void GameState_FaultPrint(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState_SetFBFilter(Gfx** gfx) {
|
void GameState_SetFBFilter(Gfx** gfxP) {
|
||||||
Gfx* gfxP;
|
Gfx* gfx = *gfxP;
|
||||||
gfxP = *gfx;
|
|
||||||
|
|
||||||
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)) {
|
||||||
D_801664F0.type = R_FB_FILTER_TYPE;
|
// Visualize coverage
|
||||||
D_801664F0.color.r = R_FB_FILTER_PRIM_COLOR(0);
|
sVisCvg.vis.type = FB_FILTER_TO_CVG_TYPE(R_FB_FILTER_TYPE);
|
||||||
D_801664F0.color.g = R_FB_FILTER_PRIM_COLOR(1);
|
sVisCvg.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||||
D_801664F0.color.b = R_FB_FILTER_PRIM_COLOR(2);
|
sVisCvg.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||||
D_801664F0.color.a = R_FB_FILTER_A;
|
sVisCvg.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||||
func_800ACE98(&D_801664F0, &gfxP);
|
sVisCvg.vis.primColor.a = R_FB_FILTER_A;
|
||||||
} else if ((R_FB_FILTER_TYPE == 5) || (R_FB_FILTER_TYPE == 6)) {
|
VisCvg_Draw(&sVisCvg, &gfx);
|
||||||
D_80166500.useRgba = (R_FB_FILTER_TYPE == 6);
|
} else if ((R_FB_FILTER_TYPE == FB_FILTER_ZBUF_IA) || (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA)) {
|
||||||
D_80166500.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
// Visualize z-buffer
|
||||||
D_80166500.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
sVisZBuf.vis.type = (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA);
|
||||||
D_80166500.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
sVisZBuf.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||||
D_80166500.primColor.a = R_FB_FILTER_A;
|
sVisZBuf.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||||
D_80166500.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
sVisZBuf.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||||
D_80166500.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
sVisZBuf.vis.primColor.a = R_FB_FILTER_A;
|
||||||
D_80166500.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
sVisZBuf.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
||||||
D_80166500.envColor.a = R_FB_FILTER_A;
|
sVisZBuf.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
||||||
func_800AD958(&D_80166500, &gfxP);
|
sVisZBuf.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
||||||
} else if (R_FB_FILTER_TYPE == 7) {
|
sVisZBuf.vis.envColor.a = R_FB_FILTER_A;
|
||||||
sMonoColors.unk_00 = 0;
|
VisZBuf_Draw(&sVisZBuf, &gfx);
|
||||||
sMonoColors.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
} else if (R_FB_FILTER_TYPE == FB_FILTER_MONO) {
|
||||||
sMonoColors.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
// Monochrome filter
|
||||||
sMonoColors.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
sVisMono.vis.type = 0;
|
||||||
sMonoColors.primColor.a = R_FB_FILTER_A;
|
sVisMono.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||||
sMonoColors.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
sVisMono.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||||
sMonoColors.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
sVisMono.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||||
sMonoColors.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
sVisMono.vis.primColor.a = R_FB_FILTER_A;
|
||||||
sMonoColors.envColor.a = R_FB_FILTER_A;
|
sVisMono.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
||||||
VisMono_Draw(&sMonoColors, &gfxP);
|
sVisMono.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
||||||
|
sVisMono.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
||||||
|
sVisMono.vis.envColor.a = R_FB_FILTER_A;
|
||||||
|
VisMono_Draw(&sVisMono, &gfx);
|
||||||
}
|
}
|
||||||
*gfx = gfxP;
|
*gfxP = gfx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_800C4344(GameState* gameState) {
|
void func_800C4344(GameState* gameState) {
|
||||||
@ -420,9 +422,9 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
|
|||||||
|
|
||||||
startTime = endTime;
|
startTime = endTime;
|
||||||
LOG_CHECK_NULL_POINTER("this->cleanup", gameState->destroy);
|
LOG_CHECK_NULL_POINTER("this->cleanup", gameState->destroy);
|
||||||
func_800ACE70(&D_801664F0);
|
VisCvg_Init(&sVisCvg);
|
||||||
func_800AD920(&D_80166500);
|
VisZBuf_Init(&sVisZBuf);
|
||||||
VisMono_Init(&sMonoColors);
|
VisMono_Init(&sVisMono);
|
||||||
if (SREG(48) == 0) {
|
if (SREG(48) == 0) {
|
||||||
ViMode_Init(&sViMode);
|
ViMode_Init(&sViMode);
|
||||||
}
|
}
|
||||||
@ -450,9 +452,9 @@ void GameState_Destroy(GameState* gameState) {
|
|||||||
}
|
}
|
||||||
func_800AA0F0();
|
func_800AA0F0();
|
||||||
SpeedMeter_Destroy(&D_801664D0);
|
SpeedMeter_Destroy(&D_801664D0);
|
||||||
func_800ACE90(&D_801664F0);
|
VisCvg_Destroy(&sVisCvg);
|
||||||
func_800AD950(&D_80166500);
|
VisZBuf_Destroy(&sVisZBuf);
|
||||||
VisMono_Destroy(&sMonoColors);
|
VisMono_Destroy(&sVisMono);
|
||||||
if (SREG(48) == 0) {
|
if (SREG(48) == 0) {
|
||||||
ViMode_Destroy(&sViMode);
|
ViMode_Destroy(&sViMode);
|
||||||
}
|
}
|
||||||
|
@ -350,16 +350,16 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
|
|||||||
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
|
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
|
||||||
break;
|
break;
|
||||||
case 22:
|
case 22:
|
||||||
D_801614B0.r = 255;
|
gVisMonoColor.r = 255;
|
||||||
D_801614B0.g = 255;
|
gVisMonoColor.g = 255;
|
||||||
D_801614B0.b = 255;
|
gVisMonoColor.b = 255;
|
||||||
D_801614B0.a = 255;
|
gVisMonoColor.a = 255;
|
||||||
break;
|
break;
|
||||||
case 23:
|
case 23:
|
||||||
D_801614B0.r = 255;
|
gVisMonoColor.r = 255;
|
||||||
D_801614B0.g = 180;
|
gVisMonoColor.g = 180;
|
||||||
D_801614B0.b = 100;
|
gVisMonoColor.b = 100;
|
||||||
D_801614B0.a = 255.0f * temp;
|
gVisMonoColor.a = 255.0f * temp;
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
play->roomCtx.curRoom.segment = NULL;
|
play->roomCtx.curRoom.segment = NULL;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
TransitionUnk sTrnsnUnk;
|
TransitionUnk sTrnsnUnk;
|
||||||
s32 gTrnsnUnkState;
|
s32 gTrnsnUnkState;
|
||||||
VisMono gPlayVisMono;
|
VisMono gPlayVisMono;
|
||||||
Color_RGBA8_u32 D_801614B0;
|
Color_RGBA8_u32 gVisMonoColor;
|
||||||
|
|
||||||
FaultClient D_801614B8;
|
FaultClient D_801614B8;
|
||||||
|
|
||||||
@ -567,7 +567,7 @@ void Play_Init(GameState* thisx) {
|
|||||||
TransitionFade_SetColor(&play->transitionFade, RGBA8(160, 160, 160, 255));
|
TransitionFade_SetColor(&play->transitionFade, RGBA8(160, 160, 160, 255));
|
||||||
TransitionFade_Start(&play->transitionFade);
|
TransitionFade_Start(&play->transitionFade);
|
||||||
VisMono_Init(&gPlayVisMono);
|
VisMono_Init(&gPlayVisMono);
|
||||||
D_801614B0.a = 0;
|
gVisMonoColor.a = 0;
|
||||||
Flags_UnsetAllEnv(play);
|
Flags_UnsetAllEnv(play);
|
||||||
|
|
||||||
osSyncPrintf("ZELDA ALLOC SIZE=%x\n", THA_GetSize(&play->state.tha));
|
osSyncPrintf("ZELDA ALLOC SIZE=%x\n", THA_GetSize(&play->state.tha));
|
||||||
@ -1422,11 +1422,9 @@ void Play_Draw(PlayState* play) {
|
|||||||
|
|
||||||
TransitionFade_Draw(&play->transitionFade, &gfxP);
|
TransitionFade_Draw(&play->transitionFade, &gfxP);
|
||||||
|
|
||||||
if (D_801614B0.a > 0) {
|
if (gVisMonoColor.a > 0) {
|
||||||
// gPlayVisMono.vis.primColor.rgba = D_801614B0.rgba;
|
gPlayVisMono.vis.primColor.rgba = gVisMonoColor.rgba;
|
||||||
// VisMono_Draw(&gPlayVisMono, &gfxP);
|
VisMono_Draw(&gPlayVisMono, &gfxP);
|
||||||
gDPSetGrayscaleColor(gfxP++, D_801614B0.r, D_801614B0.g, D_801614B0.b, D_801614B0.a);
|
|
||||||
gSPGrayscale(gfxP++, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gSPEndDisplayList(gfxP++);
|
gSPEndDisplayList(gfxP++);
|
||||||
@ -1610,7 +1608,7 @@ void Play_Draw(PlayState* play) {
|
|||||||
play->unk_121C7 = 2;
|
play->unk_121C7 = 2;
|
||||||
SREG(33) |= 1;
|
SREG(33) |= 1;
|
||||||
|
|
||||||
// 2S2H [Port] Continue to render the post world for pausing to avoid flashing the HUD
|
// SOH [Port] Continue to render the post world for pausing to avoid flashing the HUD
|
||||||
if (gTrnsnUnkState == 2) {
|
if (gTrnsnUnkState == 2) {
|
||||||
goto Play_Draw_skip;
|
goto Play_Draw_skip;
|
||||||
}
|
}
|
||||||
|
145
soh/src/code/z_viscvg.c
Normal file
145
soh/src/code/z_viscvg.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/**
|
||||||
|
* @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 "global.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 |
|
||||||
|
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||||
|
G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2),
|
||||||
|
// (blendColor RGB) * (cvg)
|
||||||
|
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||||
|
gsDPPipeSync(),
|
||||||
|
gsDPSetBlendColor(0, 0, 0, 8),
|
||||||
|
gsSPEndDisplayList(),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 |
|
||||||
|
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 |
|
||||||
|
GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||||
|
GBL_c2(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||||
|
// (fog RGB) * (fog alpha) + (FB RGB) * (cvg)
|
||||||
|
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||||
|
gsSPEndDisplayList(),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 |
|
||||||
|
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 |
|
||||||
|
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||||
|
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||||
|
// (FB RGB) * (cvg)
|
||||||
|
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||||
|
gsSPEndDisplayList(),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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),
|
||||||
|
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_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2),
|
||||||
|
// stage 1 color = (primColor RGB) * (primColor Alpha) + (FB RGB) * (1 - primColor Alpha)
|
||||||
|
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||||
|
|
||||||
|
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_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
||||||
|
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||||
|
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||||
|
// final color = (stage 1 RGB) * (cvg)
|
||||||
|
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||||
|
gsSPEndDisplayList(),
|
||||||
|
};
|
||||||
|
|
||||||
|
void VisCvg_Init(VisCvg* this) {
|
||||||
|
this->vis.type = FB_FILTER_NONE;
|
||||||
|
this->vis.scissorType = VIS_NO_SETSCISSOR;
|
||||||
|
this->vis.primColor.r = 255;
|
||||||
|
this->vis.primColor.g = 255;
|
||||||
|
this->vis.primColor.b = 255;
|
||||||
|
this->vis.primColor.a = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisCvg_Destroy(VisCvg* this) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisCvg_Draw(VisCvg* this, Gfx** gfxP) {
|
||||||
|
Gfx* gfx = *gfxP;
|
||||||
|
|
||||||
|
gDPPipeSync(gfx++);
|
||||||
|
gDPSetPrimDepth(gfx++, 0xFFFF, 0xFFFF);
|
||||||
|
|
||||||
|
if (this->vis.scissorType == VIS_SETSCISSOR) {
|
||||||
|
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (this->vis.type) {
|
||||||
|
case FB_FILTER_CVG_RGB:
|
||||||
|
gSPDisplayList(gfx++, sCoverageRGBDL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FB_FILTER_CVG_RGB_UNIFORM:
|
||||||
|
// Set primitive color for uniform color filter in custom RenderMode
|
||||||
|
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
|
||||||
|
gSPDisplayList(gfx++, sCoverageRGBUniformDL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FB_FILTER_CVG_ONLY:
|
||||||
|
// Set background color for G_RM_VISCVG
|
||||||
|
gDPSetColor(gfx++, G_SETBLENDCOLOR, this->vis.primColor.rgba);
|
||||||
|
gSPDisplayList(gfx++, sCoverageOnlyDL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FB_FILTER_CVG_RGB_FOG:
|
||||||
|
// Set fog color for custom RenderMode, needs to be close to 0 to not overflow
|
||||||
|
gDPSetColor(gfx++, G_SETFOGCOLOR, this->vis.primColor.rgba);
|
||||||
|
gSPDisplayList(gfx++, sCoverageRGBFogDL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gDPPipeSync(gfx++);
|
||||||
|
*gfxP = gfx;
|
||||||
|
}
|
@ -1,137 +1,218 @@
|
|||||||
|
/**
|
||||||
|
* @file z_vismono.c
|
||||||
|
*
|
||||||
|
* 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 "global.h"
|
#include "global.h"
|
||||||
#include <string.h>
|
|
||||||
|
#include <string.h> // memset
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "soh/framebuffer_effects.h"
|
||||||
|
|
||||||
// (Note: 80 = SCREEN_HEIGHT/3, see VisMono_DrawTexture)
|
// Upstream TODO: Replace these ones they are served from other headers
|
||||||
// This may not have been kept up-to-date with the code, 1+1+1+80*(7+2+2+3)+1+1 makes more sense
|
#define ASSERT(cond, msg, file, line) assert(cond)
|
||||||
#define DLSIZE (1 + 3 + 1 + 1 + 80 * (7 + 2 + 2 + 3) + 1)
|
#define GPACK_IA16(i, a) (((i) << 8) | (a))
|
||||||
|
|
||||||
// framebuffer
|
// 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 dedicated to color-indexed data.
|
||||||
|
#define VISMONO_CFBFRAG_HEIGHT ((TMEM_SIZE / 2) / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES))
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// color framebuffer
|
||||||
extern u16 D_0F000000[];
|
extern u16 D_0F000000[];
|
||||||
|
|
||||||
void VisMono_Init(VisMono* this) {
|
void VisMono_Init(VisMono* this) {
|
||||||
memset(this, 0, sizeof(VisMono));
|
memset(this, 0, 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) {
|
||||||
SYSTEM_ARENA_FREE_DEBUG(this->monoDl);
|
SYSTEM_ARENA_FREE(this->dList, "../z_vismono.c", 137);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisMono_UpdateTexture(VisMono* this, u16* tex) {
|
void VisMono_DesaturateTLUT(VisMono* this, u16* tlut) {
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
tex[i] = ((((i >> 3 & 0x1F) * 2 + (i << 2 & 0x1F) * 4) * 0xFF / 0xD9) << 8) |
|
// `tlut[i]` is a IA16 color
|
||||||
(((i >> 6 & 0x1F) * 4 + (i >> 1 & 0x1F)) * 0xFF / 0xD9);
|
// `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_DrawTexture(VisMono* this, Gfx* gfx)
|
Gfx* VisMono_DesaturateDList(VisMono* this, Gfx* gfx) {
|
||||||
{
|
|
||||||
// OTRTODO
|
|
||||||
#if 1
|
|
||||||
s32 y;
|
s32 y;
|
||||||
s32 height = 3;
|
s32 height = VISMONO_CFBFRAG_HEIGHT;
|
||||||
//u16* tex = D_0F000000;
|
u16* cfbFrag = D_0F000000;
|
||||||
u16* tex = SEG_ADDR(0xF, 0);
|
|
||||||
|
|
||||||
gDPPipeSync(gfx++);
|
gDPPipeSync(gfx++);
|
||||||
|
// `G_TT_IA16`: use color-indexed images, and IA16 palettes
|
||||||
gDPSetOtherMode(gfx++,
|
gDPSetOtherMode(gfx++,
|
||||||
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_IA16 | G_TL_TILE |
|
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_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);
|
G_AC_NONE | G_ZS_PRIM | G_RM_PASS | 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,
|
gDPSetCombineLERP(gfx++, 1, 0, TEXEL1_ALPHA, TEXEL0, 0, 0, 0, 1, PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, 0,
|
||||||
0, 0, PRIMITIVE);
|
0, 0, PRIMITIVE);
|
||||||
|
|
||||||
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
|
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
|
||||||
gDPLoadTextureBlock(gfx++, tex, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2, height, 0,
|
// 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_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, G_TX_NOLOD);
|
||||||
|
|
||||||
gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, 80, 0x0, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0,
|
// Set texel 0 to be a CI8 image with width `SCREEN_WIDTH * 2` and height `VISMONO_CFBFRAG_HEIGHT`
|
||||||
G_TX_NOMIRROR | G_TX_CLAMP, 0, 0);
|
// Its position in texture image space is shifted along +S by 2
|
||||||
gDPSetTileSize(gfx++, G_TX_RENDERTILE, (2 << 2), 0, ((SCREEN_WIDTH * 2 + 1) << 2), (2 << 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);
|
||||||
|
|
||||||
gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, 80, 0x0, 1, 1, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0,
|
// Set texel 1 to be a CI8 image with width `SCREEN_WIDTH * 2` and height `VISMONO_CFBFRAG_HEIGHT`
|
||||||
G_TX_NOMIRROR | G_TX_CLAMP, 0, 0);
|
// Its position in texture image space is shifted along +S by 1
|
||||||
gDPSetTileSize(gfx++, 1, (1 << 2), 0, ((SCREEN_WIDTH * 2) << 2), (2 << 2));
|
// 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,
|
||||||
|
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);
|
||||||
|
|
||||||
gSPTextureRectangle(gfx++, 0, y << 2, (SCREEN_WIDTH << 2), (y + height) << 2, G_TX_RENDERTILE, 2 << 5, 0,
|
// Draw a `SCREEN_WIDTH` wide, `height` high rectangle.
|
||||||
2 << 10, 1 << 10);
|
// Texture coordinate T (vertical) starts at 0 and changes by one each line (dtdy = 1)
|
||||||
tex += SCREEN_WIDTH * height;
|
// 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++);
|
gDPPipeSync(gfx++);
|
||||||
gSPEndDisplayList(gfx++);
|
gSPEndDisplayList(gfx++);
|
||||||
#endif
|
|
||||||
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* monoDL;
|
Gfx* dList;
|
||||||
Gfx* glistpEnd;
|
Gfx* dListEnd;
|
||||||
|
|
||||||
|
// SOH [Port] Implement VisMono by performing a framebuffer copy and redraw with an active
|
||||||
|
// grayscale command to set the mono color
|
||||||
|
FB_CopyToFramebuffer(&gfx, 0, gReusableFrameBuffer, false, NULL);
|
||||||
|
gDPSetGrayscaleColor(gfx++, this->vis.primColor.r, this->vis.primColor.g, this->vis.primColor.b,
|
||||||
|
this->vis.primColor.a);
|
||||||
|
gSPGrayscale(gfx++, true);
|
||||||
|
FB_DrawFromFramebuffer(&gfx, gReusableFrameBuffer, 255);
|
||||||
|
gSPGrayscale(gfx++, false);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (this->tlut) {
|
if (this->tlut) {
|
||||||
tlut = this->tlut;
|
tlut = this->tlut;
|
||||||
} else {
|
} else {
|
||||||
tlut = Graph_DlistAlloc(&gfx, 256 * sizeof(u16));
|
tlut = Graph_DlistAlloc(&gfx, 256 * G_IM_SIZ_16b_BYTES);
|
||||||
VisMono_UpdateTexture(this, tlut);
|
VisMono_DesaturateTLUT(this, tlut);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->monoDl) {
|
if (this->dList) {
|
||||||
monoDL = this->monoDl;
|
dList = this->dList;
|
||||||
} else {
|
} else {
|
||||||
monoDL = Graph_DlistAlloc(&gfx, DLSIZE * sizeof(Gfx));
|
dList = Graph_DlistAlloc(&gfx, VISMONO_DLSIZE * sizeof(Gfx));
|
||||||
glistpEnd = VisMono_DrawTexture(this, monoDL);
|
dListEnd = VisMono_DesaturateDList(this, dList);
|
||||||
|
|
||||||
if (!(glistpEnd <= monoDL + DLSIZE)) {
|
if (!(dListEnd <= dList + VISMONO_DLSIZE)) {
|
||||||
LOG_ADDRESS("glistp_end", glistpEnd);
|
LOG_ADDRESS("glistp_end", dListEnd);
|
||||||
LOG_ADDRESS("mono_dl", monoDL);
|
LOG_ADDRESS("mono_dl", dList);
|
||||||
LOG_ADDRESS("mono_dl + (1+3+1+1+80*(7+2+2+3)+1)", monoDL + DLSIZE);
|
LOG_ADDRESS("mono_dl + (1+3+1+1+80*(7+2+2+3)+1)", dList + VISMONO_DLSIZE);
|
||||||
LOG_ADDRESS("(1+3+1+1+80*(7+2+2+3)+1)", DLSIZE);
|
LOG_ADDRESS("(1+3+1+1+80*(7+2+2+3)+1)", VISMONO_DLSIZE);
|
||||||
}
|
}
|
||||||
assert(glistpEnd <= monoDL + DLSIZE);
|
ASSERT(dListEnd <= dList + VISMONO_DLSIZE, "glistp_end <= mono_dl + DLSIZE", "../z_vismono.c", 262);
|
||||||
}
|
}
|
||||||
|
|
||||||
gDPPipeSync(gfx++);
|
gDPPipeSync(gfx++);
|
||||||
if (this->setScissor == true) {
|
|
||||||
|
if (this->vis.scissorType == VIS_SETSCISSOR) {
|
||||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
gSPDisplayList(gfx++, monoDL);
|
gSPDisplayList(gfx++, dList);
|
||||||
gDPPipeSync(gfx++);
|
|
||||||
|
|
||||||
*gfxp = gfx;
|
gDPPipeSync(gfx++);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*gfxP = gfx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisMono_DrawOld(VisMono* this) {
|
void VisMono_DrawOld(VisMono* this) {
|
||||||
Gfx* glistpEnd;
|
Gfx* dListEnd;
|
||||||
|
|
||||||
if (!this->tlut) {
|
if (this->tlut == NULL) {
|
||||||
this->tlut = SYSTEM_ARENA_MALLOC_DEBUG(256 * sizeof(u16));
|
this->tlut = SYSTEM_ARENA_MALLOC(256 * G_IM_SIZ_16b_BYTES, "../z_vismono.c", 283);
|
||||||
VisMono_UpdateTexture(this, this->tlut);
|
VisMono_DesaturateTLUT(this, this->tlut);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->monoDl) {
|
if (this->dList == NULL) {
|
||||||
this->monoDl = SYSTEM_ARENA_MALLOC_DEBUG(DLSIZE * sizeof(Gfx));
|
this->dList = SYSTEM_ARENA_MALLOC(VISMONO_DLSIZE * sizeof(Gfx), "../z_vismono.c", 289);
|
||||||
glistpEnd = VisMono_DrawTexture(this, this->monoDl);
|
dListEnd = VisMono_DesaturateDList(this, this->dList);
|
||||||
assert(glistpEnd <= this->monoDl + DLSIZE);
|
ASSERT(dListEnd <= this->dList + VISMONO_DLSIZE, "glistp_end <= this->mono_dl + DLSIZE", "../z_vismono.c", 292);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
116
soh/src/code/z_viszbuf.c
Normal file
116
soh/src/code/z_viszbuf.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* @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 "global.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 / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES))
|
||||||
|
|
||||||
|
// z-buffer
|
||||||
|
extern u16 D_0E000000[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise to IA type with white and black as default colors.
|
||||||
|
*/
|
||||||
|
void VisZBuf_Init(VisZBuf* this) {
|
||||||
|
this->vis.type = VIS_ZBUF_TYPE_IA;
|
||||||
|
this->vis.scissorType = VIS_NO_SETSCISSOR;
|
||||||
|
|
||||||
|
this->vis.primColor.r = 255;
|
||||||
|
this->vis.primColor.g = 255;
|
||||||
|
this->vis.primColor.b = 255;
|
||||||
|
this->vis.primColor.a = 255;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
this->vis.envColor.r = 0; \
|
||||||
|
this->vis.envColor.g = 0; \
|
||||||
|
this->vis.envColor.b = 0; \
|
||||||
|
this->vis.envColor.a = 255;
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisZBuf_Destroy(VisZBuf* this) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisZBuf_Draw(VisZBuf* this, Gfx** gfxP) {
|
||||||
|
Gfx* gfx = *gfxP;
|
||||||
|
s32 pad;
|
||||||
|
u16* zbufFrag = D_0E000000;
|
||||||
|
s32 fmt;
|
||||||
|
s32 y;
|
||||||
|
s32 height;
|
||||||
|
|
||||||
|
if (this->vis.type == VIS_ZBUF_TYPE_IA) {
|
||||||
|
fmt = G_IM_FMT_IA;
|
||||||
|
} else { // VIS_ZBUF_TYPE_RGBA
|
||||||
|
fmt = G_IM_FMT_RGBA;
|
||||||
|
}
|
||||||
|
|
||||||
|
height = VISZBUF_ZBUFFRAG_HEIGHT;
|
||||||
|
|
||||||
|
gDPPipeSync(gfx++);
|
||||||
|
// Scissoring is only required if the scissor has not been set prior.
|
||||||
|
if (this->vis.scissorType == VIS_SETSCISSOR) {
|
||||||
|
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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++,
|
||||||
|
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_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,
|
||||||
|
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT);
|
||||||
|
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
|
||||||
|
gDPSetColor(gfx++, G_SETENVCOLOR, this->vis.envColor.rgba);
|
||||||
|
|
||||||
|
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
|
||||||
|
// Load a few lines of the z-buffer, as many as can fit in TMEM at once.
|
||||||
|
gDPLoadTextureBlock(gfx++, zbufFrag, fmt, G_IM_SIZ_16b, SCREEN_WIDTH, 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);
|
||||||
|
|
||||||
|
// Overwrite them with the calculated colors.
|
||||||
|
gSPTextureRectangle(gfx++, 0, y << 2, SCREEN_WIDTH << 2, (y + height) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
|
||||||
|
1 << 10);
|
||||||
|
zbufFrag += SCREEN_WIDTH * height;
|
||||||
|
}
|
||||||
|
|
||||||
|
gDPPipeSync(gfx++);
|
||||||
|
*gfxP = gfx;
|
||||||
|
}
|
@ -196,10 +196,10 @@ void BgHaka_Draw(Actor* thisx, PlayState* play) {
|
|||||||
play->envCtx.adjLight1Color[0] = newColor.r;
|
play->envCtx.adjLight1Color[0] = newColor.r;
|
||||||
play->envCtx.adjLight1Color[1] = newColor.g;
|
play->envCtx.adjLight1Color[1] = newColor.g;
|
||||||
play->envCtx.adjLight1Color[2] = newColor.b;
|
play->envCtx.adjLight1Color[2] = newColor.b;
|
||||||
D_801614B0.r = newColor.r;
|
gVisMonoColor.r = newColor.r;
|
||||||
D_801614B0.g = newColor.g;
|
gVisMonoColor.g = newColor.g;
|
||||||
D_801614B0.b = newColor.b;
|
gVisMonoColor.b = newColor.b;
|
||||||
D_801614B0.a = 255;
|
gVisMonoColor.a = 255;
|
||||||
gDPSetGrayscaleColor(POLY_OPA_DISP++, newColor.r, newColor.g, newColor.b, 255);
|
gDPSetGrayscaleColor(POLY_OPA_DISP++, newColor.r, newColor.g, newColor.b, 255);
|
||||||
gSPGrayscale(POLY_OPA_DISP++, true);
|
gSPGrayscale(POLY_OPA_DISP++, true);
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,6 @@ void EndTitle_DrawFull(Actor* thisx, PlayState* play) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OVERLAY_DISP = Gfx_SetupDL_64(OVERLAY_DISP);
|
OVERLAY_DISP = Gfx_SetupDL_64(OVERLAY_DISP);
|
||||||
if (D_801614B0.a > 0)
|
|
||||||
gSPGrayscale(OVERLAY_DISP++, false);
|
|
||||||
gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE);
|
gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE);
|
||||||
gDPSetEnvColor(OVERLAY_DISP++, 255, 120, 30, 0);
|
gDPSetEnvColor(OVERLAY_DISP++, 255, 120, 30, 0);
|
||||||
gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2);
|
gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2);
|
||||||
@ -110,8 +108,6 @@ void EndTitle_DrawFull(Actor* thisx, PlayState* play) {
|
|||||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
|
||||||
gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
|
gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
|
||||||
1 << 10);
|
1 << 10);
|
||||||
if (D_801614B0.a > 0)
|
|
||||||
gSPGrayscale(OVERLAY_DISP++, true);
|
|
||||||
CLOSE_DISPS(play->state.gfxCtx);
|
CLOSE_DISPS(play->state.gfxCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,8 +293,6 @@ void Title_Init(GameState* thisx) {
|
|||||||
|
|
||||||
//ResourceMgr_LoadDirectory("nintendo_rogo_static*");
|
//ResourceMgr_LoadDirectory("nintendo_rogo_static*");
|
||||||
|
|
||||||
// Disable vismono
|
|
||||||
D_801614B0.a = 0;
|
|
||||||
R_UPDATE_RATE = 1;
|
R_UPDATE_RATE = 1;
|
||||||
Matrix_Init(&this->state);
|
Matrix_Init(&this->state);
|
||||||
View_Init(&this->view, this->state.gfxCtx);
|
View_Init(&this->view, this->state.gfxCtx);
|
||||||
|
Loading…
Reference in New Issue
Block a user