3.8 KiB
UI System
Source: src/dusk/ui/
The UI system is an immediate-mode layer drawn on top of the game scene each frame. Elements register themselves; uiUpdate() ticks all elements and uiRender() draws them. All coordinates are in screen pixels.
Lifecycle
uiInit() → uiTextboxInit() // init order matters — textbox depends on display being ready
uiUpdate() // each frame, before rendering
uiRender() // each frame, after scene render
uiDispose()
uiTextboxDispose()
Element registration (ui/uielement.h)
Elements are stored in UI_ELEMENTS[]. Each has a type and a draw callback:
typedef struct {
uielementtype_t type;
errorret_t (*draw)();
} uielement_t;
Currently UI_ELEMENT_TYPE_NATIVE elements call their draw function directly. New debug/HUD elements are registered by adding to this array.
Textbox (ui/uitextbox.h)
UI_TEXTBOX is the global dialogue box. It word-wraps text, paginates it, and plays a typewriter scroll effect.
uiTextboxSetText("Long dialogue string..."); // wraps to charsPerLine, paginates
uiTextboxUpdate(); // each frame: advance scroll, check input
uiTextboxDraw(); // draw box + text
// Pagination:
uiTextboxPageIsComplete() // true when all chars of current page are visible
uiTextboxHasNextPage()
uiTextboxNextPage()
// Subscibe to page events:
eventSubscribe(&UI_TEXTBOX.onPageComplete, cb, user);
eventSubscribe(&UI_TEXTBOX.onLastPage, cb, user);
UI_TEXTBOX.advanceAction defaults to the input action that advances dialogue — set it before calling uiTextboxInit() if the default doesn't suit.
Layout constants:
UI_TEXTBOX_TEXT_MAX— 1024 charsUI_TEXTBOX_LINES_MAX— 64 linesUI_TEXTBOX_LINES_PER_PAGE_MAX— 3 lines visible at onceUI_TEXTBOX_SCROLL_CHARS_PER_TICK— 1 char per tick (typewriter speed)
The textbox uses UI_TEXTBOX.frame (a uiframe_t) for its border rendering and UI_TEXTBOX.font for text.
UI Frame (ui/uiframe.h)
9-slice bordered box rendered with a tileset:
uiFrameInit(&frame);
uiFrameDraw(&frame, x, y, width, height);
uiFrameDispose(&frame);
The tileset is loaded from the asset system during uiFrameInit(). The 9 slices are arranged in the tileset grid as: top-left corner, top edge, top-right corner, left edge, fill, right edge, bottom-left, bottom edge, bottom-right.
Loading overlay (ui/uiloading.h)
UI_LOADING is a full-screen loading indicator with fade-in/fade-out transitions:
uiLoadingShow(onShownCallback, user); // fade in; calls callback when fully opaque
uiLoadingHide(onHiddenCallback, user); // fade out; calls callback when fully transparent
uiLoadingUpdate(delta); // each frame
uiLoadingDraw(); // each frame, over everything
UI_LOADING_FADE_DURATION is FIXED(0.5f) seconds. Subscribe to UI_LOADING.onTransitionEnd for completion events.
Full-box overlay (ui/uifullbox.h)
Two global full-screen color overlays: UI_FULLBOX_UNDER (drawn before game content) and UI_FULLBOX_OVER (drawn after). Used for scene transitions (fade to black, etc.):
uiFullboxTransition(
&UI_FULLBOX_OVER,
COLOR_TRANSPARENT, COLOR_BLACK,
FIXED(0.5f),
EASING_IN_OUT_CUBIC
);
eventSubscribe(&UI_FULLBOX_OVER.onTransitionEnd, myCallback, NULL);
uiFullboxUnderDraw(); // draw under layer
uiFullboxOverDraw(); // draw over layer
FPS counter (ui/uifps.h)
UIFPS tracks a rolling average FPS. uiFPSDraw() renders it in the corner. Currently drawn as part of the debug HUD (not wired to an element slot).
Player position HUD (ui/uiplayerpos.h)
uiplayerpos.c draws the player's current world tile coordinates. Debug overlay, currently drawn directly in the scene render.