From 9a49ff95c7fd26a1441ebcb8e07e21c02d586217 Mon Sep 17 00:00:00 2001 From: MysterD Date: Mon, 10 Apr 2023 19:03:34 -0700 Subject: [PATCH] Fixed graphical corruption when text renders offscreen --- src/pc/djui/djui.c | 2 ++ src/pc/djui/djui_gbi.h | 6 +++++ src/pc/djui/djui_gfx.c | 19 ++++++++++++++++ src/pc/djui/djui_gfx.h | 3 +++ src/pc/gfx/gfx_pc.c | 50 +++++++++++++++++++++++------------------- 5 files changed, 58 insertions(+), 22 deletions(-) diff --git a/src/pc/djui/djui.c b/src/pc/djui/djui.c index 6c0aa9951..342043934 100644 --- a/src/pc/djui/djui.c +++ b/src/pc/djui/djui.c @@ -98,6 +98,7 @@ void djui_render(void) { gDjuiHudUtilsZ = 0; create_dl_ortho_matrix(); + djui_gfx_displaylist_begin(); smlua_call_event_hooks(HOOK_ON_HUD_RENDER); @@ -119,4 +120,5 @@ void djui_render(void) { djui_cursor_update(); djui_interactable_update(); + djui_gfx_displaylist_end(); } diff --git a/src/pc/djui/djui_gbi.h b/src/pc/djui/djui_gbi.h index ef5c59002..45c6722da 100644 --- a/src/pc/djui/djui_gbi.h +++ b/src/pc/djui/djui_gbi.h @@ -4,8 +4,14 @@ #define G_TEXOVERRIDE_DJUI 0xe0 #define G_DJUI_SIMPLE_VERT 0x11 #define G_DJUI_SIMPLE_TRI2 0x12 +#define G_TEXADDR_DJUI 0x13 #define G_EXECUTE_DJUI 0xdd +#define gsSPTextureAddrDjui(c) \ +{{ \ + (_SHIFTL(G_TEXADDR_DJUI,24,8)|_SHIFTL(~(u32)(c),0,24)),(u32)(0) \ +}} + #define gSetClippingDjui(pkt, cmd, x1, y1, x2, y2) \ { \ Gfx *_g = (Gfx *)(pkt); \ diff --git a/src/pc/djui/djui_gfx.c b/src/pc/djui/djui_gfx.c index c01099b77..26a185f39 100644 --- a/src/pc/djui/djui_gfx.c +++ b/src/pc/djui/djui_gfx.c @@ -6,6 +6,25 @@ #include "src/pc/pc_main.h" #include "src/pc/gfx/gfx_window_manager_api.h" #include "gfx_dimensions.h" +#include "djui_gfx.h" + +const Gfx dl_djui_display_list_begin[] = { + gsSPTextureAddrDjui(1), + gsSPEndDisplayList(), +}; + +const Gfx dl_djui_display_list_end[] = { + gsSPTextureAddrDjui(0), + gsSPEndDisplayList(), +}; + +void djui_gfx_displaylist_begin(void) { + gSPDisplayList(gDisplayListHead++, dl_djui_display_list_begin); +} + +void djui_gfx_displaylist_end(void) { + gSPDisplayList(gDisplayListHead++, dl_djui_display_list_end); +} static const Vtx vertex_djui_simple_rect[] = { {{{ 0, -1, 0}, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}}, diff --git a/src/pc/djui/djui_gfx.h b/src/pc/djui/djui_gfx.h index 205508e94..8369bc15d 100644 --- a/src/pc/djui/djui_gfx.h +++ b/src/pc/djui/djui_gfx.h @@ -9,6 +9,9 @@ extern const Gfx dl_djui_simple_rect[]; extern const Gfx dl_djui_img_begin[]; extern const Gfx dl_djui_img_end[]; +void djui_gfx_displaylist_begin(void); +void djui_gfx_displaylist_end(void); + f32 djui_gfx_get_scale(void); void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize); diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index dfd346477..c76544b59 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -189,6 +189,18 @@ static const uint8_t missing_texture[MISSING_W * MISSING_H * 4] = { 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, }; +static bool sOnlyTextureChangeOnAddrChange = false; + +static void gfx_update_loaded_texture(uint8_t tile_number, uint32_t size_bytes, const uint8_t* addr) { + if (!sOnlyTextureChangeOnAddrChange) { + rdp.textures_changed[tile_number] = true; + } else if (!rdp.textures_changed[tile_number]) { + rdp.textures_changed[tile_number] = rdp.loaded_texture[tile_number].addr != addr; + } + rdp.loaded_texture[tile_number].size_bytes = size_bytes; + rdp.loaded_texture[tile_number].addr = addr; +} + ////////////////////////////////// // forward declaration for djui // ////////////////////////////////// @@ -210,15 +222,9 @@ static unsigned long get_time(void) { static void gfx_flush(void) { if (buf_vbo_len > 0) { - /*int num = buf_vbo_num_tris; - unsigned long t0 = get_time();*/ gfx_rapi->draw_triangles(buf_vbo, buf_vbo_len, buf_vbo_num_tris); buf_vbo_len = 0; buf_vbo_num_tris = 0; - /*unsigned long t1 = get_time(); - if (t1 - t0 > 1000) { - printf("f: %d %d\n", num, (int)(t1 - t0)); - }*/ } } @@ -1241,8 +1247,11 @@ static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t t rdp.texture_tile.cms = cms; rdp.texture_tile.cmt = cmt; rdp.texture_tile.line_size_bytes = line * 8; - rdp.textures_changed[0] = true; - rdp.textures_changed[1] = true; + if (!sOnlyTextureChangeOnAddrChange) { + // I don't know if we ever need to set these... + rdp.textures_changed[0] = true; + rdp.textures_changed[1] = true; + } } if (tile == G_TX_LOADTILE) { @@ -1256,8 +1265,11 @@ static void gfx_dp_set_tile_size(uint8_t tile, uint16_t uls, uint16_t ult, uint1 rdp.texture_tile.ult = ult; rdp.texture_tile.lrs = lrs; rdp.texture_tile.lrt = lrt; - rdp.textures_changed[0] = true; - rdp.textures_changed[1] = true; + if (!sOnlyTextureChangeOnAddrChange) { + // I don't know if we ever need to set these... + rdp.textures_changed[0] = true; + rdp.textures_changed[1] = true; + } } } @@ -1290,9 +1302,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t break; } uint32_t size_bytes = (lrs + 1) << word_size_shift; - rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes; - rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr; - rdp.textures_changed[rdp.texture_to_load.tile_number] = true; + gfx_update_loaded_texture(rdp.texture_to_load.tile_number, size_bytes, rdp.texture_to_load.addr); } static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) { @@ -1318,15 +1328,11 @@ static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t } uint32_t size_bytes = (((lrs >> G_TEXTURE_IMAGE_FRAC) + 1) * ((lrt >> G_TEXTURE_IMAGE_FRAC) + 1)) << word_size_shift; - rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes; - - rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr; + gfx_update_loaded_texture(rdp.texture_to_load.tile_number, size_bytes, rdp.texture_to_load.addr); rdp.texture_tile.uls = uls; rdp.texture_tile.ult = ult; rdp.texture_tile.lrs = lrs; rdp.texture_tile.lrt = lrt; - - rdp.textures_changed[rdp.texture_to_load.tile_number] = true; } static uint8_t color_comb_component(uint32_t v) { @@ -1977,10 +1983,7 @@ static void OPTIMIZE_O3 djui_gfx_dp_execute_override(void) { uint32_t wordSizeShift = (sDjuiOverrideB == 32) ? 2 : 1; uint32_t lrs = (sDjuiOverrideW * sDjuiOverrideH) - 1; uint32_t sizeBytes = (lrs + 1) << wordSizeShift; - rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = sizeBytes; - rdp.textures_changed[rdp.texture_to_load.tile_number] = rdp.loaded_texture[rdp.texture_to_load.tile_number].addr != rdp.texture_to_load.addr; - rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr; - //rdp.textures_changed[rdp.texture_to_load.tile_number] = true; + gfx_update_loaded_texture(rdp.texture_to_load.tile_number, sizeBytes, rdp.texture_to_load.addr); // gsDPSetTile uint32_t line = (((sDjuiOverrideW * 2) + 7) >> 3); @@ -2135,6 +2138,9 @@ void OPTIMIZE_O3 djui_gfx_run_dl(Gfx* cmd) { djui_gfx_sp_simple_tri1(C0(16, 8) / 2, C0(8, 8) / 2, C0(0, 8) / 2); djui_gfx_sp_simple_tri1(C1(16, 8) / 2, C1(8, 8) / 2, C1(0, 8) / 2); break; + case G_TEXADDR_DJUI: + sOnlyTextureChangeOnAddrChange = !(C0(0, 24) & 0x01); + break; case G_EXECUTE_DJUI: djui_gfx_dp_execute_djui(cmd->words.w1); break;