Start support for virtual dialogs

This commit is contained in:
UnknownShadow200 2025-11-08 16:07:52 +11:00
parent dca75bb289
commit db4ed0301a
6 changed files with 108 additions and 67 deletions

View File

@ -30,7 +30,7 @@
struct FontDesc titleFont, textFont, hintFont, logoFont, rowFont;
/* Contains the pixels that are drawn to the window */
static struct Context2D framebuffer;
struct Context2D LBackend_FB;
/* 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;
@ -191,13 +191,13 @@ void LBackend_NeedsRedraw(void* widget) {
}
void LBackend_MarkAllDirty(void) {
dirty_rect.x = 0; dirty_rect.width = framebuffer.width;
dirty_rect.y = 0; dirty_rect.height = framebuffer.height;
dirty_rect.x = 0; dirty_rect.width = LBackend_FB.width;
dirty_rect.y = 0; dirty_rect.height = LBackend_FB.height;
}
void LBackend_MarkAreaDirty(int x, int y, int width, int height) {
int x1, y1, x2, y2;
if (!Drawer2D_Clamp(&framebuffer, &x, &y, &width, &height)) return;
if (!Drawer2D_Clamp(&LBackend_FB, &x, &y, &width, &height)) return;
/* union with existing dirty area */
if (dirty_rect.width) {
@ -221,14 +221,15 @@ void LBackend_InitFramebuffer(void) {
int height = max(Window_Main.Height, 1);
Window_AllocFramebuffer(&bmp, width, height);
Context2D_Wrap(&framebuffer, &bmp);
Context2D_Wrap(&LBackend_FB, &bmp);
/* Backing surface may be bigger then valid area */
framebuffer.width = width;
framebuffer.height = height;
LBackend_FB.width = width;
LBackend_FB.height = height;
}
void LBackend_FreeFramebuffer(void) {
Window_FreeFramebuffer(&framebuffer.bmp);
Window_FreeFramebuffer(&LBackend_FB.bmp);
LBackend_FB.bmp.scan0 = NULL;
}
@ -236,16 +237,16 @@ void LBackend_FreeFramebuffer(void) {
*------------------------------------------------------Base drawing-------------------------------------------------------*
*#########################################################################################################################*/
static void DrawBoxBounds(BitmapCol color, int x, int y, int width, int height) {
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
x, y,
width, yBorder);
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
x, y + height - yBorder,
width, yBorder);
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
x, y,
xBorder, height);
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
x + width - xBorder, y,
xBorder, height);
}
@ -262,7 +263,7 @@ static CC_NOINLINE void DrawWidget(struct LWidget* w) {
static CC_NOINLINE void RedrawAll(void) {
struct LScreen* s = Launcher_Active;
int i;
s->DrawBackground(s, &framebuffer);
s->DrawBackground(s, &LBackend_FB);
for (i = 0; i < s->numWidgets; i++) {
DrawWidget(s->widgets[i]);
@ -281,7 +282,7 @@ 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) {
s->ResetArea(&framebuffer,
s->ResetArea(&LBackend_FB,
w->last.x, w->last.y, w->last.width, w->last.height);
LBackend_MarkAreaDirty(w->last.x, w->last.y, w->last.width, w->last.height);
}
@ -320,9 +321,9 @@ void LBackend_Tick(void) {
for (i = 0; i < Array_Elems(LBackend_Hooks); i++)
{
if (LBackend_Hooks[i]) LBackend_Hooks[i](&framebuffer);
if (LBackend_Hooks[i]) LBackend_Hooks[i]();
}
Window_DrawFramebuffer(dirty_rect, &framebuffer.bmp);
Window_DrawFramebuffer(dirty_rect, &LBackend_FB.bmp);
dirty_rect.x = 0; dirty_rect.width = 0;
dirty_rect.y = 0; dirty_rect.height = 0;
@ -469,13 +470,13 @@ void LBackend_ButtonDraw(struct LButton* w) {
int xOffset, yOffset;
cc_bool active = w->hovered || w->selected;
LButton_DrawBackground(&framebuffer, w->x, w->y, w->width, w->height, active);
LButton_DrawBackground(&LBackend_FB, w->x, w->y, w->width, w->height, active);
xOffset = w->width - w->_textWidth;
yOffset = w->height - w->_textHeight;
DrawTextArgs_Make(&args, &w->text, &titleFont, true);
if (!active) Drawer2D.Colors['f'] = Drawer2D.Colors['7'];
Context2D_DrawText(&framebuffer, &args,
Context2D_DrawText(&LBackend_FB, &args,
w->x + xOffset / 2, w->y + yOffset / 2);
if (!active) Drawer2D.Colors['f'] = Drawer2D.Colors['F'];
@ -571,23 +572,23 @@ void LBackend_CheckboxDraw(struct LCheckbox* w) {
width = Display_ScaleX(CB_SIZE);
height = Display_ScaleY(CB_SIZE);
Gradient_Vertical(&framebuffer, boxTop, boxBottom,
Gradient_Vertical(&LBackend_FB, boxTop, boxBottom,
w->x, w->y, width, height / 2);
Gradient_Vertical(&framebuffer, boxBottom, boxTop,
Gradient_Vertical(&LBackend_FB, boxBottom, boxTop,
w->x, w->y + height / 2, width, height / 2);
if (w->value) {
const int size = 12;
x = w->x + width / 2 - size / 2;
y = w->y + height / 2 - size / 2;
DrawIndexed(size, x, y, &framebuffer);
DrawIndexed(size, x, y, &LBackend_FB);
}
DrawBoxBounds(BITMAPCOLOR_BLACK, w->x, w->y, width, height);
DrawTextArgs_Make(&args, &w->text, &textFont, true);
x = w->x + Display_ScaleX(CB_SIZE + CB_OFFSET);
y = w->y + (height - Drawer2D_TextHeight(&args)) / 2;
Context2D_DrawText(&framebuffer, &args, x, y);
Context2D_DrawText(&LBackend_FB, &args, x, y);
}
@ -735,7 +736,7 @@ void LBackend_InputUnselect(struct LInput* w) {
static void LInput_DrawOuterBorder(struct LInput* w) {
struct LScreen* s = Launcher_Active;
struct Context2D* ctx = &framebuffer;
struct Context2D* ctx = &LBackend_FB;
BitmapCol color = Launcher_Theme.ButtonBorderColor;
if (w->selected) {
@ -756,16 +757,16 @@ static void LInput_DrawInnerBorder(struct LInput* w) {
/* e.g. for modern theme: 162,131,186 --> 165,142,168 */
BitmapCol color = BitmapColor_Offset(Launcher_Theme.ButtonHighlightColor, 3,11,-18);
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
w->x + xBorder, w->y + yBorder,
w->width - xBorder2, yBorder);
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
w->x + xBorder, w->y + w->height - yBorder2,
w->width - xBorder2, yBorder);
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
w->x + xBorder, w->y + yBorder,
xBorder, w->height - yBorder2);
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
w->x + w->width - xBorder2, w->y + yBorder,
xBorder, w->height - yBorder2);
}
@ -773,13 +774,13 @@ static void LInput_DrawInnerBorder(struct LInput* w) {
static void LInput_BlendBoxTop(struct LInput* w) {
BitmapCol color = BitmapColor_RGB(0, 0, 0);
Gradient_Blend(&framebuffer, color, 75,
Gradient_Blend(&LBackend_FB, color, 75,
w->x + xBorder, w->y + yBorder,
w->width - xBorder2, yBorder);
Gradient_Blend(&framebuffer, color, 50,
Gradient_Blend(&LBackend_FB, color, 50,
w->x + xBorder, w->y + yBorder2,
w->width - xBorder2, yBorder);
Gradient_Blend(&framebuffer, color, 25,
Gradient_Blend(&LBackend_FB, color, 25,
w->x + xBorder, w->y + yBorder3,
w->width - xBorder2, yBorder);
}
@ -789,7 +790,7 @@ static void LInput_DrawText(struct LInput* w, struct DrawTextArgs* args) {
if (w->text.length || !w->hintText) {
y = w->y + (w->height - w->_textHeight) / 2;
Context2D_DrawText(&framebuffer, args,
Context2D_DrawText(&LBackend_FB, args,
w->x + xInputOffset, y + yInputOffset);
} else {
args->text = String_FromReadonly(w->hintText);
@ -799,7 +800,7 @@ static void LInput_DrawText(struct LInput* w, struct DrawTextArgs* args) {
y = w->y + (w->height - hintHeight) / 2;
Drawer2D.Colors['f'] = BitmapColor_RGB(125, 125, 125);
Context2D_DrawText(&framebuffer, args,
Context2D_DrawText(&LBackend_FB, args,
w->x + xInputOffset, y);
Drawer2D.Colors['f'] = BITMAPCOLOR_WHITE;
}
@ -815,7 +816,7 @@ void LBackend_InputDraw(struct LInput* w) {
LInput_DrawOuterBorder(w);
LInput_DrawInnerBorder(w);
Context2D_Clear(&framebuffer, BITMAPCOLOR_WHITE,
Context2D_Clear(&LBackend_FB, BITMAPCOLOR_WHITE,
w->x + xBorder2, w->y + yBorder2,
w->width - xBorder4, w->height - yBorder4);
LInput_BlendBoxTop(w);
@ -826,7 +827,7 @@ void LBackend_InputDraw(struct LInput* w) {
caretRect = LInput_MeasureCaret(w, &text);
if (!w->caretShow) return;
Context2D_Clear(&framebuffer, BITMAPCOLOR_BLACK,
Context2D_Clear(&LBackend_FB, BITMAPCOLOR_BLACK,
caretRect.x, caretRect.y, caretRect.width, caretRect.height);
}
@ -849,7 +850,7 @@ void LBackend_LabelUpdate(struct LLabel* w) {
void LBackend_LabelDraw(struct LLabel* w) {
struct DrawTextArgs args;
DrawTextArgs_Make(&args, &w->text, LLabel_GetFont(w), true);
Context2D_DrawText(&framebuffer, &args, w->x, w->y);
Context2D_DrawText(&LBackend_FB, &args, w->x, w->y);
}
@ -863,7 +864,7 @@ void LBackend_LineInit(struct LLine* w, int width) {
void LBackend_LineDraw(struct LLine* w) {
BitmapCol color = LLine_GetColor();
Gradient_Blend(&framebuffer, color, 128, w->x, w->y, w->width, w->height);
Gradient_Blend(&LBackend_FB, color, 128, w->x, w->y, w->width, w->height);
}
@ -884,17 +885,17 @@ static void LSlider_DrawBoxBounds(struct LSlider* w) {
BitmapCol boundsBottom = BitmapColor_RGB(150, 130, 165);
/* TODO: Check these are actually right */
Context2D_Clear(&framebuffer, boundsTop,
Context2D_Clear(&LBackend_FB, boundsTop,
w->x, w->y,
w->width, yBorder);
Context2D_Clear(&framebuffer, boundsBottom,
Context2D_Clear(&LBackend_FB, boundsBottom,
w->x, w->y + w->height - yBorder,
w->width, yBorder);
Gradient_Vertical(&framebuffer, boundsTop, boundsBottom,
Gradient_Vertical(&LBackend_FB, boundsTop, boundsBottom,
w->x, w->y,
xBorder, w->height);
Gradient_Vertical(&framebuffer, boundsTop, boundsBottom,
Gradient_Vertical(&LBackend_FB, boundsTop, boundsBottom,
w->x + w->width - xBorder, w->y,
xBorder, w->height);
}
@ -904,10 +905,10 @@ static void LSlider_DrawBox(struct LSlider* w) {
BitmapCol progBottom = BitmapColor_RGB(207, 181, 216);
int halfHeight = (w->height - yBorder2) / 2;
Gradient_Vertical(&framebuffer, progTop, progBottom,
Gradient_Vertical(&LBackend_FB, progTop, progBottom,
w->x + xBorder, w->y + yBorder,
w->width - xBorder2, halfHeight);
Gradient_Vertical(&framebuffer, progBottom, progTop,
Gradient_Vertical(&LBackend_FB, progBottom, progTop,
w->x + xBorder, w->y + yBorder + halfHeight,
w->width - xBorder2, halfHeight);
}
@ -919,7 +920,7 @@ void LBackend_SliderDraw(struct LSlider* w) {
LSlider_DrawBox(w);
curWidth = (int)((w->width - xBorder2) * w->value / LSLIDER_MAXVALUE);
Context2D_Clear(&framebuffer, w->color,
Context2D_Clear(&LBackend_FB, w->color,
w->x + xBorder, w->y + yBorder,
curWidth, w->height - yBorder2);
}
@ -971,10 +972,10 @@ static void LTable_DrawHeaderBackground(struct LTable* w) {
BitmapCol gridColor = BitmapColor_RGB(20, 20, 10);
if (!Launcher_Theme.ClassicBackground) {
Context2D_Clear(&framebuffer, gridColor,
Context2D_Clear(&LBackend_FB, gridColor,
w->x, w->y, w->width, w->hdrHeight);
} else {
Launcher_DrawBackground(&framebuffer,
Launcher_DrawBackground(&LBackend_FB,
w->x, w->y, w->width, w->hdrHeight);
}
}
@ -1002,10 +1003,10 @@ static void LTable_DrawRowsBackground(struct LTable* w) {
if (height < 0) break;
if (color) {
Context2D_Clear(&framebuffer, color,
Context2D_Clear(&LBackend_FB, color,
w->x, y, w->width, height);
} else {
Launcher_DrawBackground(&framebuffer,
Launcher_DrawBackground(&LBackend_FB,
w->x, y, w->width, height);
}
}
@ -1017,14 +1018,14 @@ static void LTable_DrawGridlines(struct LTable* w) {
if (Launcher_Theme.ClassicBackground) return;
x = w->x;
Context2D_Clear(&framebuffer, Launcher_Theme.BackgroundColor,
Context2D_Clear(&LBackend_FB, Launcher_Theme.BackgroundColor,
x, w->y + w->hdrHeight, w->width, gridlineHeight);
for (i = 0; i < w->numColumns; i++) {
x += w->columns[i].width;
if (!w->columns[i].hasGridline) continue;
Context2D_Clear(&framebuffer, Launcher_Theme.BackgroundColor,
Context2D_Clear(&LBackend_FB, Launcher_Theme.BackgroundColor,
x, w->y, gridlineWidth, w->height);
x += gridlineWidth;
}
@ -1047,7 +1048,7 @@ static void LTable_DrawHeaders(struct LTable* w) {
for (i = 0; i < w->numColumns; i++) {
args.text = String_FromReadonly(w->columns[i].name);
Drawer2D_DrawClippedText(&framebuffer, &args,
Drawer2D_DrawClippedText(&LBackend_FB, &args,
x + cellXOffset, y + hdrYOffset,
w->columns[i].width - cellXPadding);
@ -1081,10 +1082,10 @@ static void LTable_DrawRows(struct LTable* w) {
for (i = 0; i < w->numColumns; i++) {
args.text = str; cell.x = x; cell.y = y;
cell.width = w->columns[i].width;
w->columns[i].DrawRow(entry, &args, &cell, &framebuffer);
w->columns[i].DrawRow(entry, &args, &cell, &LBackend_FB);
if (args.text.length) {
Drawer2D_DrawClippedText(&framebuffer, &args,
Drawer2D_DrawClippedText(&LBackend_FB, &args,
x + cellXOffset, y + rowYOffset,
cell.width - cellXPadding);
}
@ -1106,9 +1107,9 @@ static void LTable_DrawScrollbar(struct LTable* w) {
x = w->x + w->width - scrollbarWidth;
LTable_GetScrollbarCoords(w, &y, &height);
Context2D_Clear(&framebuffer, backCol,
Context2D_Clear(&LBackend_FB, backCol,
x, w->y, scrollbarWidth, w->height);
Context2D_Clear(&framebuffer, scrollCol,
Context2D_Clear(&LBackend_FB, scrollCol,
x, w->y + y, scrollbarWidth, height);
}

View File

@ -19,7 +19,8 @@ struct LSlider;
struct LTable;
struct Flag;
typedef void (*LBackend_DrawHook)(struct Context2D* ctx);
typedef void (*LBackend_DrawHook)(void);
extern struct Context2D LBackend_FB;
extern LBackend_DrawHook LBackend_Hooks[4];
void LBackend_Init(void);

View File

@ -20,9 +20,9 @@ static void VirtualCursor_Draw(struct Context2D* ctx, int x, int y) {
x - CURSOR_SIZE, y - CURSOR_EXTENT, CURSOR_SIZE * 3, CURSOR_EXTENT * 2);
}
static void VirtualCursor_Display2D(struct Context2D* ctx) {
static void VirtualCursor_Display2D(void) {
LBackend_MarkAllDirty();
VirtualCursor_Draw(ctx, Pointers[0].x, Pointers[0].y);
VirtualCursor_Draw(&LBackend_FB, Pointers[0].x, Pointers[0].y);
}
static void VirtualCursor_MakeTexture(void) {

35
src/VirtualDialog.h Normal file
View File

@ -0,0 +1,35 @@
#include "Core.h"
#include "Funcs.h"
#include "Drawer2D.h"
#include "Utils.h"
#include "LBackend.h"
#include "Window.h"
static void VirtualDialog_Show(const char* title, const char* message) {
struct Bitmap bmp;
Platform_LogConst(title);
Platform_LogConst(message);
if (!LBackend_FB.bmp.scan0) {
Window_AllocFramebuffer(&bmp, Window_Main.Width, Window_Main.Height);
} else {
bmp = LBackend_FB.bmp;
}
struct Context2D ctx;
Context2D_Wrap(&ctx, &bmp);
Context2D_Clear(&ctx, BitmapCol_Make(200, 200, 200, 255),
0, 0, bmp.width, bmp.height);
for (int i = 0; i < 1000; i++) {
Rect2D rect = { 0, 0, bmp.width, bmp.height };
Window_DrawFramebuffer(rect, &bmp);
Thread_Sleep(50);
}
if (!LBackend_FB.bmp.scan0) {
Window_FreeFramebuffer(&bmp);
} else {
LBackend_Redraw();
}
}

View File

@ -348,16 +348,16 @@ static void VirtualKeyboard_MarkDirty2D(void) {
LBackend_MarkAllDirty();
}
static void VirtualKeyboard_Display2D(struct Context2D* real_ctx) {
static void VirtualKeyboard_Display2D(void) {
struct Bitmap copy = LBackend_FB.bmp;
struct Context2D ctx;
struct Bitmap copy = real_ctx->bmp;
int x, y;
if (!DisplayInfo.ShowingSoftKeyboard) return;
LBackend_MarkAllDirty();
VirtualKeyboard_CalcPosition(&x, &y, copy.width, copy.height);
copy.scan0 = Bitmap_GetRow(&real_ctx->bmp, y);
copy.scan0 = Bitmap_GetRow(&copy, y);
copy.scan0 += x;
Context2D_Wrap(&ctx, &copy);

View File

@ -9,6 +9,7 @@
#include "../Errors.h"
#include "../ExtMath.h"
#include "../Camera.h"
#include <nds.h>
#include <fat.h>
@ -127,9 +128,6 @@ static void Console_Init(cc_bool onSub) {
/*########################################################################################################################*
*------------------------------------------------------General data-------------------------------------------------------*
*#########################################################################################################################*/
static int bg_id;
static u16* bg_ptr;
struct _DisplayData DisplayInfo;
struct cc_window WindowInfo;
@ -162,6 +160,7 @@ static void SetupVideo(cc_bool is3D) {
}
void Window_PreInit(void) {
Window_Main.Is3D = 210; // So SetupVideo still runs
SetupVideo(false);
setBrightness(2, 0);
}
@ -182,14 +181,13 @@ void Window_Init(void) {
Window_Main.SoftKeyboard = SOFT_KEYBOARD_RESIZE;
Input_SetTouchMode(true);
Window_ShowDialog("AC", "DE");
}
void Window_Free(void) { }
void Window_Create2D(int width, int height) {
SetupVideo(false);
bg_id = bgInitSub(2, BgType_Bmp16, BgSize_B16_256x256, 2, 0);
bg_ptr = bgGetGfxPtr(bg_id);
}
void Window_Create3D(int width, int height) {
@ -300,10 +298,16 @@ void Gamepads_Process(float delta) {
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
static int bg_id;
static u16* bg_ptr;
void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) {
bmp->scan0 = (BitmapCol*)Mem_Alloc(width * height, BITMAPCOLOR_SIZE, "window pixels");
bmp->width = width;
bmp->height = height;
bg_id = bgInitSub(2, BgType_Bmp16, BgSize_B16_256x256, 2, 0);
bg_ptr = bgGetGfxPtr(bg_id);
}
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
@ -381,9 +385,9 @@ void OnscreenKeyboard_Close(void) {
*-------------------------------------------------------Misc/Other--------------------------------------------------------*
*#########################################################################################################################*/
void Window_ShowDialog(const char* title, const char* msg) {
/* TODO implement */
Platform_LogConst(title);
Platform_LogConst(msg);
Platform_LogConst(message);
// TODO
}
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {