diff --git a/shell/shellMain.c b/shell/shellMain.c index 65e9a7b..0870ea8 100644 --- a/shell/shellMain.c +++ b/shell/shellMain.c @@ -29,6 +29,9 @@ #include "shellApp.h" #include "shellInfo.h" #include "dvxDialog.h" +#include "dvxDraw.h" +#include "dvxVideo.h" +#include "dvxComp.h" #include "dvxPrefs.h" #include "dvxPlatform.h" #include "stb_ds.h" @@ -60,6 +63,8 @@ static DesktopUpdateFnT *sDesktopUpdateFns = NULL; static void idleYield(void *ctx); static void logVideoMode(int32_t w, int32_t h, int32_t bpp, void *userData); +static void showSplash(AppContextT *ctx); +static void hideSplash(AppContextT *ctx); // ============================================================ // shellDesktopUpdate -- notify desktop app of state change @@ -118,6 +123,62 @@ static void logVideoMode(int32_t w, int32_t h, int32_t bpp, void *userData) { } +// ============================================================ +// showSplash / hideSplash +// ============================================================ +// +// Draws a centered splash screen directly to the backbuffer before +// any windows exist. Flushed immediately so it's visible during the +// loading pause (DXE loading, widget registration, app init). + +static void showSplash(AppContextT *ctx) { + DisplayT *d = &ctx->display; + const BlitOpsT *ops = &ctx->blitOps; + const BitmapFontT *font = &ctx->font; + const ColorSchemeT *col = &ctx->colors; + + // Dark background + uint32_t bgColor = packColor(d, 0, 0, 64); + rectFill(d, ops, 0, 0, d->width, d->height, bgColor); + + // Center text + const char *title = "DVX - DOS Visual eXecutive"; + const char *version = "Loading..."; + + int32_t titleW = textWidth(font, title); + int32_t versionW = textWidth(font, version); + int32_t titleX = (d->width - titleW) / 2; + int32_t versionX = (d->width - versionW) / 2; + int32_t centerY = d->height / 2 - font->charHeight; + + uint32_t titleFg = packColor(d, 255, 255, 255); + uint32_t verFg = packColor(d, 180, 180, 220); + + drawText(d, ops, font, titleX, centerY, title, titleFg, bgColor, true); + drawText(d, ops, font, versionX, centerY + font->charHeight + 4, version, verFg, bgColor, true); + + // Flush the entire screen + RectT fullScreen = {0, 0, d->width, d->height}; + platformFlushRect(d, &fullScreen); +} + + +static void hideSplash(AppContextT *ctx) { + DisplayT *d = &ctx->display; + const BlitOpsT *ops = &ctx->blitOps; + + // Clear to desktop background -- the first dvxUpdate will paint + // the wallpaper and windows over this. + rectFill(d, ops, 0, 0, d->width, d->height, ctx->colors.desktop); + + RectT fullScreen = {0, 0, d->width, d->height}; + platformFlushRect(d, &fullScreen); + + // Mark entire screen dirty so the compositor repaints everything + dirtyListAdd(&ctx->dirty, 0, 0, d->width, d->height); +} + + // ============================================================ // shellRegisterDesktopUpdate // ============================================================ @@ -242,6 +303,9 @@ int shellMain(int argc, char *argv[]) { platformVideoEnumModes(logVideoMode, NULL); dvxLog("Selected: %ldx%ld %ldbpp (pitch %ld)", (long)sCtx.display.width, (long)sCtx.display.height, (long)sCtx.display.format.bitsPerPixel, (long)sCtx.display.pitch); + // Show splash screen while the rest of initialization runs + showSplash(&sCtx); + // Initialize task system if (tsInit() != TS_OK) { dvxLog("Failed to initialize task system"); @@ -291,6 +355,9 @@ int shellMain(int argc, char *argv[]) { return 1; } + // Dismiss splash -- desktop app is loaded, ready for interaction + hideSplash(&sCtx); + dvxLog("DVX Shell ready."); // Set recovery point for crash handler. setjmp returns 0 on initial