Files
dusk/src/dusk/ui/frame/initial/uiinitialnocard.c
T
YourWishes 7357b4a5df Localize remaining hardcoded UI strings and persist language preference
Replaces the last hardcoded English strings (initial-scene modals, game
menu save status messages) with locale-loaded text, adds a shared
LOCALE_LIST so the settings dropdown and locale manager stay in sync,
and persists the chosen language into savemeta_t across all platforms.
Also fixes two message buffers that were too small for their longest
translations.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 21:39:24 -05:00

147 lines
4.0 KiB
C

/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "uiinitialnocard.h"
#include "ui/frame/uiframe.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "util/math.h"
#include "display/screen/screen.h"
#include "display/text/text.h"
#include "display/color.h"
#include "display/spritebatch/spritebatch.h"
#include "display/texture/texture.h"
#include "display/shader/shaderunlit.h"
#include "locale/localemanager.h"
#include "asset/loader/locale/assetlocaleloader.h"
#define UI_INITIAL_NO_CARD_BACKDROP_COLOR color4b(0, 0, 0, 160)
uiinitialnocard_t UI_INITIAL_NO_CARD;
static void uiInitialNoCardSelected(
const uimenu_t *menu,
const uint8_t index,
const uimenuitem_t *item
) {
UI_INITIAL_NO_CARD.retry = index == UI_INITIAL_NO_CARD_INDEX_RETRY;
uiInitialNoCardClose();
}
static void uiInitialNoCardClosed(const uimenu_t *menu) {
if(UI_INITIAL_NO_CARD.callback != NULL) {
UI_INITIAL_NO_CARD.callback(UI_INITIAL_NO_CARD.retry, UI_INITIAL_NO_CARD.user);
}
}
errorret_t uiInitialNoCardInit(void) {
memoryZero(&UI_INITIAL_NO_CARD, sizeof(uiinitialnocard_t));
errorChain(assetLocaleGetString(
&LOCALE.entry->data.locale,
"ui.initial.no_card.message",
0,
UI_INITIAL_NO_CARD.text,
UI_INITIAL_NO_CARD_TEXT_MAX
));
errorChain(assetLocaleGetString(
&LOCALE.entry->data.locale,
"ui.initial.no_card.retry",
0,
UI_INITIAL_NO_CARD.retryLabel,
UI_INITIAL_NO_CARD_LABEL_MAX
));
errorChain(assetLocaleGetString(
&LOCALE.entry->data.locale,
"ui.initial.no_card.continue",
0,
UI_INITIAL_NO_CARD.continueLabel,
UI_INITIAL_NO_CARD_LABEL_MAX
));
MENU_BEGIN(
&UI_INITIAL_NO_CARD.menu, UI_INITIAL_NO_CARD.items,
uiInitialNoCardSelected, uiInitialNoCardClosed, NULL
);
MENU_BUTTON(UI_INITIAL_NO_CARD.retryLabel);
MENU_BUTTON(UI_INITIAL_NO_CARD.continueLabel);
MENU_END(UI_INITIAL_NO_CARD.items, menuIndex);
errorOk();
}
errorret_t uiInitialNoCardDraw(void) {
if(!uiMenuIsActive(&UI_INITIAL_NO_CARD.menu)) errorOk();
spritebatchsprite_t backdropSprite = {
.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 backdropMaterial = {
.unlit = {
.color = UI_INITIAL_NO_CARD_BACKDROP_COLOR,
.texture = &TEXTURE_WHITE
}
};
errorChain(
spriteBatchBuffer(&backdropSprite, 1, &SHADER_UNLIT, backdropMaterial)
);
errorChain(spriteBatchFlush());
int32_t textW, textH;
textMeasure(UI_INITIAL_NO_CARD.text, &FONT_DEFAULT, &textW, &textH);
float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
float_t width = mathMax(
(float_t)textW + (UI_FRAME_START_X * 2), UI_INITIAL_NO_CARD_MIN_WIDTH
);
float_t height = (UI_FRAME_START_Y * 2) + (float_t)textH +
UI_FRAME_PADDING_Y + rowHeight;
float_t x = (float_t)SCREEN.scanX + ((float_t)SCREEN.scanWidth - width) * 0.5f;
float_t y = (float_t)SCREEN.scanY + ((float_t)SCREEN.scanHeight - height) * 0.5f;
errorChain(uiFrameDraw(x, y, width, height));
float_t contentX = x + UI_FRAME_START_X;
float_t contentY = y + UI_FRAME_START_Y;
float_t contentWidth = width - (UI_FRAME_START_X * 2);
errorChain(textDraw(
contentX, contentY, UI_INITIAL_NO_CARD.text, COLOR_WHITE, &FONT_DEFAULT
));
float_t buttonsY = contentY + (float_t)textH + UI_FRAME_PADDING_Y;
errorChain(uiMenuDraw(
&UI_INITIAL_NO_CARD.menu, contentX, buttonsY, contentWidth, rowHeight
));
errorChain(spriteBatchFlush());
errorOk();
}
bool_t uiInitialNoCardIsOpen(void) {
return uiMenuIsActive(&UI_INITIAL_NO_CARD.menu);
}
void uiInitialNoCardOpen(uiinitialnocardcallback_t callback, void *user) {
UI_INITIAL_NO_CARD.callback = callback;
UI_INITIAL_NO_CARD.user = user;
UI_INITIAL_NO_CARD.retry = false;
uiMenuOpen(&UI_INITIAL_NO_CARD.menu);
}
void uiInitialNoCardClose(void) {
uiMenuClose(&UI_INITIAL_NO_CARD.menu);
}
errorret_t uiInitialNoCardDispose(void) {
errorOk();
}