From 55d74709b18bfecd7fc7890072d2ae40f359540a Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 20 Jun 2021 14:52:06 +1000 Subject: [PATCH] Launcher: WIP on splitting off drawing into separate backend module --- src/ClassiCube.vcxproj | 2 + src/ClassiCube.vcxproj.filters | 6 + src/LBackend.c | 349 +++++++++++++++++++++++++++++++++ src/LBackend.h | 29 +++ src/LWidgets.c | 236 +--------------------- src/Launcher.c | 57 +----- 6 files changed, 401 insertions(+), 278 deletions(-) create mode 100644 src/LBackend.c create mode 100644 src/LBackend.h diff --git a/src/ClassiCube.vcxproj b/src/ClassiCube.vcxproj index cf6d0a7ee..04fb13240 100644 --- a/src/ClassiCube.vcxproj +++ b/src/ClassiCube.vcxproj @@ -188,6 +188,7 @@ + @@ -274,6 +275,7 @@ + diff --git a/src/ClassiCube.vcxproj.filters b/src/ClassiCube.vcxproj.filters index d1b1ea021..68b4e247a 100644 --- a/src/ClassiCube.vcxproj.filters +++ b/src/ClassiCube.vcxproj.filters @@ -315,6 +315,9 @@ Header Files\Platform + + Header Files\Launcher + @@ -545,5 +548,8 @@ Source Files\Platform + + Source Files\Launcher + \ No newline at end of file diff --git a/src/LBackend.c b/src/LBackend.c new file mode 100644 index 000000000..f730cae14 --- /dev/null +++ b/src/LBackend.c @@ -0,0 +1,349 @@ +#include "LBackend.h" +#ifndef CC_BUILD_WEB +#include "Launcher.h" +#include "Drawer2D.h" +#include "Window.h" +#include "LWidgets.h" +#include "String.h" +#include "Gui.h" +#include "Drawer2D.h" +#include "Launcher.h" +#include "ExtMath.h" +#include "Window.h" +#include "Funcs.h" +#include "LWeb.h" +#include "Platform.h" +#include "LScreens.h" +#include "Input.h" +#include "Utils.h" + +static struct Bitmap dirtBmp, stoneBmp; +#define TILESIZE 48 + +/*########################################################################################################################* +*--------------------------------------------------------Launcher---------------------------------------------------------* +*#########################################################################################################################*/ +cc_bool LBackend_HasTextures(void) { return dirtBmp.scan0 != NULL; } + +void LBackend_LoadTextures(struct Bitmap* bmp) { + int tileSize = bmp->width / 16; + Bitmap_Allocate(&dirtBmp, TILESIZE, TILESIZE); + Bitmap_Allocate(&stoneBmp, TILESIZE, TILESIZE); + + /* Precompute the scaled background */ + Bitmap_Scale(&dirtBmp, bmp, 2 * tileSize, 0, tileSize, tileSize); + Bitmap_Scale(&stoneBmp, bmp, 1 * tileSize, 0, tileSize, tileSize); + + Gradient_Tint(&dirtBmp, 128, 64, 0, 0, TILESIZE, TILESIZE); + Gradient_Tint(&stoneBmp, 96, 96, 0, 0, TILESIZE, TILESIZE); +} + +/* Fills the given area using pixels from the source bitmap, by repeatedly tiling the bitmap */ +CC_NOINLINE static void ClearTile(int x, int y, int width, int height, struct Bitmap* src) { + struct Bitmap* dst = &Launcher_Framebuffer; + BitmapCol* dstRow; + BitmapCol* srcRow; + int xx, yy; + if (!Drawer2D_Clamp(dst, &x, &y, &width, &height)) return; + + for (yy = 0; yy < height; yy++) { + srcRow = Bitmap_GetRow(src, (y + yy) % TILESIZE); + dstRow = Bitmap_GetRow(dst, y + yy) + x; + + for (xx = 0; xx < width; xx++) { + dstRow[xx] = srcRow[(x + xx) % TILESIZE]; + } + } +} + +void LBackend_ResetArea(int x, int y, int width, int height) { + if (Launcher_ClassicBackground && dirtBmp.scan0) { + ClearTile(x, y, width, height, &stoneBmp); + } else { + Gradient_Noise(&Launcher_Framebuffer, Launcher_BackgroundCol, 6, x, y, width, height); + } +} + +void LBackend_ResetPixels(void) { + if (Launcher_ClassicBackground && dirtBmp.scan0) { + ClearTile(0, 0, WindowInfo.Width, TILESIZE, &dirtBmp); + ClearTile(0, TILESIZE, WindowInfo.Width, WindowInfo.Height - TILESIZE, &stoneBmp); + } else { + Launcher_ResetArea(0, 0, WindowInfo.Width, WindowInfo.Height); + } +} + + +/*########################################################################################################################* +*---------------------------------------------------------LWidget---------------------------------------------------------* +*#########################################################################################################################*/ +static int xBorder, xBorder2, xBorder3, xBorder4; +static int yBorder, yBorder2, yBorder3, yBorder4; +static int xInputOffset, yInputOffset, inputExpand; + +void LBackend_CalcOffsets(void) { + xBorder = Display_ScaleX(1); xBorder2 = xBorder * 2; xBorder3 = xBorder * 3; xBorder4 = xBorder * 4; + yBorder = Display_ScaleY(1); yBorder2 = yBorder * 2; yBorder3 = yBorder * 3; yBorder4 = yBorder * 4; + + xInputOffset = Display_ScaleX(5); + yInputOffset = Display_ScaleY(2); + inputExpand = Display_ScaleX(20); +} + + +/*########################################################################################################################* +*------------------------------------------------------ButtonWidget-------------------------------------------------------* +*#########################################################################################################################*/ +static BitmapCol LButton_Expand(BitmapCol a, int amount) { + int r, g, b; + r = BitmapCol_R(a) + amount; Math_Clamp(r, 0, 255); + g = BitmapCol_G(a) + amount; Math_Clamp(g, 0, 255); + b = BitmapCol_B(a) + amount; Math_Clamp(b, 0, 255); + return BitmapCol_Make(r, g, b, 255); +} + +static void LButton_DrawBackground(struct LButton* w) { + BitmapCol activeCol = BitmapCol_Make(126, 136, 191, 255); + BitmapCol inactiveCol = BitmapCol_Make(111, 111, 111, 255); + BitmapCol col; + + if (Launcher_ClassicBackground) { + col = w->hovered ? activeCol : inactiveCol; + Gradient_Noise(&Launcher_Framebuffer, col, 8, + w->x + xBorder, w->y + yBorder, + w->width - xBorder2, w->height - yBorder2); + } else { + col = w->hovered ? Launcher_ButtonForeActiveCol : Launcher_ButtonForeCol; + Gradient_Vertical(&Launcher_Framebuffer, LButton_Expand(col, 8), LButton_Expand(col, -8), + w->x + xBorder, w->y + yBorder, + w->width - xBorder2, w->height - yBorder2); + } +} + +static void LButton_DrawBorder(struct LButton* w) { + BitmapCol black = BitmapCol_Make(0, 0, 0, 255); + BitmapCol backCol = Launcher_ClassicBackground ? black : Launcher_ButtonBorderCol; + + Drawer2D_Clear(&Launcher_Framebuffer, backCol, + w->x + xBorder, w->y, + w->width - xBorder2, yBorder); + Drawer2D_Clear(&Launcher_Framebuffer, backCol, + w->x + xBorder, w->y + w->height - yBorder, + w->width - xBorder2, yBorder); + Drawer2D_Clear(&Launcher_Framebuffer, backCol, + w->x, w->y + yBorder, + xBorder, w->height - yBorder2); + Drawer2D_Clear(&Launcher_Framebuffer, backCol, + w->x + w->width - xBorder, w->y + yBorder, + xBorder, w->height - yBorder2); +} + +static void LButton_DrawHighlight(struct LButton* w) { + BitmapCol activeCol = BitmapCol_Make(189, 198, 255, 255); + BitmapCol inactiveCol = BitmapCol_Make(168, 168, 168, 255); + BitmapCol highlightCol; + + if (Launcher_ClassicBackground) { + highlightCol = w->hovered ? activeCol : inactiveCol; + Drawer2D_Clear(&Launcher_Framebuffer, highlightCol, + w->x + xBorder2, w->y + yBorder, + w->width - xBorder4, yBorder); + Drawer2D_Clear(&Launcher_Framebuffer, highlightCol, + w->x + xBorder, w->y + yBorder2, + xBorder, w->height - yBorder4); + } else if (!w->hovered) { + Drawer2D_Clear(&Launcher_Framebuffer, Launcher_ButtonHighlightCol, + w->x + xBorder2, w->y + yBorder, + w->width - xBorder4, yBorder); + } +} + +void LBackend_DrawButton(struct LButton* w) { + struct DrawTextArgs args; + int xOffset, yOffset; + + xOffset = w->width - w->_textWidth; + yOffset = w->height - w->_textHeight; + DrawTextArgs_Make(&args, &w->text, &Launcher_TitleFont, true); + + LButton_DrawBackground(w); + LButton_DrawBorder(w); + LButton_DrawHighlight(w); + + if (!w->hovered) Drawer2D.Colors['f'] = Drawer2D.Colors['7']; + Drawer2D_DrawText(&Launcher_Framebuffer, &args, + w->x + xOffset / 2, w->y + yOffset / 2); + + if (!w->hovered) Drawer2D.Colors['f'] = Drawer2D.Colors['F']; +} + + +/*########################################################################################################################* +*------------------------------------------------------InputWidget--------------------------------------------------------* +*#########################################################################################################################*/ +static void LInput_DrawOuterBorder(struct LInput* w) { + BitmapCol col = BitmapCol_Make(97, 81, 110, 255); + + if (w->selected) { + Drawer2D_Clear(&Launcher_Framebuffer, col, + w->x, w->y, + w->width, yBorder); + Drawer2D_Clear(&Launcher_Framebuffer, col, + w->x, w->y + w->height - yBorder, + w->width, yBorder); + Drawer2D_Clear(&Launcher_Framebuffer, col, + w->x, w->y, + xBorder, w->height); + Drawer2D_Clear(&Launcher_Framebuffer, col, + w->x + w->width - xBorder, w->y, + xBorder, 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); + } +} + +static void LInput_DrawInnerBorder(struct LInput* w) { + BitmapCol col = BitmapCol_Make(165, 142, 168, 255); + + Drawer2D_Clear(&Launcher_Framebuffer, col, + w->x + xBorder, w->y + yBorder, + w->width - xBorder2, yBorder); + Drawer2D_Clear(&Launcher_Framebuffer, col, + w->x + xBorder, w->y + w->height - yBorder2, + w->width - xBorder2, yBorder); + Drawer2D_Clear(&Launcher_Framebuffer, col, + w->x + xBorder, w->y + yBorder, + xBorder, w->height - yBorder2); + Drawer2D_Clear(&Launcher_Framebuffer, col, + w->x + w->width - xBorder2, w->y + yBorder, + xBorder, w->height - yBorder2); +} + +static void LInput_BlendBoxTop(struct LInput* w) { + BitmapCol col = BitmapCol_Make(0, 0, 0, 255); + + Gradient_Blend(&Launcher_Framebuffer, col, 75, + w->x + xBorder, w->y + yBorder, + w->width - xBorder2, yBorder); + Gradient_Blend(&Launcher_Framebuffer, col, 50, + w->x + xBorder, w->y + yBorder2, + w->width - xBorder2, yBorder); + Gradient_Blend(&Launcher_Framebuffer, col, 25, + w->x + xBorder, w->y + yBorder3, + w->width - xBorder2, yBorder); +} + +static void LInput_DrawText(struct LInput* w, struct DrawTextArgs* args) { + int y, hintHeight; + + if (w->text.length || !w->hintText) { + y = w->y + (w->height - w->_textHeight) / 2; + Drawer2D_DrawText(&Launcher_Framebuffer, args, + w->x + xInputOffset, y + yInputOffset); + } else { + args->text = String_FromReadonly(w->hintText); + args->font = &Launcher_HintFont; + + hintHeight = Drawer2D_TextHeight(args); + y = w->y + (w->height - hintHeight) / 2; + Drawer2D_DrawText(&Launcher_Framebuffer, args, + w->x + xInputOffset, y); + } +} + +void LBackend_DrawInput(struct LInput* w, const cc_string* text) { + struct DrawTextArgs args; + int textWidth; + DrawTextArgs_Make(&args, text, &Launcher_TextFont, false); + + textWidth = Drawer2D_TextWidth(&args); + w->width = max(w->minWidth, textWidth + inputExpand); + w->_textHeight = Drawer2D_TextHeight(&args); + + LInput_DrawOuterBorder(w); + LInput_DrawInnerBorder(w); + Drawer2D_Clear(&Launcher_Framebuffer, BITMAPCOL_WHITE, + w->x + xBorder2, w->y + yBorder2, + w->width - xBorder4, w->height - yBorder4); + LInput_BlendBoxTop(w); + + Drawer2D.Colors['f'] = Drawer2D.Colors['0']; + LInput_DrawText(w, &args); + Drawer2D.Colors['f'] = Drawer2D.Colors['F']; +} + + +/*########################################################################################################################* +*------------------------------------------------------LabelWidget--------------------------------------------------------* +*#########################################################################################################################*/ +void LBackend_DrawLabel(struct LLabel* w) { + struct DrawTextArgs args; + DrawTextArgs_Make(&args, &w->text, w->font, true); + Drawer2D_DrawText(&Launcher_Framebuffer, &args, w->x, w->y); +} + + +/*########################################################################################################################* +*-------------------------------------------------------LineWidget--------------------------------------------------------* +*#########################################################################################################################*/ +#define CLASSIC_LINE_COL BitmapCol_Make(128,128,128, 255) +void LBackend_DrawLine(struct LLine* w) { + BitmapCol col = Launcher_ClassicBackground ? CLASSIC_LINE_COL : Launcher_ButtonBorderCol; + Gradient_Blend(&Launcher_Framebuffer, col, 128, w->x, w->y, w->width, w->height); +} + + +/*########################################################################################################################* +*------------------------------------------------------SliderWidget-------------------------------------------------------* +*#########################################################################################################################*/ +static void LSlider_DrawBoxBounds(struct LSlider* w) { + BitmapCol boundsTop = BitmapCol_Make(119, 100, 132, 255); + BitmapCol boundsBottom = BitmapCol_Make(150, 130, 165, 255); + + /* TODO: Check these are actually right */ + Drawer2D_Clear(&Launcher_Framebuffer, boundsTop, + w->x, w->y, + w->width, yBorder); + Drawer2D_Clear(&Launcher_Framebuffer, boundsBottom, + w->x, w->y + w->height - yBorder, + w->width, yBorder); + + Gradient_Vertical(&Launcher_Framebuffer, boundsTop, boundsBottom, + w->x, w->y, + xBorder, w->height); + Gradient_Vertical(&Launcher_Framebuffer, boundsTop, boundsBottom, + w->x + w->width - xBorder, w->y, + xBorder, w->height); +} + +static void LSlider_DrawBox(struct LSlider* w) { + BitmapCol progTop = BitmapCol_Make(220, 204, 233, 255); + BitmapCol progBottom = BitmapCol_Make(207, 181, 216, 255); + int halfHeight = (w->height - yBorder2) / 2; + + Gradient_Vertical(&Launcher_Framebuffer, progTop, progBottom, + w->x + xBorder, w->y + yBorder, + w->width - xBorder2, halfHeight); + Gradient_Vertical(&Launcher_Framebuffer, progBottom, progTop, + w->x + xBorder, w->y + yBorder + halfHeight, + w->width - xBorder2, halfHeight); +} + +void LBackend_DrawSlider(struct LSlider* w) { + int curWidth; + LSlider_DrawBoxBounds(w); + LSlider_DrawBox(w); + + curWidth = (int)((w->width - xBorder2) * w->value / w->maxValue); + Drawer2D_Clear(&Launcher_Framebuffer, w->col, + w->x + xBorder, w->y + yBorder, + curWidth, w->height - yBorder2); +} +#endif diff --git a/src/LBackend.h b/src/LBackend.h new file mode 100644 index 000000000..c930159f1 --- /dev/null +++ b/src/LBackend.h @@ -0,0 +1,29 @@ +#ifndef CC_LBACKEND_H +#define CC_LBACKEND_H +#include "Core.h" +/* Implements the gui drawing backend for the Launcher + Copyright 2014-2021 ClassiCube | Licensed under BSD-3 +*/ +struct Bitmap; +struct LButton; +struct LInput; +struct LLabel; +struct LLine; +struct LSlider; + +/* Whether tiles have been extracted from a terrain atlas */ +cc_bool LBackend_HasTextures(void); +/* Extracts tiles from the given terrain atlas bitmap */ +void LBackend_LoadTextures(struct Bitmap* bmp); +/* Redraws the specified region with the background pixels */ +void LBackend_ResetArea(int x, int y, int width, int height); +/* Redraws all pixels with default background */ +void LBackend_ResetPixels(void); + +void LBackend_CalcOffsets(void); +void LBackend_DrawButton(struct LButton* w); +void LBackend_DrawInput(struct LInput* w, const cc_string* text); +void LBackend_DrawLabel(struct LLabel* w); +void LBackend_DrawLine(struct LLine* w); +void LBackend_DrawSlider(struct LSlider* w); +#endif diff --git a/src/LWidgets.c b/src/LWidgets.c index ef95b6bab..c0ef50871 100644 --- a/src/LWidgets.c +++ b/src/LWidgets.c @@ -12,9 +12,8 @@ #include "LScreens.h" #include "Input.h" #include "Utils.h" +#include "LBackend.h" -static int xBorder, xBorder2, xBorder3, xBorder4; -static int yBorder, yBorder2, yBorder3, yBorder4; static int xInputOffset, yInputOffset, inputExpand; static int caretOffset, caretWidth, caretHeight; static int scrollbarWidth, dragPad, gridlineWidth, gridlineHeight; @@ -23,9 +22,6 @@ static int cellXOffset, cellXPadding, cellMinWidth; static int flagXOffset, flagYOffset; void LWidget_CalcOffsets(void) { - xBorder = Display_ScaleX(1); xBorder2 = xBorder * 2; xBorder3 = xBorder * 3; xBorder4 = xBorder * 4; - yBorder = Display_ScaleY(1); yBorder2 = yBorder * 2; yBorder3 = yBorder * 3; yBorder4 = yBorder * 4; - xInputOffset = Display_ScaleX(5); yInputOffset = Display_ScaleY(2); inputExpand = Display_ScaleX(20); @@ -84,89 +80,11 @@ void LWidget_Redraw(void* widget) { /*########################################################################################################################* *------------------------------------------------------ButtonWidget-------------------------------------------------------* *#########################################################################################################################*/ -static BitmapCol LButton_Expand(BitmapCol a, int amount) { - int r, g, b; - r = BitmapCol_R(a) + amount; Math_Clamp(r, 0, 255); - g = BitmapCol_G(a) + amount; Math_Clamp(g, 0, 255); - b = BitmapCol_B(a) + amount; Math_Clamp(b, 0, 255); - return BitmapCol_Make(r, g, b, 255); -} - -static void LButton_DrawBackground(struct LButton* w) { - BitmapCol activeCol = BitmapCol_Make(126, 136, 191, 255); - BitmapCol inactiveCol = BitmapCol_Make(111, 111, 111, 255); - BitmapCol col; - - if (Launcher_ClassicBackground) { - col = w->hovered ? activeCol : inactiveCol; - Gradient_Noise(&Launcher_Framebuffer, col, 8, - w->x + xBorder, w->y + yBorder, - w->width - xBorder2, w->height - yBorder2); - } else { - col = w->hovered ? Launcher_ButtonForeActiveCol : Launcher_ButtonForeCol; - Gradient_Vertical(&Launcher_Framebuffer, LButton_Expand(col, 8), LButton_Expand(col, -8), - w->x + xBorder, w->y + yBorder, - w->width - xBorder2, w->height - yBorder2); - } -} - -static void LButton_DrawBorder(struct LButton* w) { - BitmapCol black = BitmapCol_Make(0, 0, 0, 255); - BitmapCol backCol = Launcher_ClassicBackground ? black : Launcher_ButtonBorderCol; - - Drawer2D_Clear(&Launcher_Framebuffer, backCol, - w->x + xBorder, w->y, - w->width - xBorder2, yBorder); - Drawer2D_Clear(&Launcher_Framebuffer, backCol, - w->x + xBorder, w->y + w->height - yBorder, - w->width - xBorder2, yBorder); - Drawer2D_Clear(&Launcher_Framebuffer, backCol, - w->x, w->y + yBorder, - xBorder, w->height - yBorder2); - Drawer2D_Clear(&Launcher_Framebuffer, backCol, - w->x + w->width - xBorder, w->y + yBorder, - xBorder, w->height - yBorder2); -} - -static void LButton_DrawHighlight(struct LButton* w) { - BitmapCol activeCol = BitmapCol_Make(189, 198, 255, 255); - BitmapCol inactiveCol = BitmapCol_Make(168, 168, 168, 255); - BitmapCol highlightCol; - - if (Launcher_ClassicBackground) { - highlightCol = w->hovered ? activeCol : inactiveCol; - Drawer2D_Clear(&Launcher_Framebuffer, highlightCol, - w->x + xBorder2, w->y + yBorder, - w->width - xBorder4, yBorder); - Drawer2D_Clear(&Launcher_Framebuffer, highlightCol, - w->x + xBorder, w->y + yBorder2, - xBorder, w->height - yBorder4); - } else if (!w->hovered) { - Drawer2D_Clear(&Launcher_Framebuffer, Launcher_ButtonHighlightCol, - w->x + xBorder2, w->y + yBorder, - w->width - xBorder4, yBorder); - } -} - static void LButton_Draw(void* widget) { struct LButton* w = (struct LButton*)widget; - struct DrawTextArgs args; - int xOffset, yOffset; if (w->hidden) return; - xOffset = w->width - w->_textWidth; - yOffset = w->height - w->_textHeight; - DrawTextArgs_Make(&args, &w->text, &Launcher_TitleFont, true); - - LButton_DrawBackground(w); - LButton_DrawBorder(w); - LButton_DrawHighlight(w); - - if (!w->hovered) Drawer2D.Colors['f'] = Drawer2D.Colors['7']; - Drawer2D_DrawText(&Launcher_Framebuffer, &args, - w->x + xOffset / 2, w->y + yOffset / 2); - - if (!w->hovered) Drawer2D.Colors['f'] = Drawer2D.Colors['F']; + LBackend_DrawButton(w); Launcher_MarkDirty(w->x, w->y, w->width, w->height); } @@ -212,107 +130,13 @@ CC_NOINLINE static void LInput_GetText(struct LInput* w, cc_string* text) { } } -static void LInput_DrawOuterBorder(struct LInput* w) { - BitmapCol col = BitmapCol_Make(97, 81, 110, 255); - - if (w->selected) { - Drawer2D_Clear(&Launcher_Framebuffer, col, - w->x, w->y, - w->width, yBorder); - Drawer2D_Clear(&Launcher_Framebuffer, col, - w->x, w->y + w->height - yBorder, - w->width, yBorder); - Drawer2D_Clear(&Launcher_Framebuffer, col, - w->x, w->y, - xBorder, w->height); - Drawer2D_Clear(&Launcher_Framebuffer, col, - w->x + w->width - xBorder, w->y, - xBorder, 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); - } -} - -static void LInput_DrawInnerBorder(struct LInput* w) { - BitmapCol col = BitmapCol_Make(165, 142, 168, 255); - - Drawer2D_Clear(&Launcher_Framebuffer, col, - w->x + xBorder, w->y + yBorder, - w->width - xBorder2, yBorder); - Drawer2D_Clear(&Launcher_Framebuffer, col, - w->x + xBorder, w->y + w->height - yBorder2, - w->width - xBorder2, yBorder); - Drawer2D_Clear(&Launcher_Framebuffer, col, - w->x + xBorder, w->y + yBorder, - xBorder, w->height - yBorder2); - Drawer2D_Clear(&Launcher_Framebuffer, col, - w->x + w->width - xBorder2, w->y + yBorder, - xBorder, w->height - yBorder2); -} - -static void LInput_BlendBoxTop(struct LInput* w) { - BitmapCol col = BitmapCol_Make(0, 0, 0, 255); - - Gradient_Blend(&Launcher_Framebuffer, col, 75, - w->x + xBorder, w->y + yBorder, - w->width - xBorder2, yBorder); - Gradient_Blend(&Launcher_Framebuffer, col, 50, - w->x + xBorder, w->y + yBorder2, - w->width - xBorder2, yBorder); - Gradient_Blend(&Launcher_Framebuffer, col, 25, - w->x + xBorder, w->y + yBorder3, - w->width - xBorder2, yBorder); -} - -static void LInput_DrawText(struct LInput* w, struct DrawTextArgs* args) { - int y, hintHeight; - - if (w->text.length || !w->hintText) { - y = w->y + (w->height - w->_textHeight) / 2; - Drawer2D_DrawText(&Launcher_Framebuffer, args, - w->x + xInputOffset, y + yInputOffset); - } else { - args->text = String_FromReadonly(w->hintText); - args->font = &Launcher_HintFont; - - hintHeight = Drawer2D_TextHeight(args); - y = w->y + (w->height - hintHeight) / 2; - Drawer2D_DrawText(&Launcher_Framebuffer, args, - w->x + xInputOffset, y); - } -} - static void LInput_Draw(void* widget) { struct LInput* w = (struct LInput*)widget; cc_string text; char textBuffer[STRING_SIZE]; - struct DrawTextArgs args; - int textWidth; String_InitArray(text, textBuffer); LInput_GetText(w, &text); - DrawTextArgs_Make(&args, &text, &Launcher_TextFont, false); - - textWidth = Drawer2D_TextWidth(&args); - w->width = max(w->minWidth, textWidth + inputExpand); - w->_textHeight = Drawer2D_TextHeight(&args); - - LInput_DrawOuterBorder(w); - LInput_DrawInnerBorder(w); - Drawer2D_Clear(&Launcher_Framebuffer, BITMAPCOL_WHITE, - w->x + xBorder2, w->y + yBorder2, - w->width - xBorder4, w->height - yBorder4); - LInput_BlendBoxTop(w); - - Drawer2D.Colors['f'] = Drawer2D.Colors['0']; - LInput_DrawText(w, &args); - Drawer2D.Colors['f'] = Drawer2D.Colors['F']; + LBackend_DrawInput(w, &text); } static Rect2D LInput_MeasureCaret(struct LInput* w) { @@ -604,10 +428,7 @@ void LInput_Clear(struct LInput* w) { *#########################################################################################################################*/ static void LLabel_Draw(void* widget) { struct LLabel* w = (struct LLabel*)widget; - struct DrawTextArgs args; - - DrawTextArgs_Make(&args, &w->text, w->font, true); - Drawer2D_DrawText(&Launcher_Framebuffer, &args, w->x, w->y); + LBackend_DrawLabel(w); } static const struct LWidgetVTABLE llabel_VTABLE = { @@ -642,13 +463,11 @@ void LLabel_SetConst(struct LLabel* w, const char* text) { /*########################################################################################################################* -*-------------------------------------------------------BoxWidget---------------------------------------------------------* +*-------------------------------------------------------LineWidget--------------------------------------------------------* *#########################################################################################################################*/ -#define CLASSIC_LINE_COL BitmapCol_Make(128,128,128, 255) static void LLine_Draw(void* widget) { struct LLine* w = (struct LLine*)widget; - BitmapCol col = Launcher_ClassicBackground ? CLASSIC_LINE_COL : Launcher_ButtonBorderCol; - Gradient_Blend(&Launcher_Framebuffer, col, 128, w->x, w->y, w->width, w->height); + LBackend_DrawLine(w); } static const struct LWidgetVTABLE lline_VTABLE = { @@ -668,50 +487,9 @@ void LLine_Init(struct LScreen* s, struct LLine* w, int width) { /*########################################################################################################################* *------------------------------------------------------SliderWidget-------------------------------------------------------* *#########################################################################################################################*/ -static void LSlider_DrawBoxBounds(struct LSlider* w) { - BitmapCol boundsTop = BitmapCol_Make(119, 100, 132, 255); - BitmapCol boundsBottom = BitmapCol_Make(150, 130, 165, 255); - - /* TODO: Check these are actually right */ - Drawer2D_Clear(&Launcher_Framebuffer, boundsTop, - w->x, w->y, - w->width, yBorder); - Drawer2D_Clear(&Launcher_Framebuffer, boundsBottom, - w->x, w->y + w->height - yBorder, - w->width, yBorder); - - Gradient_Vertical(&Launcher_Framebuffer, boundsTop, boundsBottom, - w->x, w->y, - xBorder, w->height); - Gradient_Vertical(&Launcher_Framebuffer, boundsTop, boundsBottom, - w->x + w->width - xBorder, w->y, - xBorder, w->height); -} - -static void LSlider_DrawBox(struct LSlider* w) { - BitmapCol progTop = BitmapCol_Make(220, 204, 233, 255); - BitmapCol progBottom = BitmapCol_Make(207, 181, 216, 255); - int halfHeight = (w->height - yBorder2) / 2; - - Gradient_Vertical(&Launcher_Framebuffer, progTop, progBottom, - w->x + xBorder, w->y + yBorder, - w->width - xBorder2, halfHeight); - Gradient_Vertical(&Launcher_Framebuffer, progBottom, progTop, - w->x + xBorder, w->y + yBorder + halfHeight, - w->width - xBorder2, halfHeight); -} - static void LSlider_Draw(void* widget) { struct LSlider* w = (struct LSlider*)widget; - int curWidth; - - LSlider_DrawBoxBounds(w); - LSlider_DrawBox(w); - - curWidth = (int)((w->width - xBorder2) * w->value / w->maxValue); - Drawer2D_Clear(&Launcher_Framebuffer, w->col, - w->x + xBorder, w->y + yBorder, - curWidth, w->height - yBorder2); + LBackend_DrawSlider(w); } static const struct LWidgetVTABLE lslider_VTABLE = { diff --git a/src/Launcher.c b/src/Launcher.c index a219d90e0..1661b6a4a 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -18,6 +18,7 @@ #include "Funcs.h" #include "Logger.h" #include "Options.h" +#include "LBackend.h" static struct LScreen* activeScreen; Rect2D Launcher_Dirty; @@ -35,8 +36,6 @@ cc_string Launcher_AutoHash = String_FromArray(hashBuffer); cc_string Launcher_Username = String_FromArray(userBuffer); static cc_bool useBitmappedFont, hasBitmappedFont; -static struct Bitmap dirtBmp, stoneBmp; -#define TILESIZE 48 static void CloseActiveScreen(void) { Window_CloseKeyboard(); @@ -283,6 +282,7 @@ void Launcher_Run(void) { Window_SetTitle(&title); Window_Show(); LWidget_CalcOffsets(); + LBackend_CalcOffsets(); #ifdef CC_BUILD_WIN /* clean leftover exe from updating */ @@ -417,19 +417,6 @@ static cc_bool Launcher_SelectZipEntry(const cc_string* path) { String_CaselessEqualsConst(path, "terrain.png"); } -static void LoadTextures(struct Bitmap* bmp) { - int tileSize = bmp->width / 16; - Bitmap_Allocate(&dirtBmp, TILESIZE, TILESIZE); - Bitmap_Allocate(&stoneBmp, TILESIZE, TILESIZE); - - /* Precompute the scaled background */ - Bitmap_Scale(&dirtBmp, bmp, 2 * tileSize, 0, tileSize, tileSize); - Bitmap_Scale(&stoneBmp, bmp, 1 * tileSize, 0, tileSize, tileSize); - - Gradient_Tint(&dirtBmp, 128, 64, 0, 0, TILESIZE, TILESIZE); - Gradient_Tint(&stoneBmp, 96, 96, 0, 0, TILESIZE, TILESIZE); -} - static cc_result Launcher_ProcessZipEntry(const cc_string* path, struct Stream* data, struct ZipState* s) { struct Bitmap bmp; cc_result res; @@ -448,13 +435,13 @@ static cc_result Launcher_ProcessZipEntry(const cc_string* path, struct Stream* Mem_Free(bmp.scan0); } } else if (String_CaselessEqualsConst(path, "terrain.png")) { - if (dirtBmp.scan0) return 0; + if (LBackend_HasTextures()) return 0; res = Png_Decode(&bmp, data); if (res) { Logger_SysWarn(res, "decoding terrain.png"); return res; } else { - LoadTextures(&bmp); + LBackend_LoadTextures(&bmp); } } return 0; @@ -479,7 +466,7 @@ static void ExtractTexturePack(const cc_string* path) { } void Launcher_TryLoadTexturePack(void) { - static const cc_string defZipPath = String_FromConst("texpacks/default.zip"); + static const cc_string defZip = String_FromConst("texpacks/default.zip"); cc_string path; char pathBuffer[FILENAME_SIZE]; cc_string texPack; @@ -496,7 +483,7 @@ void Launcher_TryLoadTexturePack(void) { } /* user selected texture pack is missing some required .png files */ - if (!hasBitmappedFont || !dirtBmp.scan0) ExtractTexturePack(&defZipPath); + if (!hasBitmappedFont || !LBackend_HasTextures()) ExtractTexturePack(&defZip); Launcher_UpdateLogoFont(); } @@ -507,30 +494,8 @@ void Launcher_UpdateLogoFont(void) { Drawer2D.BitmappedText = false; } -/* Fills the given area using pixels from the source bitmap, by repeatedly tiling the bitmap. */ -CC_NOINLINE static void ClearTile(int x, int y, int width, int height, struct Bitmap* src) { - struct Bitmap* dst = &Launcher_Framebuffer; - BitmapCol* dstRow; - BitmapCol* srcRow; - int xx, yy; - if (!Drawer2D_Clamp(dst, &x, &y, &width, &height)) return; - - for (yy = 0; yy < height; yy++) { - srcRow = Bitmap_GetRow(src, (y + yy) % TILESIZE); - dstRow = Bitmap_GetRow(dst, y + yy) + x; - - for (xx = 0; xx < width; xx++) { - dstRow[xx] = srcRow[(x + xx) % TILESIZE]; - } - } -} - void Launcher_ResetArea(int x, int y, int width, int height) { - if (Launcher_ClassicBackground && dirtBmp.scan0) { - ClearTile(x, y, width, height, &stoneBmp); - } else { - Gradient_Noise(&Launcher_Framebuffer, Launcher_BackgroundCol, 6, x, y, width, height); - } + LBackend_ResetArea(x, y, width, height); Launcher_MarkDirty(x, y, width, height); } @@ -545,13 +510,7 @@ void Launcher_ResetPixels(void) { return; } - if (Launcher_ClassicBackground && dirtBmp.scan0) { - ClearTile(0, 0, WindowInfo.Width, TILESIZE, &dirtBmp); - ClearTile(0, TILESIZE, WindowInfo.Width, WindowInfo.Height - TILESIZE, &stoneBmp); - } else { - Launcher_ResetArea(0, 0, WindowInfo.Width, WindowInfo.Height); - } - + LBackend_ResetPixels(); DrawTextArgs_Make(&args, &title_fore, &logoFont, false); x = WindowInfo.Width / 2 - Drawer2D_TextWidth(&args) / 2;