diff --git a/src/LBackend.c b/src/LBackend.c index 1fa906d4d..96b4b7a55 100644 --- a/src/LBackend.c +++ b/src/LBackend.c @@ -27,9 +27,11 @@ struct FontDesc titleFont, textFont, hintFont; static struct LScreen* activeScreen; -static cc_uint8 pendingRedraw; -extern Rect2D dirty_rect; +/* 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. */ +static Rect2D dirty_rect; +static cc_uint8 pendingRedraw; #define REDRAW_ALL 0x02 #define REDRAW_SOME 0x01 @@ -101,6 +103,27 @@ static CC_NOINLINE void MarkAllDirty(void) { 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-------------------------------------------------------* @@ -126,7 +149,7 @@ static CC_NOINLINE void DrawWidget(struct LWidget* w) { w->dirty = false; 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) { @@ -151,8 +174,9 @@ static CC_NOINLINE void RedrawDirty(void) { /* check if widget might need redrawing of background behind */ 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); - Launcher_MarkDirty(w->last.X, w->last.Y, w->last.Width, w->last.Height); + s->ResetArea(&Launcher_Framebuffer, + 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); } @@ -355,19 +379,21 @@ void LBackend_InputInit(struct LInput* w, int width) { } 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) { DrawBoxBounds(color, w->x, w->y, w->width, w->height); } else { - Launcher_ResetArea(w->x, w->y, - w->width, yBorder); - Launcher_ResetArea(w->x, w->y + w->height - yBorder, - w->width, yBorder); - Launcher_ResetArea(w->x, w->y, - xBorder, w->height); - Launcher_ResetArea(w->x + w->width - xBorder, w->y, - xBorder, w->height); + s->ResetArea(bmp, w->x, w->y, + w->width, yBorder); + s->ResetArea(bmp, w->x, w->y + w->height - yBorder, + w->width, yBorder); + s->ResetArea(bmp, w->x, w->y, + xBorder, w->height); + s->ResetArea(bmp, w->x + w->width - xBorder, w->y, + xBorder, w->height); } } @@ -543,9 +569,9 @@ void LBackend_InputTick(struct LInput* w) { if (Rect2D_Equals(r, lastCaretRec)) { /* 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 { - Launcher_MarkDirty(w->x, w->y, w->width, w->height); + MarkAreaDirty(w->x, w->y, w->width, w->height); } lastCaretRec = r; } @@ -694,7 +720,8 @@ static void LTable_DrawHeaderBackground(struct LTable* w) { Drawer2D_Clear(&Launcher_Framebuffer, gridColor, w->x, w->y, w->width, w->hdrHeight); } 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) { Drawer2D_Clear(&Launcher_Framebuffer, color, - w->x, y, w->width, height); + w->x, y, w->width, height); } else { - Launcher_ResetArea(w->x, y, w->width, height); + Launcher_DrawBackground(&Launcher_Framebuffer, + w->x, y, w->width, height); } } } diff --git a/src/LScreens.c b/src/LScreens.c index 840bef657..e9b2f80af 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -195,6 +195,7 @@ CC_NOINLINE static void LScreen_Reset(struct LScreen* s) { s->MouseWheel = LScreen_MouseWheel; s->TextChanged = LScreen_TextChanged; s->DrawBackground = LScreen_DrawBackground; + s->ResetArea = Launcher_DrawBackground; /* reset all widgets mouse state */ 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_FORE_COLOR BitmapCol_Make(120, 85, 151, 255) -static void CheckResourcesScreen_ResetArea(int x, int y, int width, int height) { - Gradient_Noise(&Launcher_Framebuffer, RESOURCES_FORE_COLOR, 4, x, y, width, height); - Launcher_MarkDirty(x, y, width, height); +static void CheckResourcesScreen_ResetArea(struct Bitmap* bmp, int x, int y, int width, int height) { + Gradient_Noise(bmp, RESOURCES_FORE_COLOR, 4, x, y, width, height); } 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); 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) { @@ -1132,6 +1132,7 @@ void CheckResourcesScreen_SetActive(void) { s->Show = CheckResourcesScreen_Show; s->Layout = CheckResourcesScreen_Layout; s->DrawBackground = CheckResourcesScreen_DrawBackground; + s->ResetArea = CheckResourcesScreen_ResetArea; s->onEnterWidget = (struct LWidget*)&s->btnYes; 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); } -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) { cc_string str; char strBuffer[STRING_SIZE]; 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); if (String_Equals(&str, &s->lblStatus.text)) return; - FetchResourcesScreen_SetStatus(s, &str); + LLabel_SetText(&s->lblStatus, &str); } static void FetchResourcesScreen_UpdateProgress(struct FetchResourcesScreen* s) { @@ -1213,7 +1206,7 @@ static void FetchResourcesScreen_Error(struct FetchResourcesScreen* s) { String_InitArray(str, buffer); 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_) { @@ -1238,6 +1231,7 @@ void FetchResourcesScreen_SetActive(void) { s->Tick = FetchResourcesScreen_Tick; s->Layout = FetchResourcesScreen_Layout; s->DrawBackground = CheckResourcesScreen_DrawBackground; + s->ResetArea = CheckResourcesScreen_ResetArea; Launcher_SetScreen((struct LScreen*)s); } diff --git a/src/LScreens.h b/src/LScreens.h index babe5a12b..77602b686 100644 --- a/src/LScreens.h +++ b/src/LScreens.h @@ -24,6 +24,7 @@ typedef void (*LScreen_Func)(struct LScreen* s); void (*MouseMove)(struct LScreen* s, int idx); \ void (*MouseWheel)(struct LScreen* s, float delta); \ 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* hoveredWidget; /* Widget the mouse is currently hovering over. */ \ struct LWidget* selectedWidget; /* Widget mouse last clicked on. */ \ diff --git a/src/LWidgets.h b/src/LWidgets.h index 51dddf4aa..b3c96ffdc 100644 --- a/src/LWidgets.h +++ b/src/LWidgets.h @@ -40,7 +40,7 @@ struct LWidgetVTABLE { 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_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 */ \ void (*OnClick)(void* widget); /* Called when widget is clicked */ \ void (*OnHover)(void* widget); /* Called when widget is hovered over */ \ diff --git a/src/Launcher.c b/src/Launcher.c index e00401cbc..7bfa1f7d9 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -21,10 +21,6 @@ #include "LBackend.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; struct Bitmap Launcher_Framebuffer; struct FontDesc Launcher_LogoFont; @@ -517,29 +513,4 @@ void Launcher_UpdateLogoFont(void) { Drawer2D_MakeFont(&Launcher_LogoFont, 32, FONT_FLAGS_NONE); 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 diff --git a/src/Launcher.h b/src/Launcher.h index 7564e7cfb..c8cc2a2b4 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -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 */ 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. */ void Launcher_SetScreen(struct LScreen* screen); /* Attempts to start the game by connecting to the given server. */