7357b4a5df
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>
147 lines
4.0 KiB
C
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();
|
|
}
|