Cleaned up and documented gfx_draw_background, changed vscode config to use gcc-x86 to avoid intellisense truncation warnings for pointers (#739)

This commit is contained in:
Mr-Wiseguy 2022-07-03 02:42:28 -04:00 committed by GitHub
parent 97059b9f4d
commit ea64a774fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 19 deletions

View File

@ -25,7 +25,8 @@
"VERSION_US"
],
"cStandard": "c89",
"cppStandard": "c++17"
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x86"
}
]
}

View File

@ -64,6 +64,11 @@
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
// Size of tmem in bytes (4kB)
#define TMEM_SIZE 0x1000
// Height of tiles to use when copying fullscreen images (6)
#define SCREEN_COPY_TILE_HEIGHT ((TMEM_SIZE) / ((SCREEN_WIDTH) * (2)))
// Alternative to libultra's M_PI: non-float version; more digits cause issues
#define PI 3.141592f
#define PI_D 3.141592
@ -80,6 +85,7 @@
#define COLLISION_ONLY_ENTITIES 0x100000
#define PACK_FILL_COLOR(r, g, b, a) (GPACK_RGBA5551(r, g, b, a) << 0x10) | GPACK_RGBA5551(r, g, b, a)
#define PACK_FILL_DEPTH(z,dz) (GPACK_ZDZ(z, dz) << 0x10) | GPACK_ZDZ(z, dz)
#define SQ(x) ((x)*(x))
#define CUBE(x) (x*x*x)

View File

@ -20,7 +20,7 @@ s32 D_800741A8[] = { 0x00010000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
u16 gMatrixListPos = 0;
u16 D_800741F2 = 0;
s32 gCurrentDisplayContextIndex = 0;
s32 D_800741F8 = 0;
s32 gPauseBackgroundFade = 0;
s32 D_800741FC = 0;
s32 D_80074200[] = { 0x028001E0, 0x01FF0000, 0x028001E0, 0x01FF0000 };
@ -430,6 +430,12 @@ void func_80027BAC(s32 arg0, s32 arg1) {
}
}
// Logic for the drawing the scene background. In normal operation, it draws the regular background.
// While opening pause menu, it does the following:
// * Extracts coverage from the current framebuffer and saves it to nuGfxCfb[1] on the first frame.
// * Copies the current framebuffer to the depth buffer to save it and applies a filter on the
// saved framebuffer based on the saved coverage values one frame later.
// * Draws the saved framebuffer to the current framebuffer while the pause screen is opened, fading it in over time.
void gfx_draw_background(void) {
Camera* camera;
s32 bgFlags;
@ -439,7 +445,7 @@ void gfx_draw_background(void) {
s32 backgroundMaxY;
s32 viewportStartX;
s32 i;
s32 a = 0x18;
s32 a = SCREEN_COPY_TILE_HEIGHT << 2;
gDPSetScissor(gMasterGfxPos++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
@ -448,11 +454,12 @@ void gfx_draw_background(void) {
switch (bgFlags) {
case 0x10:
// Save coverage to nunGfxCfb[1] using the VISCVG render mode
gDPPipeSync(gMasterGfxPos++);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, nuGfxCfb[1]);
gDPSetCycleType(gMasterGfxPos++, G_CYC_1CYCLE);
gDPSetBlendColor(gMasterGfxPos++, 0x80, 0x80, 0x80, 0xFF);
gDPSetPrimDepth(gMasterGfxPos++, -1, -1);
gDPSetPrimDepth(gMasterGfxPos++, 0xFFFF, 0xFFFF);
gDPSetDepthSource(gMasterGfxPos++, G_ZS_PRIM);
gDPSetRenderMode(gMasterGfxPos++, G_RM_VISCVG, G_RM_VISCVG2);
gDPFillRectangle(gMasterGfxPos++, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
@ -462,15 +469,17 @@ void gfx_draw_background(void) {
gGameStatusPtr->backgroundFlags |= 0x20;
break;
case 0x20:
// Save the framebuffer into the depth buffer and run a filter on it based on the saved coverage values
gfx_transfer_frame_to_depth(nuGfxCfb[0], nuGfxCfb[1], nuGfxZBuffer); // applies filters to the framebuffer
D_800741F8 = 0;
gPauseBackgroundFade = 0;
gGameStatusPtr->backgroundFlags &= ~0xF0;
gGameStatusPtr->backgroundFlags |= 0x30;
// fall through
case 0x30:
D_800741F8 += 0x10;
if (D_800741F8 > 0x80) {
D_800741F8 = 0x80;
// Draw the saved framebuffer to the background, fading in at a rate of 0x10 opacity per frame until reaching 0x80 opacity
gPauseBackgroundFade += 0x10;
if (gPauseBackgroundFade > 0x80) {
gPauseBackgroundFade = 0x80;
}
gDPPipeSync(gMasterGfxPos++);
@ -478,37 +487,48 @@ void gfx_draw_background(void) {
gDPSetCycleType(gMasterGfxPos++, G_CYC_FILL);
gDPSetRenderMode(gMasterGfxPos++, G_RM_NOOP, G_RM_NOOP2);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, nuGfxCfb_ptr);
gDPSetFillColor(gMasterGfxPos++, 0x00010001);
gDPSetFillColor(gMasterGfxPos++, PACK_FILL_COLOR(0, 0, 0, 1));
gDPFillRectangle(gMasterGfxPos++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
gDPSetCycleType(gMasterGfxPos++, G_CYC_1CYCLE);
gDPSetTexturePersp(gMasterGfxPos++, G_TP_NONE);
gDPSetTextureLUT(gMasterGfxPos++, G_TT_NONE);
gDPSetRenderMode(gMasterGfxPos++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
// @bug In 1-cycle mode, the two combiner cycles should be identical. Using Texel1 here in the second cycle,
// which is the actual cycle of the combiner used on hardware in 1-cycle mode, actually samples the next
// pixel's texel value instead of the current pixel's. This results in a one-pixel offset.
gDPSetCombineLERP(gMasterGfxPos++, PRIMITIVE, TEXEL0, PRIMITIVE_ALPHA, TEXEL0, 0, 0, 0, 1, PRIMITIVE,
TEXEL1, PRIMITIVE_ALPHA, TEXEL1, 0, 0, 0, 1);
gDPSetPrimColor(gMasterGfxPos++, 0, 0, 0x28, 0x28, 0x28, D_800741F8);
gDPSetPrimColor(gMasterGfxPos++, 0, 0, 0x28, 0x28, 0x28, gPauseBackgroundFade);
gDPSetTextureFilter(gMasterGfxPos++, G_TF_POINT);
for (i = 0; i < 40; i++) {
gDPLoadTextureTile(gMasterGfxPos++, nuGfxZBuffer + (i * 0x780), G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH,
SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH - 1, 5, 0, G_TX_NOMIRROR | G_TX_WRAP,
gDPLoadTextureTile(gMasterGfxPos++, nuGfxZBuffer + (i * SCREEN_WIDTH * SCREEN_COPY_TILE_HEIGHT), G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH,
SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH - 1, SCREEN_COPY_TILE_HEIGHT - 1, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPTextureRectangle(gMasterGfxPos++, 0, i * a, 0x0500, a + (i * 0x18), G_TX_RENDERTILE,
-0x0020, 0, 0x0400, 0x0400);
// @bug Due to the previous issue with the incorrect second cycle combiner, the devs added a 1-pixel offset to texture coordinates
// in this texrect to compensate for the combiner error.
gSPTextureRectangle(gMasterGfxPos++,
// ulx, uly, lrx, lry
0 << 2, i * a, SCREEN_WIDTH << 2, a + (i * (SCREEN_COPY_TILE_HEIGHT << 2)),
// tile
G_TX_RENDERTILE,
// s, t, dsdx, dtdy
-1 << 5, 0 << 5, 1 << 10, 1 << 10);
gDPPipeSync(gMasterGfxPos++);
}
break;
default:
// Draw the scene's background as normal
if (gOverrideFlags & GLOBAL_OVERRIDES_8) {
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, osVirtualToPhysical(nuGfxCfb_ptr));
return;
}
gDPSetDepthImage(gMasterGfxPos++, OS_PHYSICAL_TO_K0(nuGfxZBuffer)); // TODO: or OS_K0_TO_PHYSICAL
gDPSetDepthImage(gMasterGfxPos++, OS_K0_TO_PHYSICAL(nuGfxZBuffer));
gDPSetCycleType(gMasterGfxPos++, G_CYC_FILL);
gDPSetRenderMode(gMasterGfxPos++, G_RM_NOOP, G_RM_NOOP2);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, OS_PHYSICAL_TO_K0(nuGfxZBuffer));
gDPSetFillColor(gMasterGfxPos++, 0xFFFCFFFC);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, OS_K0_TO_PHYSICAL(nuGfxZBuffer));
gDPSetFillColor(gMasterGfxPos++, PACK_FILL_DEPTH(G_MAXFBZ, 0));
gDPFillRectangle(gMasterGfxPos++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
gDPPipeSync(gMasterGfxPos++);
gDPSetColorImage(gMasterGfxPos++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WIDTH, osVirtualToPhysical(nuGfxCfb_ptr));
@ -577,7 +597,7 @@ void gfx_draw_background(void) {
gDPPipeSync(gMasterGfxPos++);
gDPSetCycleType(gMasterGfxPos++, G_CYC_FILL);
gDPSetRenderMode(gMasterGfxPos++, G_RM_NOOP, G_RM_NOOP2);
gDPSetFillColor(gMasterGfxPos++, 0x00010001);
gDPSetFillColor(gMasterGfxPos++, PACK_FILL_COLOR(0, 0, 0, 1));
gDPPipeSync(gMasterGfxPos++);
if (backgroundMinY > 0) {

View File

@ -1310,7 +1310,7 @@ D_800741A8 = 0x800741A8; // type:data rom:0x4F5A8
gMatrixListPos = 0x800741F0; // rom:0x4F5F0
D_800741F2 = 0x800741F2; // type:data rom:0x4F5F2
gCurrentDisplayContextIndex = 0x800741F4; // rom:0x4F5F4
D_800741F8 = 0x800741F8; // type:data rom:0x4F5F8
gPauseBackgroundFade = 0x800741F8; // type:data rom:0x4F5F8
D_800741FC = 0x800741FC; // type:data rom:0x4F5FC
D_80074200 = 0x80074200; // type:data rom:0x4F600
D_80074210 = 0x80074210; // type:data rom:0x4F610