mirror of
https://github.com/zeldaret/oot
synced 2026-09-02 01:52:35 -04:00
[cc0 oot] z_vis* (#2782)
* [cc0 oot] z_vis* * bss * docs * fixup * further vis docs * add FbFilterType enum * bss * gfxP
This commit is contained in:
+2
-2
@@ -68,9 +68,9 @@ struct PlayState;
|
||||
#define R_VI_MODE_EDIT_ULX_ADJ SREG(53)
|
||||
#define R_VI_MODE_EDIT_LRX_ADJ SREG(54)
|
||||
#define R_FB_FILTER_TYPE SREG(80)
|
||||
#define R_FB_FILTER_PRIM_COLOR(c) SREG(81 + (c))
|
||||
#define R_FB_FILTER_COLOR1(c) SREG(81 + (c))
|
||||
#define R_FB_FILTER_A SREG(84)
|
||||
#define R_FB_FILTER_ENV_COLOR(c) SREG(85 + (c))
|
||||
#define R_FB_FILTER_COLOR2(c) SREG(85 + (c))
|
||||
#define R_ENABLE_FB_FILTER SREG(88)
|
||||
#define R_PAUSE_BG_PRERENDER_STATE SREG(94) // `PauseBgPreRenderState`
|
||||
#define R_CAM_XZ_OFFSET_UPDATE_RATE OREG(2)
|
||||
|
||||
+40
-59
@@ -4,81 +4,62 @@
|
||||
#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 FbFilterType {
|
||||
/* 0 */ FB_FILTER_TYPE_NONE,
|
||||
/* 1 */ FB_FILTER_TYPE_VISCVG_TYPE_MODULATE_FB,
|
||||
/* 2 */ FB_FILTER_TYPE_VISCVG_TYPE_FADE_AND_MODULATE_FB,
|
||||
/* 3 */ FB_FILTER_TYPE_VISCVG_TYPE_MODULATE_COLOR,
|
||||
/* 4 */ FB_FILTER_TYPE_VISCVG_TYPE_MODULATE_FB_ADDITIVE_COLOR,
|
||||
/* 5 */ FB_FILTER_TYPE_VISZBUFFER_AS_IA16,
|
||||
/* 6 */ FB_FILTER_TYPE_VISZBUFFER_AS_RGBA16,
|
||||
/* 7 */ FB_FILTER_TYPE_VISMONO
|
||||
} FbFilterType;
|
||||
|
||||
typedef enum VisScissorType {
|
||||
/* 0 */ VIS_NO_SETSCISSOR,
|
||||
/* 1 */ VIS_SETSCISSOR
|
||||
} VisScissorType;
|
||||
|
||||
typedef struct Vis {
|
||||
/**
|
||||
* Meaning of color1 and color2:
|
||||
* - VisCvg: see VisCvgType for color1. color2 unused
|
||||
* - VisMono: LERP endpoints. See z_vismono.c file comment
|
||||
* - VisZBuffer: LERP endpoints. See z_viszbuffer.c file comment
|
||||
*/
|
||||
typedef struct VisParams {
|
||||
/* 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)
|
||||
/* 0x04 */ u32 setScissor;
|
||||
/* 0x08 */ Color_RGBA8_u32 color1;
|
||||
/* 0x0C */ Color_RGBA8_u32 color2;
|
||||
} VisParams; // size = 0x10
|
||||
|
||||
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)
|
||||
VISCVG_TYPE_NOP,
|
||||
VISCVG_TYPE_MODULATE_FB, // Multiply coverage with framebuffer
|
||||
VISCVG_TYPE_FADE_AND_MODULATE_FB, // Also fade to color1 by color1.a
|
||||
VISCVG_TYPE_MODULATE_COLOR, // Multiply coverage with color1
|
||||
VISCVG_TYPE_MODULATE_FB_ADDITIVE_COLOR // Add color1
|
||||
} VisCvgType;
|
||||
|
||||
typedef struct VisCvg {
|
||||
/* 0x00 */ Vis vis;
|
||||
/* 0x00 */ VisParams params; // params.color2 unused
|
||||
} VisCvg; // size = 0x10
|
||||
|
||||
typedef struct VisMono {
|
||||
/* 0x00 */ VisParams params; // params.type unused
|
||||
/* 0x10 */ u16* tlut;
|
||||
/* 0x14 */ Gfx* dList;
|
||||
} VisMono; // size = 0x18
|
||||
|
||||
typedef struct VisZBuffer {
|
||||
/* 0x00 */ VisParams params;
|
||||
} VisZBuffer; // 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);
|
||||
void VisZBuffer_Init(VisZBuffer* this);
|
||||
void VisZBuffer_Destroy(VisZBuffer* this);
|
||||
void VisZBuffer_Draw(VisZBuffer* this, Gfx** gfxP);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -598,7 +598,7 @@ beginseg
|
||||
include "$(BUILD_DIR)/src/code/z_vimode.o"
|
||||
include "$(BUILD_DIR)/src/code/z_viscvg.o"
|
||||
include "$(BUILD_DIR)/src/code/z_vismono.o"
|
||||
include "$(BUILD_DIR)/src/code/z_viszbuf.o"
|
||||
include "$(BUILD_DIR)/src/code/z_viszbuffer.o"
|
||||
include "$(BUILD_DIR)/src/code/z_vr_box.o"
|
||||
include "$(BUILD_DIR)/src/code/z_vr_box_draw.o"
|
||||
include "$(BUILD_DIR)/src/code/z_player_call.o"
|
||||
|
||||
+40
-41
@@ -35,9 +35,9 @@
|
||||
#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0"
|
||||
|
||||
SpeedMeter D_801664D0;
|
||||
VisCvg sVisCvg;
|
||||
VisZBuf sVisZBuf;
|
||||
VisMono sVisMono;
|
||||
VisCvg sGameStateVisCvg;
|
||||
VisZBuffer sGameStateVisZBuffer;
|
||||
VisMono sGameStateVisMono;
|
||||
ViMode sViMode;
|
||||
|
||||
#if DEBUG_FEATURES
|
||||
@@ -61,38 +61,37 @@ void GameState_FaultPrint(void) {
|
||||
void GameState_SetFBFilter(Gfx** gfxP) {
|
||||
Gfx* gfx = *gfxP;
|
||||
|
||||
if ((R_FB_FILTER_TYPE >= FB_FILTER_CVG_RGB) && (R_FB_FILTER_TYPE <= FB_FILTER_CVG_RGB_FOG)) {
|
||||
// Visualize coverage
|
||||
sVisCvg.vis.type = FB_FILTER_TO_CVG_TYPE(R_FB_FILTER_TYPE);
|
||||
sVisCvg.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
sVisCvg.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
sVisCvg.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
sVisCvg.vis.primColor.a = R_FB_FILTER_A;
|
||||
VisCvg_Draw(&sVisCvg, &gfx);
|
||||
} else if ((R_FB_FILTER_TYPE == FB_FILTER_ZBUF_IA) || (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA)) {
|
||||
// Visualize z-buffer
|
||||
sVisZBuf.vis.type = (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA);
|
||||
sVisZBuf.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
sVisZBuf.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
sVisZBuf.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
sVisZBuf.vis.primColor.a = R_FB_FILTER_A;
|
||||
sVisZBuf.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
||||
sVisZBuf.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
||||
sVisZBuf.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
||||
sVisZBuf.vis.envColor.a = R_FB_FILTER_A;
|
||||
VisZBuf_Draw(&sVisZBuf, &gfx);
|
||||
} else if (R_FB_FILTER_TYPE == FB_FILTER_MONO) {
|
||||
// Monochrome filter
|
||||
sVisMono.vis.type = 0;
|
||||
sVisMono.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
sVisMono.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
sVisMono.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
sVisMono.vis.primColor.a = R_FB_FILTER_A;
|
||||
sVisMono.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
||||
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);
|
||||
if ((R_FB_FILTER_TYPE >= FB_FILTER_TYPE_VISCVG_TYPE_MODULATE_FB) &&
|
||||
(R_FB_FILTER_TYPE <= FB_FILTER_TYPE_VISCVG_TYPE_MODULATE_FB_ADDITIVE_COLOR)) {
|
||||
sGameStateVisCvg.params.type = R_FB_FILTER_TYPE;
|
||||
sGameStateVisCvg.params.color1.r = R_FB_FILTER_COLOR1(0);
|
||||
sGameStateVisCvg.params.color1.g = R_FB_FILTER_COLOR1(1);
|
||||
sGameStateVisCvg.params.color1.b = R_FB_FILTER_COLOR1(2);
|
||||
sGameStateVisCvg.params.color1.a = R_FB_FILTER_A;
|
||||
VisCvg_Draw(&sGameStateVisCvg, &gfx);
|
||||
} else if ((R_FB_FILTER_TYPE == FB_FILTER_TYPE_VISZBUFFER_AS_IA16) ||
|
||||
(R_FB_FILTER_TYPE == FB_FILTER_TYPE_VISZBUFFER_AS_RGBA16)) {
|
||||
sGameStateVisZBuffer.params.type = (R_FB_FILTER_TYPE == FB_FILTER_TYPE_VISZBUFFER_AS_RGBA16);
|
||||
sGameStateVisZBuffer.params.color1.r = R_FB_FILTER_COLOR1(0);
|
||||
sGameStateVisZBuffer.params.color1.g = R_FB_FILTER_COLOR1(1);
|
||||
sGameStateVisZBuffer.params.color1.b = R_FB_FILTER_COLOR1(2);
|
||||
sGameStateVisZBuffer.params.color1.a = R_FB_FILTER_A;
|
||||
sGameStateVisZBuffer.params.color2.r = R_FB_FILTER_COLOR2(0);
|
||||
sGameStateVisZBuffer.params.color2.g = R_FB_FILTER_COLOR2(1);
|
||||
sGameStateVisZBuffer.params.color2.b = R_FB_FILTER_COLOR2(2);
|
||||
sGameStateVisZBuffer.params.color2.a = R_FB_FILTER_A;
|
||||
VisZBuffer_Draw(&sGameStateVisZBuffer, &gfx);
|
||||
} else if (R_FB_FILTER_TYPE == FB_FILTER_TYPE_VISMONO) {
|
||||
sGameStateVisMono.params.type = 0;
|
||||
sGameStateVisMono.params.color1.r = R_FB_FILTER_COLOR1(0);
|
||||
sGameStateVisMono.params.color1.g = R_FB_FILTER_COLOR1(1);
|
||||
sGameStateVisMono.params.color1.b = R_FB_FILTER_COLOR1(2);
|
||||
sGameStateVisMono.params.color1.a = R_FB_FILTER_A;
|
||||
sGameStateVisMono.params.color2.r = R_FB_FILTER_COLOR2(0);
|
||||
sGameStateVisMono.params.color2.g = R_FB_FILTER_COLOR2(1);
|
||||
sGameStateVisMono.params.color2.b = R_FB_FILTER_COLOR2(2);
|
||||
sGameStateVisMono.params.color2.a = R_FB_FILTER_A;
|
||||
VisMono_Draw(&sGameStateVisMono, &gfx);
|
||||
}
|
||||
*gfxP = gfx;
|
||||
}
|
||||
@@ -498,9 +497,9 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
|
||||
|
||||
startTime = endTime;
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this->cleanup", gameState->destroy, "../game.c", 1088);
|
||||
VisCvg_Init(&sVisCvg);
|
||||
VisZBuf_Init(&sVisZBuf);
|
||||
VisMono_Init(&sVisMono);
|
||||
VisCvg_Init(&sGameStateVisCvg);
|
||||
VisZBuffer_Init(&sGameStateVisZBuffer);
|
||||
VisMono_Init(&sGameStateVisMono);
|
||||
if ((R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) || !DEBUG_FEATURES) {
|
||||
ViMode_Init(&sViMode);
|
||||
}
|
||||
@@ -529,9 +528,9 @@ void GameState_Destroy(GameState* gameState) {
|
||||
}
|
||||
Rumble_Destroy();
|
||||
SpeedMeter_Destroy(&D_801664D0);
|
||||
VisCvg_Destroy(&sVisCvg);
|
||||
VisZBuf_Destroy(&sVisZBuf);
|
||||
VisMono_Destroy(&sVisMono);
|
||||
VisCvg_Destroy(&sGameStateVisCvg);
|
||||
VisZBuffer_Destroy(&sGameStateVisZBuffer);
|
||||
VisMono_Destroy(&sGameStateVisMono);
|
||||
if ((R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) || !DEBUG_FEATURES) {
|
||||
ViMode_Destroy(&sViMode);
|
||||
}
|
||||
|
||||
+7
-7
@@ -47,12 +47,12 @@
|
||||
#include "save.h"
|
||||
#include "vis.h"
|
||||
|
||||
#pragma increment_block_number "gc-eu:224 gc-eu-mq:224 gc-jp:224 gc-jp-ce:224 gc-jp-mq:224 gc-us:224 gc-us-mq:224" \
|
||||
"ique-cn:224 ntsc-1.0:240 ntsc-1.1:240 ntsc-1.2:240 pal-1.0:240 pal-1.1:240"
|
||||
#pragma increment_block_number "gc-eu:218 gc-eu-mq:218 gc-jp:218 gc-jp-ce:218 gc-jp-mq:218 gc-us:218 gc-us-mq:218" \
|
||||
"ique-cn:218 ntsc-1.0:218 ntsc-1.1:218 ntsc-1.2:218 pal-1.0:218 pal-1.1:218"
|
||||
|
||||
TransitionTile gTransitionTile;
|
||||
s32 gTransitionTileState;
|
||||
VisMono gPlayVisMono;
|
||||
VisMono sPlayVisMono;
|
||||
Color_RGBA8_u32 gVisMonoColor;
|
||||
|
||||
#if DEBUG_FEATURES
|
||||
@@ -261,7 +261,7 @@ void Play_Destroy(GameState* thisx) {
|
||||
|
||||
Letterbox_Destroy();
|
||||
TransitionFade_Destroy(&this->transitionFadeFlash);
|
||||
VisMono_Destroy(&gPlayVisMono);
|
||||
VisMono_Destroy(&sPlayVisMono);
|
||||
|
||||
if (gSaveContext.save.linkAge != this->linkAgeOnLoad) {
|
||||
Inventory_SwapAgeEquipment();
|
||||
@@ -482,7 +482,7 @@ void Play_Init(GameState* thisx) {
|
||||
TransitionFade_SetType(&this->transitionFadeFlash, TRANS_INSTANCE_TYPE_FADE_FLASH);
|
||||
TransitionFade_SetColor(&this->transitionFadeFlash, RGBA8(160, 160, 160, 255));
|
||||
TransitionFade_Start(&this->transitionFadeFlash);
|
||||
VisMono_Init(&gPlayVisMono);
|
||||
VisMono_Init(&sPlayVisMono);
|
||||
gVisMonoColor.a = 0;
|
||||
CutsceneFlags_UnsetAll(this);
|
||||
|
||||
@@ -1217,8 +1217,8 @@ void Play_Draw(PlayState* this) {
|
||||
if (gVisMonoColor.a > 0)
|
||||
#endif
|
||||
{
|
||||
gPlayVisMono.vis.primColor.rgba = gVisMonoColor.rgba;
|
||||
VisMono_Draw(&gPlayVisMono, &gfxP);
|
||||
sPlayVisMono.params.color1.rgba = gVisMonoColor.rgba;
|
||||
VisMono_Draw(&sPlayVisMono, &gfxP);
|
||||
}
|
||||
|
||||
gSPEndDisplayList(gfxP++);
|
||||
|
||||
+34
-72
@@ -1,104 +1,71 @@
|
||||
/**
|
||||
* @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.
|
||||
* This file implements framebuffer effects relying on coverage.
|
||||
* Coverage's primary use is performing antialiasing: it basically tracks how much of a pixel is covered by its current
|
||||
* color. Coverage is stored in a rgba16 framebuffer as a 3 bits value.
|
||||
* Coverage is typically partial on geometry outer edges and full elsewhere: this makes the framebuffer effects here
|
||||
* usually highlight silhouettes.
|
||||
*/
|
||||
|
||||
#include "ultra64.h"
|
||||
#include "gfx.h"
|
||||
#include "vis.h"
|
||||
|
||||
/**
|
||||
* Draws only coverage: does not retain any of the original pixel RGB, primColor is used as background color.
|
||||
*/
|
||||
Gfx sCoverageOnlyDL[] = {
|
||||
Gfx sVisCvgModulateBlendColorDL[] = {
|
||||
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[] = {
|
||||
Gfx sVisCvgModulateFramebufferAdditiveFogDL[] = {
|
||||
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 |
|
||||
// Note: additive blending often overflows the blender, causing visual bugs
|
||||
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[] = {
|
||||
Gfx sVisCvgModulateFramebufferDL[] = {
|
||||
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[] = {
|
||||
Gfx sVisCvgFadeToPrimAndModulateFramebuffer[] = {
|
||||
// Fade the framebuffer towards prim color
|
||||
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,
|
||||
// Note: G_RM_CLD_SURF sets CVG_DST_SAVE which preserves coverage
|
||||
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),
|
||||
|
||||
// Like sVisCvgModulateFramebufferDL
|
||||
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;
|
||||
this->params.type = VISCVG_TYPE_NOP;
|
||||
this->params.setScissor = false;
|
||||
this->params.color1.r = 255;
|
||||
this->params.color1.g = 255;
|
||||
this->params.color1.b = 255;
|
||||
this->params.color1.a = 255;
|
||||
}
|
||||
|
||||
void VisCvg_Destroy(VisCvg* this) {
|
||||
@@ -108,36 +75,31 @@ void VisCvg_Draw(VisCvg* this, Gfx** gfxP) {
|
||||
Gfx* gfx = *gfxP;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
// Set full dz, see comment in PreRender_FetchFbufCoverage for details.
|
||||
gDPSetPrimDepth(gfx++, 0xFFFF, 0xFFFF);
|
||||
|
||||
if (this->vis.scissorType == VIS_SETSCISSOR) {
|
||||
if (this->params.setScissor == true) {
|
||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
switch (this->vis.type) {
|
||||
case FB_FILTER_CVG_RGB:
|
||||
gSPDisplayList(gfx++, sCoverageRGBDL);
|
||||
switch (this->params.type) {
|
||||
case VISCVG_TYPE_MODULATE_FB:
|
||||
gSPDisplayList(gfx++, sVisCvgModulateFramebufferDL);
|
||||
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);
|
||||
case VISCVG_TYPE_FADE_AND_MODULATE_FB:
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->params.color1.rgba);
|
||||
gSPDisplayList(gfx++, sVisCvgFadeToPrimAndModulateFramebuffer);
|
||||
break;
|
||||
|
||||
case FB_FILTER_CVG_ONLY:
|
||||
// Set background color for G_RM_VISCVG
|
||||
gDPSetColor(gfx++, G_SETBLENDCOLOR, this->vis.primColor.rgba);
|
||||
gSPDisplayList(gfx++, sCoverageOnlyDL);
|
||||
case VISCVG_TYPE_MODULATE_COLOR:
|
||||
gDPSetColor(gfx++, G_SETBLENDCOLOR, this->params.color1.rgba);
|
||||
gSPDisplayList(gfx++, sVisCvgModulateBlendColorDL);
|
||||
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:
|
||||
case VISCVG_TYPE_MODULATE_FB_ADDITIVE_COLOR:
|
||||
gDPSetColor(gfx++, G_SETFOGCOLOR, this->params.color1.rgba);
|
||||
gSPDisplayList(gfx++, sVisCvgModulateFramebufferAdditiveFogDL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+23
-21
@@ -1,11 +1,14 @@
|
||||
/**
|
||||
* @file z_vismono.c
|
||||
* Color frame buffer effect to desaturate the colors.
|
||||
*
|
||||
* This file implements a full-screen framebuffer effect for desaturating the contents of the framebuffer image.
|
||||
* The result of the desaturation is used to LERP from color2 (0) to color1 (1).
|
||||
* In the simplest case, to get a grayscale result, set color1 to white and color2 to black.
|
||||
*
|
||||
* 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.
|
||||
* This effect is achieved by making the RDP read the rgba16 framebuffer as a ci8 texture using a specific ia16 palette.
|
||||
* For every two-bytes pixel in the rgba16 framebuffer, the palette maps in particular an intensity to the high byte and
|
||||
* an alpha value to the low byte. The sum of those intensity and alpha value corresponds to the gray level of the
|
||||
* desaturated color. This sum is done by the RDP with a clever setup of texture tiles and an adequate combiner.
|
||||
* See the rest of the file for specifics.
|
||||
*/
|
||||
|
||||
#include "libc64/malloc.h"
|
||||
@@ -17,7 +20,7 @@
|
||||
|
||||
// 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.
|
||||
// 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`.
|
||||
@@ -37,16 +40,16 @@ extern u16 D_0F000000[];
|
||||
|
||||
void VisMono_Init(VisMono* this) {
|
||||
bzero(this, sizeof(VisMono));
|
||||
this->vis.type = 0;
|
||||
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;
|
||||
this->vis.envColor.r = 0;
|
||||
this->vis.envColor.g = 0;
|
||||
this->vis.envColor.b = 0;
|
||||
this->vis.envColor.a = 0;
|
||||
this->params.type = 0;
|
||||
this->params.setScissor = false;
|
||||
this->params.color1.r = 255;
|
||||
this->params.color1.g = 255;
|
||||
this->params.color1.b = 255;
|
||||
this->params.color1.a = 255;
|
||||
this->params.color2.r = 0;
|
||||
this->params.color2.g = 0;
|
||||
this->params.color2.b = 0;
|
||||
this->params.color2.a = 0;
|
||||
}
|
||||
|
||||
void VisMono_Destroy(VisMono* this) {
|
||||
@@ -105,8 +108,7 @@ Gfx* VisMono_DesaturateDList(VisMono* this, Gfx* gfx) {
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
// (palette is set to 1 here but that's ignored in the case of CI8 where there is only one palette)
|
||||
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, (height - 1) << 2);
|
||||
@@ -171,12 +173,12 @@ void VisMono_Draw(VisMono* this, Gfx** gfxP) {
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
|
||||
if (this->vis.scissorType == VIS_SETSCISSOR) {
|
||||
if (this->params.setScissor == true) {
|
||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
|
||||
gDPSetColor(gfx++, G_SETENVCOLOR, this->vis.envColor.rgba);
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->params.color1.rgba);
|
||||
gDPSetColor(gfx++, G_SETENVCOLOR, this->params.color2.rgba);
|
||||
|
||||
gDPLoadTLUT_pal256(gfx++, tlut);
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/**
|
||||
* @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 "gfx.h"
|
||||
#include "vis.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;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* This file implements a framebuffer effect relying on the depth buffer (Z buffer).
|
||||
* It merely allows LERPing between two colors (from color2 to color1), using the Z buffer bytes (interpreted as either
|
||||
* ia16 or rgba16 depending on the type being 0 or not) as the factor.
|
||||
*
|
||||
* Z buffer values are two bytes each. They are floating point, which makes the effect not that interesting for an
|
||||
* actual application as that doesn't map well to be interpreted as ia16 or rgba16, though some discontinuous gradients
|
||||
* can be seen.
|
||||
*
|
||||
* The bit layout of Z buffer values is:
|
||||
* 0bEEEM_MMMM_MMMM_MMDD
|
||||
* Where E is the 3 exponent bits, M is the 11 mantissa bits,
|
||||
* and D is 2 of the 4 dz value bits (the remaining two are stored in the "hidden" 9th bit of each byte).
|
||||
* In 3D space, Z values increase from front (near plane) to back (far plane).
|
||||
*
|
||||
* Interpreted as ia16:
|
||||
* 0bIIII_IIII_AAAA_AAAA
|
||||
* The intensity channel takes its value from the exponent bits and the high mantissa bits, so it continuously increases
|
||||
* from front to back.
|
||||
* The alpha channel mostly takes its value from the lowest mantissa bits, so it increases from front to back but also
|
||||
* rolls over frequently.
|
||||
* This can be observed in-game by setting color1 to white and color2 to black.
|
||||
* From front to back, the intensity gradient is a continuous increase.
|
||||
* The alpha is ignored due to the render mode VisZBuffer uses.
|
||||
*
|
||||
* Interpreted as rgba16:
|
||||
* 0bRRRR_RGGG_GGBB_BBBA
|
||||
* The red channel mostly takes its value from the exponent bits, so it continuously increases from front to back.
|
||||
* The green channel takes its value from the middle mantissa bits, so it increases from front to back but also rolls
|
||||
* over frequently.
|
||||
* The blue channel mostly takes its value from the lowest mantissa bits, so it increases from front to back and also
|
||||
* rolls over even more frequently.
|
||||
* This can be observed in-game by setting color1 to white and color2 to black.
|
||||
* From front to back, the gradients for each color channel are then:
|
||||
* - red: continuous increase
|
||||
* - green: discontinuous succession of continuous increases
|
||||
* - blue: like green but even higher frequency
|
||||
*/
|
||||
|
||||
#include "ultra64.h"
|
||||
#include "gfx.h"
|
||||
#include "vis.h"
|
||||
|
||||
// z-buffer
|
||||
extern u16 D_0E000000[];
|
||||
|
||||
void VisZBuffer_Init(VisZBuffer* this) {
|
||||
this->params.type = 0;
|
||||
this->params.setScissor = false;
|
||||
this->params.color1.r = 255;
|
||||
this->params.color1.g = 255;
|
||||
this->params.color1.b = 255;
|
||||
this->params.color1.a = 255;
|
||||
|
||||
// clang-format off
|
||||
this->params.color2.r = 0; \
|
||||
this->params.color2.g = 0; \
|
||||
this->params.color2.b = 0; \
|
||||
this->params.color2.a = 255;
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void VisZBuffer_Destroy(VisZBuffer* this) {
|
||||
}
|
||||
|
||||
void VisZBuffer_Draw(VisZBuffer* this, Gfx** gfxP) {
|
||||
Gfx* gfx = *gfxP;
|
||||
s32 pad;
|
||||
u16* tex = D_0E000000;
|
||||
s32 fmt = this->params.type == 0 ? G_IM_FMT_IA : G_IM_FMT_RGBA;
|
||||
s32 y;
|
||||
s32 height = TMEM_SIZE / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES);
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
if (this->params.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->params.color1.rgba);
|
||||
gDPSetColor(gfx++, G_SETENVCOLOR, this->params.color2.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;
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// z_kankyo, z_demo_kankyo, z_en_viewer, z_object_kankyo, z_eff_ss_dead_dd
|
||||
D_01000000 = 0x01000000;
|
||||
|
||||
// z_viszbuf
|
||||
// z_viszbuffer
|
||||
D_0E000000 = 0x0E000000;
|
||||
|
||||
// z_vismono
|
||||
|
||||
Reference in New Issue
Block a user