mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-12-07 16:42:36 +00:00
a proper fix to djui cursor dl corruption (#1018)
An alternative solution to https://github.com/coop-deluxe/sm64coopdx/pull/1014. Which keeps smooth cursor rendering, while adding safe guards. This makes djui interactions always update at 30hz instead of 60hz, to avoid more chances of display list corruption. The cursor gfx is now placed in it's own static buffer to allow it to take up extra room if needed. If the 20 dl command buffer size is too small, we'll hear about it because it'll throw a system error. I doubt it'll trigger though, in my testing it never needed more than 8.
This commit is contained in:
parent
48bfef7d87
commit
8b92817055
3 changed files with 26 additions and 15 deletions
|
|
@ -69,7 +69,6 @@ void djui_shutdown(void) {
|
|||
void patch_djui_before(void) {
|
||||
sDjuiRendered60fps = false;
|
||||
sSavedDisplayListHead = NULL;
|
||||
djui_cursor_interp_before();
|
||||
}
|
||||
|
||||
void patch_djui_interpolated(UNUSED f32 delta) {
|
||||
|
|
@ -211,6 +210,11 @@ void djui_render(void) {
|
|||
|
||||
djui_cursor_update();
|
||||
djui_base_render(&gDjuiConsole->base);
|
||||
djui_interactable_update();
|
||||
|
||||
// Be careful! Djui interactables update at 30hz to avoid display list corruption.
|
||||
if (!sDjuiRendered60fps) {
|
||||
djui_interactable_update();
|
||||
}
|
||||
|
||||
djui_gfx_displaylist_end();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include "pc/gfx/gfx_window_manager_api.h"
|
||||
#include "pc/pc_main.h"
|
||||
|
||||
#define CURSOR_GFX_MAX_SIZE 20
|
||||
|
||||
extern ALIGNED8 u8 gd_texture_hand_open[];
|
||||
extern ALIGNED8 u8 gd_texture_hand_closed[];
|
||||
|
||||
|
|
@ -17,10 +19,10 @@ static f32 sSavedMouseY = 0;
|
|||
f32 gCursorX = 0;
|
||||
f32 gCursorY = 0;
|
||||
|
||||
static Gfx sDjuiCursorGfx[CURSOR_GFX_MAX_SIZE] = { 0 };
|
||||
|
||||
static f32 sPrevCursorX = 0;
|
||||
static f32 sPrevCursorY = 0;
|
||||
static Gfx* sSavedDisplayListHead = NULL;
|
||||
static bool sInterpCursor = false;
|
||||
|
||||
void djui_cursor_set_visible(bool visible) {
|
||||
if (sMouseCursor) {
|
||||
|
|
@ -161,25 +163,31 @@ static void djui_cursor_update_position(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void djui_cursor_interp_before(void) {
|
||||
sSavedDisplayListHead = NULL;
|
||||
sInterpCursor = false;
|
||||
static void djui_cursor_render_cursor(void) {
|
||||
gDisplayListHead = sDjuiCursorGfx;
|
||||
djui_base_render(&sMouseCursor->base);
|
||||
gSPEndDisplayList(gDisplayListHead++);
|
||||
if (gDisplayListHead - sDjuiCursorGfx >= CURSOR_GFX_MAX_SIZE) {
|
||||
sys_fatal("CURSOR_GFX_MAX_SIZE is too small! %lu", gDisplayListHead - sDjuiCursorGfx);
|
||||
}
|
||||
}
|
||||
|
||||
// This isn't actually interpolation, it just updates the cursor at a faster rate
|
||||
void djui_cursor_interp(void) {
|
||||
djui_cursor_update_position();
|
||||
if (sInterpCursor && (sPrevCursorX != gCursorX || sPrevCursorY != gCursorY)) {
|
||||
if (sSavedDisplayListHead == NULL) { return; }
|
||||
gDisplayListHead = sSavedDisplayListHead;
|
||||
djui_base_render(&sMouseCursor->base);
|
||||
|
||||
if (sPrevCursorX != gCursorX || sPrevCursorY != gCursorY) {
|
||||
djui_cursor_render_cursor();
|
||||
}
|
||||
}
|
||||
|
||||
void djui_cursor_update(void) {
|
||||
djui_cursor_update_position();
|
||||
sSavedDisplayListHead = gDisplayListHead;
|
||||
djui_base_render(&sMouseCursor->base);
|
||||
sInterpCursor = gDisplayListHead != sSavedDisplayListHead; // Check that we actually rendered something
|
||||
|
||||
Gfx *savedDisplayListHead = gDisplayListHead;
|
||||
djui_cursor_render_cursor();
|
||||
gDisplayListHead = savedDisplayListHead;
|
||||
gSPDisplayList(gDisplayListHead++, sDjuiCursorGfx);
|
||||
}
|
||||
|
||||
void djui_cursor_create(void) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ void djui_cursor_set_visible(bool visible);
|
|||
bool djui_cursor_inside_base(struct DjuiBase* base);
|
||||
void djui_cursor_input_controlled_center(struct DjuiBase* base);
|
||||
void djui_cursor_move(s8 xDir, s8 yDir);
|
||||
void djui_cursor_interp_before(void);
|
||||
void djui_cursor_interp(void);
|
||||
void djui_cursor_update(void);
|
||||
void djui_cursor_create(void);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue