Scene loading example

This commit is contained in:
2026-05-26 21:42:37 -05:00
parent 7c4b8c307f
commit e24707c847
9 changed files with 187 additions and 11 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
/* Run the init script. */
consolePrint("Engine initialized");
sceneSet(SCENE_TYPE_OVERWORLD);
sceneSet(SCENE_TYPE_INITIAL);
errorOk();
}
+15
View File
@@ -7,12 +7,27 @@
#include "initialscene.h"
#include "console/console.h"
#include "scene/scene.h"
#include "time/time.h"
#include "ui/uiloading.h"
void initialSceneInit(void) {
consolePrint("Initial scene initialized");
SCENE.data.initial.timer = 0.0f;
SCENE.data.initial.hiding = false;
uiLoadingShow(NULL, NULL);
}
errorret_t initialSceneUpdate(void) {
initialscene_t *scene = &SCENE.data.initial;
if(scene->hiding) errorOk();
scene->timer += TIME.delta;
if(scene->timer >= INITIAL_SCENE_WAIT) {
scene->hiding = true;
uiLoadingHide(NULL, NULL);
}
errorOk();
}
+4 -1
View File
@@ -8,8 +8,11 @@
#pragma once
#include "error/error.h"
#define INITIAL_SCENE_WAIT 2.0f
typedef struct {
void *nothing;
float_t timer;
bool_t hiding;
} initialscene_t;
void initialSceneInit(void);
+1
View File
@@ -11,5 +11,6 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
uielement.c
uiframe.c
uifullbox.c
uiloading.c
uitextbox.c
)
+3
View File
@@ -12,6 +12,7 @@
#include "display/screen/screen.h"
#include "ui/uielement.h"
#include "ui/uifullbox.h"
#include "ui/uiloading.h"
#include "time/time.h"
#include "log/log.h"
@@ -19,6 +20,7 @@ ui_t UI;
errorret_t uiInit(void) {
memoryZero(&UI, sizeof(ui_t));
uiLoadingInit();
uielement_t *element = &UI_ELEMENTS[0];
while(element->type != UI_ELEMENT_TYPE_NULL) {
@@ -32,6 +34,7 @@ errorret_t uiInit(void) {
void uiUpdate(void) {
uiFullboxUpdate(&UI_FULLBOX_UNDER, TIME.delta);
uiFullboxUpdate(&UI_FULLBOX_OVER, TIME.delta);
uiLoadingUpdate(TIME.delta);
}
errorret_t uiRender(void) {
+4 -1
View File
@@ -12,6 +12,7 @@
#include "engine/engine.h"
#include "ui/uitextbox.h"
#include "ui/uifullbox.h"
#include "ui/uiloading.h"
uielement_t UI_ELEMENTS[] = {
// Fullbox under: above scene, below system UI.
@@ -20,10 +21,12 @@ uielement_t UI_ELEMENTS[] = {
// { .type = UI_ELEMENT_TYPE_SCRIPT, .script = { .script = "ui/test.js" } },
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = consoleDraw },
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFPSDraw },
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiTextboxDraw },
// Fullbox over: above absolutely everything.
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFullboxOverDraw },
// These render above the fullbox overlay.
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFPSDraw },
{ .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiLoadingDraw },
{ .type = UI_ELEMENT_TYPE_NULL },
};
+8 -8
View File
@@ -52,20 +52,20 @@ errorret_t uiFullboxDraw(uifullbox_t *fullbox) {
color_t color = uiFullboxGetColor(fullbox);
if(color.a == 0) errorOk();
errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, &TEXTURE_WHITE));
#if MESH_ENABLE_COLOR
#else
errorChain(shaderSetColor(&SHADER_UNLIT, SHADER_UNLIT_COLOR, color));
#endif
spritebatchsprite_t sprite;
spritebatchsprite_t sprite = {
.min = { 0.0f, 0.0f, 0.0f },
.max = { (float_t)SCREEN.width, (float_t)SCREEN.height, 0.0f },
.uvMin = { 0.0f, 0.0f },
.uvMax = { 1.0f, 1.0f }
};
shadermaterial_t material = {
.unlit = {
.color = color,
.texture = &TEXTURE_WHITE
}
};
return spriteBatchBuffer(&sprite, 1, &SHADER_UNLIT, material);
errorChain(spriteBatchBuffer(&sprite, 1, &SHADER_UNLIT, material));
return spriteBatchFlush();
}
void uiFullboxTransition(
+92
View File
@@ -0,0 +1,92 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "uiloading.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "display/text/text.h"
#include "display/screen/screen.h"
#include "display/spritebatch/spritebatch.h"
#include "ui/uifullbox.h"
#define UI_LOADING_TEXT "loading"
uiloading_t UI_LOADING;
void uiLoadingInit(void) {
memoryZero(&UI_LOADING, sizeof(uiloading_t));
eventInit(&UI_LOADING.onTransitionEnd);
}
void uiLoadingUpdate(float_t delta) {
if(UI_LOADING.duration <= 0.0f || UI_LOADING.time >= UI_LOADING.duration) return;
UI_LOADING.time += delta;
if(UI_LOADING.time >= UI_LOADING.duration) {
UI_LOADING.time = UI_LOADING.duration;
eventInvoke(&UI_LOADING.onTransitionEnd, &UI_LOADING);
}
}
errorret_t uiLoadingDraw(void) {
float_t alpha;
if(UI_LOADING.duration <= 0.0f || UI_LOADING.time >= UI_LOADING.duration) {
alpha = UI_LOADING.toAlpha;
} else {
float_t t = UI_LOADING.time / UI_LOADING.duration;
alpha = UI_LOADING.fromAlpha + (UI_LOADING.toAlpha - UI_LOADING.fromAlpha) * t;
}
if(alpha <= 0.0f) errorOk();
int32_t textW, textH;
textMeasure(UI_LOADING_TEXT, &FONT_DEFAULT, &textW, &textH);
float_t x = (float_t)SCREEN.width - (float_t)textW - UI_LOADING_MARGIN;
float_t y = (float_t)SCREEN.height - (float_t)textH - UI_LOADING_MARGIN;
color_t color = COLOR_WHITE;
color.a = (uint8_t)(alpha * 255.0f);
errorChain(textDraw(x, y, UI_LOADING_TEXT, color, &FONT_DEFAULT));
return spriteBatchFlush();
}
static void uiLoadingTransition(
const float_t from,
const float_t to,
const eventcallback_t callback,
void *user
) {
UI_LOADING.fromAlpha = from;
UI_LOADING.toAlpha = to;
UI_LOADING.duration = UI_LOADING_FADE_DURATION;
UI_LOADING.time = 0.0f;
eventInit(&UI_LOADING.onTransitionEnd);
if(callback) eventSubscribe(&UI_LOADING.onTransitionEnd, callback, user);
}
void uiLoadingShow(eventcallback_t callback, void *user) {
uiLoadingTransition(0.0f, 1.0f, callback, user);
uiFullboxTransition(
&UI_FULLBOX_OVER,
COLOR_TRANSPARENT_BLACK,
COLOR_BLACK,
UI_LOADING_FADE_DURATION,
EASING_LINEAR
);
}
void uiLoadingHide(eventcallback_t callback, void *user) {
uiLoadingTransition(1.0f, 0.0f, callback, user);
uiFullboxTransition(
&UI_FULLBOX_OVER,
COLOR_BLACK,
COLOR_TRANSPARENT_BLACK,
UI_LOADING_FADE_DURATION,
EASING_LINEAR
);
}
+59
View File
@@ -0,0 +1,59 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#include "event/event.h"
#define UI_LOADING_FADE_DURATION 0.5f
#define UI_LOADING_MARGIN 8.0f
typedef struct {
float_t fromAlpha;
float_t toAlpha;
float_t duration;
float_t time;
event_t onTransitionEnd;
} uiloading_t;
extern uiloading_t UI_LOADING;
/**
* Initializes the loading indicator.
*/
void uiLoadingInit(void);
/**
* Advances the loading indicator fade transition. Fires onTransitionEnd once
* when the transition completes.
*
* @param delta Seconds elapsed since last update.
*/
void uiLoadingUpdate(float_t delta);
/**
* Draws the loading indicator. No-op when fully transparent.
*
* @return Error state.
*/
errorret_t uiLoadingDraw(void);
/**
* Fades the loading indicator in. Invokes callback when fully visible.
*
* @param callback Called when the fade-in completes. May be NULL.
* @param user Forwarded to the callback unchanged.
*/
void uiLoadingShow(eventcallback_t callback, void *user);
/**
* Fades the loading indicator out. Invokes callback when fully hidden.
*
* @param callback Called when the fade-out completes. May be NULL.
* @param user Forwarded to the callback unchanged.
*/
void uiLoadingHide(eventcallback_t callback, void *user);