Move dirty region tracking into LBackend, fix background area resetting to work with resources screens

This commit is contained in:
UnknownShadow200 2022-04-23 23:38:29 +10:00
parent ccfb87e54f
commit d9b3659551
6 changed files with 57 additions and 69 deletions

View File

@ -27,9 +27,11 @@
struct FontDesc titleFont, textFont, hintFont; struct FontDesc titleFont, textFont, hintFont;
static struct LScreen* activeScreen; static struct LScreen* activeScreen;
static cc_uint8 pendingRedraw; /* The area/region of the window that needs to be redrawn and presented to the screen. */
extern Rect2D dirty_rect; /* If width is 0, means no area needs to be redrawn. */
static Rect2D dirty_rect;
static cc_uint8 pendingRedraw;
#define REDRAW_ALL 0x02 #define REDRAW_ALL 0x02
#define REDRAW_SOME 0x01 #define REDRAW_SOME 0x01
@ -101,6 +103,27 @@ static CC_NOINLINE void MarkAllDirty(void) {
dirty_rect.Y = 0; dirty_rect.Height = Launcher_Framebuffer.height; dirty_rect.Y = 0; dirty_rect.Height = Launcher_Framebuffer.height;
} }
/* Marks the given area/region as needing to be redrawn. */
static CC_NOINLINE void MarkAreaDirty(int x, int y, int width, int height) {
int x1, y1, x2, y2;
if (!Drawer2D_Clamp(&Launcher_Framebuffer, &x, &y, &width, &height)) return;
/* union with existing dirty area */
if (dirty_rect.Width) {
x1 = min(x, dirty_rect.X);
y1 = min(y, dirty_rect.Y);
x2 = max(x + width, dirty_rect.X + dirty_rect.Width);
y2 = max(y + height, dirty_rect.Y + dirty_rect.Height);
x = x1; width = x2 - x1;
y = y1; height = y2 - y1;
}
dirty_rect.X = x; dirty_rect.Width = width;
dirty_rect.Y = y; dirty_rect.Height = height;
}
/*########################################################################################################################* /*########################################################################################################################*
*------------------------------------------------------Base drawing-------------------------------------------------------* *------------------------------------------------------Base drawing-------------------------------------------------------*
@ -126,7 +149,7 @@ static CC_NOINLINE void DrawWidget(struct LWidget* w) {
w->dirty = false; w->dirty = false;
w->VTABLE->Draw(w); w->VTABLE->Draw(w);
Launcher_MarkDirty(w->x, w->y, w->width, w->height); MarkAreaDirty(w->x, w->y, w->width, w->height);
} }
static CC_NOINLINE void RedrawAll(void) { static CC_NOINLINE void RedrawAll(void) {
@ -151,8 +174,9 @@ static CC_NOINLINE void RedrawDirty(void) {
/* check if widget might need redrawing of background behind */ /* check if widget might need redrawing of background behind */
if (!w->opaque || w->last.Width > w->width || w->last.Height > w->height) { if (!w->opaque || w->last.Width > w->width || w->last.Height > w->height) {
Launcher_ResetArea(w->last.X, w->last.Y, w->last.Width, w->last.Height); s->ResetArea(&Launcher_Framebuffer,
Launcher_MarkDirty(w->last.X, w->last.Y, w->last.Width, w->last.Height); w->last.X, w->last.Y, w->last.Width, w->last.Height);
MarkAreaDirty(w->last.X, w->last.Y, w->last.Width, w->last.Height);
} }
DrawWidget(w); DrawWidget(w);
} }
@ -355,19 +379,21 @@ void LBackend_InputInit(struct LInput* w, int width) {
} }
static void LInput_DrawOuterBorder(struct LInput* w) { static void LInput_DrawOuterBorder(struct LInput* w) {
BitmapCol color = BitmapCol_Make(97, 81, 110, 255); struct LScreen* s = activeScreen;
struct Bitmap* bmp = &Launcher_Framebuffer;
BitmapCol color = BitmapCol_Make(97, 81, 110, 255);
if (w->selected) { if (w->selected) {
DrawBoxBounds(color, w->x, w->y, w->width, w->height); DrawBoxBounds(color, w->x, w->y, w->width, w->height);
} else { } else {
Launcher_ResetArea(w->x, w->y, s->ResetArea(bmp, w->x, w->y,
w->width, yBorder); w->width, yBorder);
Launcher_ResetArea(w->x, w->y + w->height - yBorder, s->ResetArea(bmp, w->x, w->y + w->height - yBorder,
w->width, yBorder); w->width, yBorder);
Launcher_ResetArea(w->x, w->y, s->ResetArea(bmp, w->x, w->y,
xBorder, w->height); xBorder, w->height);
Launcher_ResetArea(w->x + w->width - xBorder, w->y, s->ResetArea(bmp, w->x + w->width - xBorder, w->y,
xBorder, w->height); xBorder, w->height);
} }
} }
@ -543,9 +569,9 @@ void LBackend_InputTick(struct LInput* w) {
if (Rect2D_Equals(r, lastCaretRec)) { if (Rect2D_Equals(r, lastCaretRec)) {
/* Fast path, caret is blinking in same spot */ /* Fast path, caret is blinking in same spot */
Launcher_MarkDirty(r.X, r.Y, r.Width, r.Height); MarkAreaDirty(r.X, r.Y, r.Width, r.Height);
} else { } else {
Launcher_MarkDirty(w->x, w->y, w->width, w->height); MarkAreaDirty(w->x, w->y, w->width, w->height);
} }
lastCaretRec = r; lastCaretRec = r;
} }
@ -694,7 +720,8 @@ static void LTable_DrawHeaderBackground(struct LTable* w) {
Drawer2D_Clear(&Launcher_Framebuffer, gridColor, Drawer2D_Clear(&Launcher_Framebuffer, gridColor,
w->x, w->y, w->width, w->hdrHeight); w->x, w->y, w->width, w->hdrHeight);
} else { } else {
Launcher_ResetArea(w->x, w->y, w->width, w->hdrHeight); Launcher_DrawBackground(&Launcher_Framebuffer,
w->x, w->y, w->width, w->hdrHeight);
} }
} }
@ -739,9 +766,10 @@ static void LTable_DrawRowsBackground(struct LTable* w) {
if (color) { if (color) {
Drawer2D_Clear(&Launcher_Framebuffer, color, Drawer2D_Clear(&Launcher_Framebuffer, color,
w->x, y, w->width, height); w->x, y, w->width, height);
} else { } else {
Launcher_ResetArea(w->x, y, w->width, height); Launcher_DrawBackground(&Launcher_Framebuffer,
w->x, y, w->width, height);
} }
} }
} }

View File

@ -195,6 +195,7 @@ CC_NOINLINE static void LScreen_Reset(struct LScreen* s) {
s->MouseWheel = LScreen_MouseWheel; s->MouseWheel = LScreen_MouseWheel;
s->TextChanged = LScreen_TextChanged; s->TextChanged = LScreen_TextChanged;
s->DrawBackground = LScreen_DrawBackground; s->DrawBackground = LScreen_DrawBackground;
s->ResetArea = Launcher_DrawBackground;
/* reset all widgets mouse state */ /* reset all widgets mouse state */
for (i = 0; i < s->numWidgets; i++) { for (i = 0; i < s->numWidgets; i++) {
@ -1109,9 +1110,8 @@ static void CheckResourcesScreen_Layout(struct LScreen* s_) {
#define RESOURCES_BACK_COLOR BitmapCol_Make( 12, 12, 12, 255) #define RESOURCES_BACK_COLOR BitmapCol_Make( 12, 12, 12, 255)
#define RESOURCES_FORE_COLOR BitmapCol_Make(120, 85, 151, 255) #define RESOURCES_FORE_COLOR BitmapCol_Make(120, 85, 151, 255)
static void CheckResourcesScreen_ResetArea(int x, int y, int width, int height) { static void CheckResourcesScreen_ResetArea(struct Bitmap* bmp, int x, int y, int width, int height) {
Gradient_Noise(&Launcher_Framebuffer, RESOURCES_FORE_COLOR, 4, x, y, width, height); Gradient_Noise(bmp, RESOURCES_FORE_COLOR, 4, x, y, width, height);
Launcher_MarkDirty(x, y, width, height);
} }
static void CheckResourcesScreen_DrawBackground(struct LScreen* s, struct Bitmap* bmp) { static void CheckResourcesScreen_DrawBackground(struct LScreen* s, struct Bitmap* bmp) {
@ -1122,7 +1122,7 @@ static void CheckResourcesScreen_DrawBackground(struct LScreen* s, struct Bitmap
x = Gui_CalcPos(ANCHOR_CENTRE, 0, width, bmp->width); x = Gui_CalcPos(ANCHOR_CENTRE, 0, width, bmp->width);
y = Gui_CalcPos(ANCHOR_CENTRE, 0, height, bmp->height); y = Gui_CalcPos(ANCHOR_CENTRE, 0, height, bmp->height);
Gradient_Noise(bmp, RESOURCES_FORE_COLOR, 4, x, y, width, height); CheckResourcesScreen_ResetArea(bmp, x, y, width, height);
} }
void CheckResourcesScreen_SetActive(void) { void CheckResourcesScreen_SetActive(void) {
@ -1132,6 +1132,7 @@ void CheckResourcesScreen_SetActive(void) {
s->Show = CheckResourcesScreen_Show; s->Show = CheckResourcesScreen_Show;
s->Layout = CheckResourcesScreen_Layout; s->Layout = CheckResourcesScreen_Layout;
s->DrawBackground = CheckResourcesScreen_DrawBackground; s->DrawBackground = CheckResourcesScreen_DrawBackground;
s->ResetArea = CheckResourcesScreen_ResetArea;
s->onEnterWidget = (struct LWidget*)&s->btnYes; s->onEnterWidget = (struct LWidget*)&s->btnYes;
Launcher_SetScreen((struct LScreen*)s); Launcher_SetScreen((struct LScreen*)s);
} }
@ -1173,14 +1174,6 @@ static void FetchResourcesScreen_Layout(struct LScreen* s_) {
LWidget_SetLocation(&s->sdrProgress, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 15); LWidget_SetLocation(&s->sdrProgress, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 15);
} }
static void FetchResourcesScreen_SetStatus(struct FetchResourcesScreen* s, const cc_string* str) {
struct LLabel* w = &s->lblStatus;
/* TODO FIXY FIXY FIXY */ w->opaque = true; /* need to rethink ResetArea for Launcher */
CheckResourcesScreen_ResetArea(w->last.X, w->last.Y,
w->last.Width, w->last.Height);
LLabel_SetText(w, str);
}
static void FetchResourcesScreen_UpdateStatus(struct FetchResourcesScreen* s, int reqID) { static void FetchResourcesScreen_UpdateStatus(struct FetchResourcesScreen* s, int reqID) {
cc_string str; char strBuffer[STRING_SIZE]; cc_string str; char strBuffer[STRING_SIZE];
const char* name; const char* name;
@ -1194,7 +1187,7 @@ static void FetchResourcesScreen_UpdateStatus(struct FetchResourcesScreen* s, in
String_Format3(&str, "&eFetching %c.. (%i/%i)", name, &count, &Resources_Count); String_Format3(&str, "&eFetching %c.. (%i/%i)", name, &count, &Resources_Count);
if (String_Equals(&str, &s->lblStatus.text)) return; if (String_Equals(&str, &s->lblStatus.text)) return;
FetchResourcesScreen_SetStatus(s, &str); LLabel_SetText(&s->lblStatus, &str);
} }
static void FetchResourcesScreen_UpdateProgress(struct FetchResourcesScreen* s) { static void FetchResourcesScreen_UpdateProgress(struct FetchResourcesScreen* s) {
@ -1213,7 +1206,7 @@ static void FetchResourcesScreen_Error(struct FetchResourcesScreen* s) {
String_InitArray(str, buffer); String_InitArray(str, buffer);
Launcher_DisplayHttpError(Fetcher_Result, Fetcher_StatusCode, "downloading resources", &str); Launcher_DisplayHttpError(Fetcher_Result, Fetcher_StatusCode, "downloading resources", &str);
FetchResourcesScreen_SetStatus(s, &str); LLabel_SetText(&s->lblStatus, &str);
} }
static void FetchResourcesScreen_Tick(struct LScreen* s_) { static void FetchResourcesScreen_Tick(struct LScreen* s_) {
@ -1238,6 +1231,7 @@ void FetchResourcesScreen_SetActive(void) {
s->Tick = FetchResourcesScreen_Tick; s->Tick = FetchResourcesScreen_Tick;
s->Layout = FetchResourcesScreen_Layout; s->Layout = FetchResourcesScreen_Layout;
s->DrawBackground = CheckResourcesScreen_DrawBackground; s->DrawBackground = CheckResourcesScreen_DrawBackground;
s->ResetArea = CheckResourcesScreen_ResetArea;
Launcher_SetScreen((struct LScreen*)s); Launcher_SetScreen((struct LScreen*)s);
} }

View File

@ -24,6 +24,7 @@ typedef void (*LScreen_Func)(struct LScreen* s);
void (*MouseMove)(struct LScreen* s, int idx); \ void (*MouseMove)(struct LScreen* s, int idx); \
void (*MouseWheel)(struct LScreen* s, float delta); \ void (*MouseWheel)(struct LScreen* s, float delta); \
void (*TextChanged)(struct LScreen* s, const cc_string* str); \ void (*TextChanged)(struct LScreen* s, const cc_string* str); \
void (*ResetArea)(struct Bitmap* bmp, int x, int y, int width, int height); \
struct LWidget* onEnterWidget; /* Default widget to auto-click when Enter is pressed. Can be NULL. */ \ struct LWidget* onEnterWidget; /* Default widget to auto-click when Enter is pressed. Can be NULL. */ \
struct LWidget* hoveredWidget; /* Widget the mouse is currently hovering over. */ \ struct LWidget* hoveredWidget; /* Widget the mouse is currently hovering over. */ \
struct LWidget* selectedWidget; /* Widget mouse last clicked on. */ \ struct LWidget* selectedWidget; /* Widget mouse last clicked on. */ \

View File

@ -40,7 +40,7 @@ struct LWidgetVTABLE {
cc_bool tabSelectable; /* Whether this widget gets selected when pressing tab */ \ cc_bool tabSelectable; /* Whether this widget gets selected when pressing tab */ \
cc_uint8 horAnchor, verAnchor; /* Specifies the reference point for when this widget is resized */ \ cc_uint8 horAnchor, verAnchor; /* Specifies the reference point for when this widget is resized */ \
cc_bool dirty; /* Whether this widget needs to be redrawn */ \ cc_bool dirty; /* Whether this widget needs to be redrawn */ \
cc_bool opaque; /* Whethe this widget completely obscures background behind it */ \ cc_bool opaque; /* Whether this widget completely obscures background behind it */ \
int xOffset, yOffset; /* Offset from the reference point */ \ int xOffset, yOffset; /* Offset from the reference point */ \
void (*OnClick)(void* widget); /* Called when widget is clicked */ \ void (*OnClick)(void* widget); /* Called when widget is clicked */ \
void (*OnHover)(void* widget); /* Called when widget is hovered over */ \ void (*OnHover)(void* widget); /* Called when widget is hovered over */ \

View File

@ -21,10 +21,6 @@
#include "LBackend.h" #include "LBackend.h"
#include "PackedCol.h" #include "PackedCol.h"
/* The area/region of the window that needs to be redrawn and presented to the screen. */
/* If width is 0, means no area needs to be redrawn. */
Rect2D dirty_rect;
static struct LScreen* activeScreen; static struct LScreen* activeScreen;
struct Bitmap Launcher_Framebuffer; struct Bitmap Launcher_Framebuffer;
struct FontDesc Launcher_LogoFont; struct FontDesc Launcher_LogoFont;
@ -517,29 +513,4 @@ void Launcher_UpdateLogoFont(void) {
Drawer2D_MakeFont(&Launcher_LogoFont, 32, FONT_FLAGS_NONE); Drawer2D_MakeFont(&Launcher_LogoFont, 32, FONT_FLAGS_NONE);
Drawer2D.BitmappedText = false; Drawer2D.BitmappedText = false;
} }
void Launcher_ResetArea(int x, int y, int width, int height) {
Launcher_DrawBackground(&Launcher_Framebuffer, x, y, width, height);
Launcher_MarkDirty(x, y, width, height);
}
void Launcher_MarkDirty(int x, int y, int width, int height) {
int x1, y1, x2, y2;
if (!Drawer2D_Clamp(&Launcher_Framebuffer, &x, &y, &width, &height)) return;
/* union with existing dirty area */
if (dirty_rect.Width) {
x1 = min(x, dirty_rect.X);
y1 = min(y, dirty_rect.Y);
x2 = max(x + width, dirty_rect.X + dirty_rect.Width);
y2 = max(y + height, dirty_rect.Y + dirty_rect.Height);
x = x1; width = x2 - x1;
y = y1; height = y2 - y1;
}
dirty_rect.X = x; dirty_rect.Width = width;
dirty_rect.Y = y; dirty_rect.Height = height;
}
#endif #endif

View File

@ -62,12 +62,6 @@ void Launcher_DrawBackground(struct Bitmap* bmp, int x, int y, int width, int he
/* NOTE: Also draws titlebar at top, if current screen permits it */ /* NOTE: Also draws titlebar at top, if current screen permits it */
void Launcher_DrawBackgroundAll(struct Bitmap* bmp); void Launcher_DrawBackgroundAll(struct Bitmap* bmp);
/* Redraws the specified region with the background pixels. */
/* Also marks that area as neeing to be redrawn. */
void Launcher_ResetArea(int x, int y, int width, int height);
/* Marks the given area/region as needing to be redrawn. */
CC_NOINLINE void Launcher_MarkDirty(int x, int y, int width, int height);
/* Sets currently active screen/menu, freeing old one. */ /* Sets currently active screen/menu, freeing old one. */
void Launcher_SetScreen(struct LScreen* screen); void Launcher_SetScreen(struct LScreen* screen);
/* Attempts to start the game by connecting to the given server. */ /* Attempts to start the game by connecting to the given server. */