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>
This commit is contained in:
@@ -60,6 +60,58 @@ msgstr "Settings"
|
|||||||
msgid "ui.game_menu.save"
|
msgid "ui.game_menu.save"
|
||||||
msgstr "Save"
|
msgstr "Save"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_success"
|
||||||
|
msgstr "Game saved."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_cancelled"
|
||||||
|
msgstr "Save cancelled."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_unavailable"
|
||||||
|
msgstr "Can't save - no save device found."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_temporary"
|
||||||
|
msgstr "This session is temporary - no save device was found, so saving is disabled."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_create_confirm"
|
||||||
|
msgstr "No save data found. Create a new save?"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_failed_format"
|
||||||
|
msgstr "Save failed: %s"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_check_failed_format"
|
||||||
|
msgstr "Can't save: %s"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.message"
|
||||||
|
msgstr "No save device found. You can continue, but\nprogress will not be saved."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.retry"
|
||||||
|
msgstr "Retry"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.continue"
|
||||||
|
msgstr "Continue Anyway"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.message"
|
||||||
|
msgstr "No save data found. Create a new save?"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.yes"
|
||||||
|
msgstr "Yes"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.no"
|
||||||
|
msgstr "No"
|
||||||
|
|
||||||
msgid "item.potion.name"
|
msgid "item.potion.name"
|
||||||
msgstr "Potion"
|
msgstr "Potion"
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,58 @@ msgstr "Configuración"
|
|||||||
msgid "ui.game_menu.save"
|
msgid "ui.game_menu.save"
|
||||||
msgstr "Guardar"
|
msgstr "Guardar"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_success"
|
||||||
|
msgstr "Partida guardada."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_cancelled"
|
||||||
|
msgstr "Guardado cancelado."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_unavailable"
|
||||||
|
msgstr "No se puede guardar: no se encontró ningún dispositivo de guardado."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_temporary"
|
||||||
|
msgstr "Esta sesión es temporal - no se encontró ningún dispositivo de guardado, por lo que guardar está deshabilitado."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_create_confirm"
|
||||||
|
msgstr "No se encontraron datos guardados. ¿Crear una partida nueva?"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_failed_format"
|
||||||
|
msgstr "Error al guardar: %s"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_check_failed_format"
|
||||||
|
msgstr "No se puede guardar: %s"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.message"
|
||||||
|
msgstr "No se encontró ningún dispositivo de guardado. Puedes continuar, pero\nel progreso no se guardará."
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.retry"
|
||||||
|
msgstr "Reintentar"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.continue"
|
||||||
|
msgstr "Continuar de todos modos"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.message"
|
||||||
|
msgstr "No se encontraron datos guardados. ¿Crear una partida nueva?"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.yes"
|
||||||
|
msgstr "Sí"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.no"
|
||||||
|
msgstr "No"
|
||||||
|
|
||||||
#: src/dusk/rpg/item/item.json
|
#: src/dusk/rpg/item/item.json
|
||||||
msgid "item.potion.name"
|
msgid "item.potion.name"
|
||||||
msgstr "Poción"
|
msgstr "Poción"
|
||||||
|
|||||||
@@ -61,6 +61,58 @@ msgstr "設定"
|
|||||||
msgid "ui.game_menu.save"
|
msgid "ui.game_menu.save"
|
||||||
msgstr "セーブ"
|
msgstr "セーブ"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_success"
|
||||||
|
msgstr "セーブしました。"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_cancelled"
|
||||||
|
msgstr "セーブをキャンセルしました。"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_unavailable"
|
||||||
|
msgstr "セーブできません - セーブデバイスが見つかりません。"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_temporary"
|
||||||
|
msgstr "このセッションは一時的です - セーブデバイスが見つからなかったため、セーブは無効になっています。"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_create_confirm"
|
||||||
|
msgstr "セーブデータが見つかりません。新しいセーブを作成しますか?"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_failed_format"
|
||||||
|
msgstr "セーブに失敗しました: %s"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/game/uigamemenu.c
|
||||||
|
msgid "ui.game_menu.save_check_failed_format"
|
||||||
|
msgstr "セーブできません: %s"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.message"
|
||||||
|
msgstr "セーブデバイスが見つかりません。続行できますが、\n進行状況は保存されません。"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.retry"
|
||||||
|
msgstr "再試行"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialnocard.c
|
||||||
|
msgid "ui.initial.no_card.continue"
|
||||||
|
msgstr "続行する"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.message"
|
||||||
|
msgstr "セーブデータが見つかりません。新しいセーブを作成しますか?"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.yes"
|
||||||
|
msgstr "はい"
|
||||||
|
|
||||||
|
#: src/dusk/ui/frame/initial/uiinitialcreatesave.c
|
||||||
|
msgid "ui.initial.create_save.no"
|
||||||
|
msgstr "いいえ"
|
||||||
|
|
||||||
#: src/dusk/rpg/item/item.json
|
#: src/dusk/rpg/item/item.json
|
||||||
msgid "item.potion.name"
|
msgid "item.potion.name"
|
||||||
msgstr "ポーション"
|
msgstr "ポーション"
|
||||||
|
|||||||
@@ -7,16 +7,42 @@
|
|||||||
|
|
||||||
#include "localemanager.h"
|
#include "localemanager.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
|
#include "save/save.h"
|
||||||
|
|
||||||
localemanager_t LOCALE;
|
localemanager_t LOCALE;
|
||||||
|
|
||||||
|
const localeinfo_t * const LOCALE_LIST[LOCALE_LIST_COUNT] = {
|
||||||
|
&LOCALE_EN_US,
|
||||||
|
&LOCALE_JP_JP,
|
||||||
|
&LOCALE_ES_MX
|
||||||
|
};
|
||||||
|
|
||||||
errorret_t localeManagerInit() {
|
errorret_t localeManagerInit() {
|
||||||
memoryZero(&LOCALE, sizeof(localemanager_t));
|
memoryZero(&LOCALE, sizeof(localemanager_t));
|
||||||
errorChain(localeManagerSetLocale(&LOCALE_EN_US));
|
// saveInit() runs before this (see engine.c) and, on most platforms,
|
||||||
|
// has already loaded a persisted language choice into savemeta_t by
|
||||||
|
// this point - see localeManagerGetByIndex().
|
||||||
|
errorChain(localeManagerSetLocale(
|
||||||
|
localeManagerGetByIndex(saveGetMeta()->language)
|
||||||
|
));
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t localeManagerGetIndex(const localeinfo_t *locale) {
|
||||||
|
assertNotNull(locale, "Locale cannot be NULL");
|
||||||
|
for(uint8_t i = 0; i < LOCALE_LIST_COUNT; i++) {
|
||||||
|
if(stringCompare(LOCALE_LIST[i]->file, locale->file) == 0) return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const localeinfo_t * localeManagerGetByIndex(const uint8_t index) {
|
||||||
|
if(index >= LOCALE_LIST_COUNT) return LOCALE_LIST[0];
|
||||||
|
return LOCALE_LIST[index];
|
||||||
|
}
|
||||||
|
|
||||||
errorret_t localeManagerSetLocale(const localeinfo_t *locale) {
|
errorret_t localeManagerSetLocale(const localeinfo_t *locale) {
|
||||||
assertNotNull(locale, "Locale cannot be NULL");
|
assertNotNull(locale, "Locale cannot be NULL");
|
||||||
|
|
||||||
|
|||||||
@@ -18,21 +18,51 @@ typedef struct {
|
|||||||
|
|
||||||
extern localemanager_t LOCALE;
|
extern localemanager_t LOCALE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Every locale the game supports, in a fixed, stable order - index into
|
||||||
|
* this array is what gets persisted as savemeta_t.language (see
|
||||||
|
* save/savemeta.h), so the order here must never change once shipped
|
||||||
|
* (only append new locales at the end).
|
||||||
|
*/
|
||||||
|
#define LOCALE_LIST_COUNT 3
|
||||||
|
extern const localeinfo_t * const LOCALE_LIST[LOCALE_LIST_COUNT];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the locale system.
|
* Initialize the locale system.
|
||||||
*
|
*
|
||||||
* @return An error code if a failure occurs.
|
* @return An error code if a failure occurs.
|
||||||
*/
|
*/
|
||||||
errorret_t localeManagerInit();
|
errorret_t localeManagerInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current locale.
|
* Set the current locale.
|
||||||
*
|
*
|
||||||
* @param locale The locale to set.
|
* @param locale The locale to set.
|
||||||
* @return An error code if a failure occurs.
|
* @return An error code if a failure occurs.
|
||||||
*/
|
*/
|
||||||
errorret_t localeManagerSetLocale(const localeinfo_t *locale);
|
errorret_t localeManagerSetLocale(const localeinfo_t *locale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the LOCALE_LIST index matching the given locale's file, by
|
||||||
|
* content rather than pointer identity (localeinfo_t instances are
|
||||||
|
* declared `static const` in a header, so the same locale gets a
|
||||||
|
* distinct pointer in every translation unit that references it).
|
||||||
|
*
|
||||||
|
* @param locale The locale to find.
|
||||||
|
* @return The matching index in LOCALE_LIST, or 0 if not found.
|
||||||
|
*/
|
||||||
|
uint8_t localeManagerGetIndex(const localeinfo_t *locale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the locale at the given LOCALE_LIST index, clamping to index 0
|
||||||
|
* (LOCALE_EN_US) if out of range - e.g. a save file's persisted language
|
||||||
|
* index from a future build with more locales than this one supports.
|
||||||
|
*
|
||||||
|
* @param index The index to look up.
|
||||||
|
* @return The locale at that index, or LOCALE_LIST[0] if out of range.
|
||||||
|
*/
|
||||||
|
const localeinfo_t * localeManagerGetByIndex(const uint8_t index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a localized string for the given message ID.
|
* Get a localized string for the given message ID.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ static void _saveEagerLoadComplete(errorret_t result, void *user) {
|
|||||||
errorret_t saveInit(void) {
|
errorret_t saveInit(void) {
|
||||||
memoryZero(&SAVE, sizeof(save_t));
|
memoryZero(&SAVE, sizeof(save_t));
|
||||||
SAVE.meta.deadzone = SAVE_META_DEADZONE_DEFAULT;
|
SAVE.meta.deadzone = SAVE_META_DEADZONE_DEFAULT;
|
||||||
|
SAVE.meta.language = SAVE_META_LANGUAGE_DEFAULT;
|
||||||
|
|
||||||
#ifdef saveInitPlatform
|
#ifdef saveInitPlatform
|
||||||
// A missing/unreachable save medium is expected, recoverable state,
|
// A missing/unreachable save medium is expected, recoverable state,
|
||||||
|
|||||||
@@ -25,6 +25,13 @@
|
|||||||
*/
|
*/
|
||||||
#define SAVE_META_DEADZONE_DEFAULT 0.1f
|
#define SAVE_META_DEADZONE_DEFAULT 0.1f
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default language index for meta that's never actually been loaded from
|
||||||
|
* disk yet - index 0 into LOCALE_LIST (see locale/localemanager.h), i.e.
|
||||||
|
* LOCALE_EN_US.
|
||||||
|
*/
|
||||||
|
#define SAVE_META_LANGUAGE_DEFAULT 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Device/user-wide preferences, independent of any individual game save
|
* Device/user-wide preferences, independent of any individual game save
|
||||||
* slot (see saveslot.h) - there's exactly one of these, not one per slot,
|
* slot (see saveslot.h) - there's exactly one of these, not one per slot,
|
||||||
@@ -44,4 +51,13 @@ typedef struct {
|
|||||||
* rather than caching it anywhere else.
|
* rather than caching it anywhere else.
|
||||||
*/
|
*/
|
||||||
float_t deadzone;
|
float_t deadzone;
|
||||||
|
/**
|
||||||
|
* Index into LOCALE_LIST (see locale/localemanager.h) for the player's
|
||||||
|
* preferred UI language - the save meta is the only place this lives;
|
||||||
|
* read it directly via saveGetMeta()->language rather than caching it
|
||||||
|
* anywhere else. Never reorder/remove entries from LOCALE_LIST, only
|
||||||
|
* append, since this index must keep meaning the same locale across
|
||||||
|
* versions.
|
||||||
|
*/
|
||||||
|
uint8_t language;
|
||||||
} savemeta_t;
|
} savemeta_t;
|
||||||
|
|||||||
@@ -340,6 +340,7 @@ errorret_t saveMetaSerializeRead(savestream_t *stream, savemeta_t *meta) {
|
|||||||
);
|
);
|
||||||
saveFileReadVersion(stream, &meta->version);
|
saveFileReadVersion(stream, &meta->version);
|
||||||
saveFileReadFloat(stream, &meta->deadzone);
|
saveFileReadFloat(stream, &meta->deadzone);
|
||||||
|
saveFileReadUInt8(stream, &meta->language);
|
||||||
errorChain(saveStreamVerifyChecksumImpl(stream, "Save meta"));
|
errorChain(saveStreamVerifyChecksumImpl(stream, "Save meta"));
|
||||||
meta->exists = true;
|
meta->exists = true;
|
||||||
errorOk();
|
errorOk();
|
||||||
@@ -354,6 +355,7 @@ errorret_t saveMetaSerializeWrite(savestream_t *stream, savemeta_t *meta) {
|
|||||||
saveFileWriteHeader(stream, meta->header, SAVE_META_HEADER_SIZE);
|
saveFileWriteHeader(stream, meta->header, SAVE_META_HEADER_SIZE);
|
||||||
saveFileWriteVersion(stream, &meta->version);
|
saveFileWriteVersion(stream, &meta->version);
|
||||||
saveFileWriteFloat(stream, &meta->deadzone);
|
saveFileWriteFloat(stream, &meta->deadzone);
|
||||||
|
saveFileWriteUInt8(stream, &meta->language);
|
||||||
errorChain(saveStreamFinalizeWriteImpl(
|
errorChain(saveStreamFinalizeWriteImpl(
|
||||||
stream, headerPosition, SAVE_META_HEADER_SIZE
|
stream, headerPosition, SAVE_META_HEADER_SIZE
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -33,19 +33,19 @@ static void uiGameMenuSaveWriteComplete(errorret_t result, void *user) {
|
|||||||
// the longest platform save-error message plus this prefix.
|
// the longest platform save-error message plus this prefix.
|
||||||
char_t msg[256];
|
char_t msg[256];
|
||||||
stringFormat(
|
stringFormat(
|
||||||
msg, sizeof(msg), "Save failed: %s", result.state->message
|
msg, sizeof(msg), UI_GAME_MENU.saveFailedFormat, result.state->message
|
||||||
);
|
);
|
||||||
errorCatch(result);
|
errorCatch(result);
|
||||||
uiTextboxMainSetText(msg);
|
uiTextboxMainSetText(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uiTextboxMainSetText("Game saved.");
|
uiTextboxMainSetText(UI_GAME_MENU.saveSuccessText);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uiGameMenuSaveCreateConfirmed(const bool_t confirmed, void *user) {
|
static void uiGameMenuSaveCreateConfirmed(const bool_t confirmed, void *user) {
|
||||||
if(!confirmed) {
|
if(!confirmed) {
|
||||||
uiTextboxMainSetText("Save cancelled.");
|
uiTextboxMainSetText(UI_GAME_MENU.saveCancelledText);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,10 @@ static void uiGameMenuSaveCreateConfirmed(const bool_t confirmed, void *user) {
|
|||||||
static void uiGameMenuSaveCheckComplete(errorret_t result, void *user) {
|
static void uiGameMenuSaveCheckComplete(errorret_t result, void *user) {
|
||||||
if(errorIsNotOk(result)) {
|
if(errorIsNotOk(result)) {
|
||||||
char_t msg[256];
|
char_t msg[256];
|
||||||
stringFormat(msg, sizeof(msg), "Can't save: %s", result.state->message);
|
stringFormat(
|
||||||
|
msg, sizeof(msg), UI_GAME_MENU.saveCheckFailedFormat,
|
||||||
|
result.state->message
|
||||||
|
);
|
||||||
errorCatch(result);
|
errorCatch(result);
|
||||||
uiTextboxMainSetText(msg);
|
uiTextboxMainSetText(msg);
|
||||||
return;
|
return;
|
||||||
@@ -74,7 +77,7 @@ static void uiGameMenuSaveCheckComplete(errorret_t result, void *user) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uiConfirmOpen(
|
uiConfirmOpen(
|
||||||
"No save data found. Create a new save?",
|
UI_GAME_MENU.saveCreateConfirmText,
|
||||||
uiGameMenuSaveCreateConfirmed,
|
uiGameMenuSaveCreateConfirmed,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
@@ -82,14 +85,11 @@ static void uiGameMenuSaveCheckComplete(errorret_t result, void *user) {
|
|||||||
|
|
||||||
static void uiGameMenuSave(void) {
|
static void uiGameMenuSave(void) {
|
||||||
if(saveIsTemporary()) {
|
if(saveIsTemporary()) {
|
||||||
uiTextboxMainSetText(
|
uiTextboxMainSetText(UI_GAME_MENU.saveTemporaryText);
|
||||||
"This session is temporary - no save device was found, so saving "
|
|
||||||
"is disabled."
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!saveIsAvailable()) {
|
if(!saveIsAvailable()) {
|
||||||
uiTextboxMainSetText("Can't save - no save device found.");
|
uiTextboxMainSetText(UI_GAME_MENU.saveUnavailableText);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(saveIsBusy()) return;// A save/load dialog (e.g. on PSP) is already up.
|
if(saveIsBusy()) return;// A save/load dialog (e.g. on PSP) is already up.
|
||||||
@@ -140,6 +140,55 @@ errorret_t uiGameMenuInit(void) {
|
|||||||
UI_GAME_MENU.saveLabel,
|
UI_GAME_MENU.saveLabel,
|
||||||
UI_GAME_MENU_LABEL_MAX
|
UI_GAME_MENU_LABEL_MAX
|
||||||
));
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.game_menu.save_success",
|
||||||
|
0,
|
||||||
|
UI_GAME_MENU.saveSuccessText,
|
||||||
|
UI_GAME_MENU_MESSAGE_MAX
|
||||||
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.game_menu.save_cancelled",
|
||||||
|
0,
|
||||||
|
UI_GAME_MENU.saveCancelledText,
|
||||||
|
UI_GAME_MENU_MESSAGE_MAX
|
||||||
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.game_menu.save_unavailable",
|
||||||
|
0,
|
||||||
|
UI_GAME_MENU.saveUnavailableText,
|
||||||
|
UI_GAME_MENU_MESSAGE_MAX
|
||||||
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.game_menu.save_temporary",
|
||||||
|
0,
|
||||||
|
UI_GAME_MENU.saveTemporaryText,
|
||||||
|
UI_GAME_MENU_MESSAGE_MAX
|
||||||
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.game_menu.save_create_confirm",
|
||||||
|
0,
|
||||||
|
UI_GAME_MENU.saveCreateConfirmText,
|
||||||
|
UI_GAME_MENU_MESSAGE_MAX
|
||||||
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.game_menu.save_failed_format",
|
||||||
|
0,
|
||||||
|
UI_GAME_MENU.saveFailedFormat,
|
||||||
|
UI_GAME_MENU_MESSAGE_MAX
|
||||||
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.game_menu.save_check_failed_format",
|
||||||
|
0,
|
||||||
|
UI_GAME_MENU.saveCheckFailedFormat,
|
||||||
|
UI_GAME_MENU_MESSAGE_MAX
|
||||||
|
));
|
||||||
|
|
||||||
MENU_BEGIN(
|
MENU_BEGIN(
|
||||||
&UI_GAME_MENU.menu, UI_GAME_MENU.items, uiGameMenuSelected, NULL, NULL
|
&UI_GAME_MENU.menu, UI_GAME_MENU.items, uiGameMenuSelected, NULL, NULL
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#define UI_GAME_MENU_ITEM_COUNT 4
|
#define UI_GAME_MENU_ITEM_COUNT 4
|
||||||
#define UI_GAME_MENU_WIDTH 150.0f
|
#define UI_GAME_MENU_WIDTH 150.0f
|
||||||
#define UI_GAME_MENU_LABEL_MAX 32
|
#define UI_GAME_MENU_LABEL_MAX 32
|
||||||
|
#define UI_GAME_MENU_MESSAGE_MAX 192
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uimenu_t menu;
|
uimenu_t menu;
|
||||||
@@ -20,6 +21,13 @@ typedef struct {
|
|||||||
char_t itemsLabel[UI_GAME_MENU_LABEL_MAX];
|
char_t itemsLabel[UI_GAME_MENU_LABEL_MAX];
|
||||||
char_t settingsLabel[UI_GAME_MENU_LABEL_MAX];
|
char_t settingsLabel[UI_GAME_MENU_LABEL_MAX];
|
||||||
char_t saveLabel[UI_GAME_MENU_LABEL_MAX];
|
char_t saveLabel[UI_GAME_MENU_LABEL_MAX];
|
||||||
|
char_t saveSuccessText[UI_GAME_MENU_MESSAGE_MAX];
|
||||||
|
char_t saveCancelledText[UI_GAME_MENU_MESSAGE_MAX];
|
||||||
|
char_t saveUnavailableText[UI_GAME_MENU_MESSAGE_MAX];
|
||||||
|
char_t saveTemporaryText[UI_GAME_MENU_MESSAGE_MAX];
|
||||||
|
char_t saveCreateConfirmText[UI_GAME_MENU_MESSAGE_MAX];
|
||||||
|
char_t saveFailedFormat[UI_GAME_MENU_MESSAGE_MAX];
|
||||||
|
char_t saveCheckFailedFormat[UI_GAME_MENU_MESSAGE_MAX];
|
||||||
} uigamemenu_t;
|
} uigamemenu_t;
|
||||||
|
|
||||||
extern uigamemenu_t UI_GAME_MENU;
|
extern uigamemenu_t UI_GAME_MENU;
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
#include "display/texture/texture.h"
|
#include "display/texture/texture.h"
|
||||||
#include "display/shader/shaderunlit.h"
|
#include "display/shader/shaderunlit.h"
|
||||||
|
#include "locale/localemanager.h"
|
||||||
|
#include "asset/loader/locale/assetlocaleloader.h"
|
||||||
|
|
||||||
#define UI_INITIAL_CREATE_SAVE_BACKDROP_COLOR color4b(0, 0, 0, 160)
|
#define UI_INITIAL_CREATE_SAVE_BACKDROP_COLOR color4b(0, 0, 0, 160)
|
||||||
#define UI_INITIAL_CREATE_SAVE_TEXT "No save data found. Create a new save?"
|
|
||||||
|
|
||||||
uiinitialcreatesave_t UI_INITIAL_CREATE_SAVE;
|
uiinitialcreatesave_t UI_INITIAL_CREATE_SAVE;
|
||||||
|
|
||||||
@@ -42,12 +43,34 @@ static void uiInitialCreateSaveClosed(const uimenu_t *menu) {
|
|||||||
errorret_t uiInitialCreateSaveInit(void) {
|
errorret_t uiInitialCreateSaveInit(void) {
|
||||||
memoryZero(&UI_INITIAL_CREATE_SAVE, sizeof(uiinitialcreatesave_t));
|
memoryZero(&UI_INITIAL_CREATE_SAVE, sizeof(uiinitialcreatesave_t));
|
||||||
|
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.initial.create_save.message",
|
||||||
|
0,
|
||||||
|
UI_INITIAL_CREATE_SAVE.text,
|
||||||
|
UI_INITIAL_CREATE_SAVE_TEXT_MAX
|
||||||
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.initial.create_save.yes",
|
||||||
|
0,
|
||||||
|
UI_INITIAL_CREATE_SAVE.yesLabel,
|
||||||
|
UI_INITIAL_CREATE_SAVE_LABEL_MAX
|
||||||
|
));
|
||||||
|
errorChain(assetLocaleGetString(
|
||||||
|
&LOCALE.entry->data.locale,
|
||||||
|
"ui.initial.create_save.no",
|
||||||
|
0,
|
||||||
|
UI_INITIAL_CREATE_SAVE.noLabel,
|
||||||
|
UI_INITIAL_CREATE_SAVE_LABEL_MAX
|
||||||
|
));
|
||||||
|
|
||||||
MENU_BEGIN(
|
MENU_BEGIN(
|
||||||
&UI_INITIAL_CREATE_SAVE.menu, UI_INITIAL_CREATE_SAVE.items,
|
&UI_INITIAL_CREATE_SAVE.menu, UI_INITIAL_CREATE_SAVE.items,
|
||||||
uiInitialCreateSaveSelected, uiInitialCreateSaveClosed, NULL
|
uiInitialCreateSaveSelected, uiInitialCreateSaveClosed, NULL
|
||||||
);
|
);
|
||||||
MENU_BUTTON("Yes");
|
MENU_BUTTON(UI_INITIAL_CREATE_SAVE.yesLabel);
|
||||||
MENU_BUTTON("No");
|
MENU_BUTTON(UI_INITIAL_CREATE_SAVE.noLabel);
|
||||||
|
|
||||||
MENU_END(UI_INITIAL_CREATE_SAVE.items, menuIndex);
|
MENU_END(UI_INITIAL_CREATE_SAVE.items, menuIndex);
|
||||||
|
|
||||||
@@ -75,7 +98,7 @@ errorret_t uiInitialCreateSaveDraw(void) {
|
|||||||
errorChain(spriteBatchFlush());
|
errorChain(spriteBatchFlush());
|
||||||
|
|
||||||
int32_t textW, textH;
|
int32_t textW, textH;
|
||||||
textMeasure(UI_INITIAL_CREATE_SAVE_TEXT, &FONT_DEFAULT, &textW, &textH);
|
textMeasure(UI_INITIAL_CREATE_SAVE.text, &FONT_DEFAULT, &textW, &textH);
|
||||||
|
|
||||||
float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
||||||
float_t width = mathMax(
|
float_t width = mathMax(
|
||||||
@@ -93,7 +116,7 @@ errorret_t uiInitialCreateSaveDraw(void) {
|
|||||||
float_t contentWidth = width - (UI_FRAME_START_X * 2);
|
float_t contentWidth = width - (UI_FRAME_START_X * 2);
|
||||||
|
|
||||||
errorChain(textDraw(
|
errorChain(textDraw(
|
||||||
contentX, contentY, UI_INITIAL_CREATE_SAVE_TEXT, COLOR_WHITE, &FONT_DEFAULT
|
contentX, contentY, UI_INITIAL_CREATE_SAVE.text, COLOR_WHITE, &FONT_DEFAULT
|
||||||
));
|
));
|
||||||
|
|
||||||
float_t buttonsY = contentY + rowHeight + UI_FRAME_PADDING_Y;
|
float_t buttonsY = contentY + rowHeight + UI_FRAME_PADDING_Y;
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#define UI_INITIAL_CREATE_SAVE_INDEX_NO 1
|
#define UI_INITIAL_CREATE_SAVE_INDEX_NO 1
|
||||||
#define UI_INITIAL_CREATE_SAVE_ITEM_COUNT 2
|
#define UI_INITIAL_CREATE_SAVE_ITEM_COUNT 2
|
||||||
#define UI_INITIAL_CREATE_SAVE_MIN_WIDTH 160.0f
|
#define UI_INITIAL_CREATE_SAVE_MIN_WIDTH 160.0f
|
||||||
|
#define UI_INITIAL_CREATE_SAVE_TEXT_MAX 256
|
||||||
|
#define UI_INITIAL_CREATE_SAVE_LABEL_MAX 32
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback invoked once the create-save modal is dismissed.
|
* Callback invoked once the create-save modal is dismissed.
|
||||||
@@ -29,6 +31,9 @@ typedef struct {
|
|||||||
uiinitialcreatesavecallback_t callback;
|
uiinitialcreatesavecallback_t callback;
|
||||||
void *user;
|
void *user;
|
||||||
bool_t create;
|
bool_t create;
|
||||||
|
char_t text[UI_INITIAL_CREATE_SAVE_TEXT_MAX];
|
||||||
|
char_t yesLabel[UI_INITIAL_CREATE_SAVE_LABEL_MAX];
|
||||||
|
char_t noLabel[UI_INITIAL_CREATE_SAVE_LABEL_MAX];
|
||||||
} uiinitialcreatesave_t;
|
} uiinitialcreatesave_t;
|
||||||
|
|
||||||
extern uiinitialcreatesave_t UI_INITIAL_CREATE_SAVE;
|
extern uiinitialcreatesave_t UI_INITIAL_CREATE_SAVE;
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
#include "display/spritebatch/spritebatch.h"
|
#include "display/spritebatch/spritebatch.h"
|
||||||
#include "display/texture/texture.h"
|
#include "display/texture/texture.h"
|
||||||
#include "display/shader/shaderunlit.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)
|
#define UI_INITIAL_NO_CARD_BACKDROP_COLOR color4b(0, 0, 0, 160)
|
||||||
#define UI_INITIAL_NO_CARD_TEXT \
|
|
||||||
"No save device found. You can continue, but\nprogress will not be saved."
|
|
||||||
|
|
||||||
uiinitialnocard_t UI_INITIAL_NO_CARD;
|
uiinitialnocard_t UI_INITIAL_NO_CARD;
|
||||||
|
|
||||||
@@ -41,12 +41,34 @@ static void uiInitialNoCardClosed(const uimenu_t *menu) {
|
|||||||
errorret_t uiInitialNoCardInit(void) {
|
errorret_t uiInitialNoCardInit(void) {
|
||||||
memoryZero(&UI_INITIAL_NO_CARD, sizeof(uiinitialnocard_t));
|
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(
|
MENU_BEGIN(
|
||||||
&UI_INITIAL_NO_CARD.menu, UI_INITIAL_NO_CARD.items,
|
&UI_INITIAL_NO_CARD.menu, UI_INITIAL_NO_CARD.items,
|
||||||
uiInitialNoCardSelected, uiInitialNoCardClosed, NULL
|
uiInitialNoCardSelected, uiInitialNoCardClosed, NULL
|
||||||
);
|
);
|
||||||
MENU_BUTTON("Retry");
|
MENU_BUTTON(UI_INITIAL_NO_CARD.retryLabel);
|
||||||
MENU_BUTTON("Continue Anyway");
|
MENU_BUTTON(UI_INITIAL_NO_CARD.continueLabel);
|
||||||
|
|
||||||
MENU_END(UI_INITIAL_NO_CARD.items, menuIndex);
|
MENU_END(UI_INITIAL_NO_CARD.items, menuIndex);
|
||||||
|
|
||||||
@@ -74,7 +96,7 @@ errorret_t uiInitialNoCardDraw(void) {
|
|||||||
errorChain(spriteBatchFlush());
|
errorChain(spriteBatchFlush());
|
||||||
|
|
||||||
int32_t textW, textH;
|
int32_t textW, textH;
|
||||||
textMeasure(UI_INITIAL_NO_CARD_TEXT, &FONT_DEFAULT, &textW, &textH);
|
textMeasure(UI_INITIAL_NO_CARD.text, &FONT_DEFAULT, &textW, &textH);
|
||||||
|
|
||||||
float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
|
||||||
float_t width = mathMax(
|
float_t width = mathMax(
|
||||||
@@ -92,7 +114,7 @@ errorret_t uiInitialNoCardDraw(void) {
|
|||||||
float_t contentWidth = width - (UI_FRAME_START_X * 2);
|
float_t contentWidth = width - (UI_FRAME_START_X * 2);
|
||||||
|
|
||||||
errorChain(textDraw(
|
errorChain(textDraw(
|
||||||
contentX, contentY, UI_INITIAL_NO_CARD_TEXT, COLOR_WHITE, &FONT_DEFAULT
|
contentX, contentY, UI_INITIAL_NO_CARD.text, COLOR_WHITE, &FONT_DEFAULT
|
||||||
));
|
));
|
||||||
|
|
||||||
float_t buttonsY = contentY + (float_t)textH + UI_FRAME_PADDING_Y;
|
float_t buttonsY = contentY + (float_t)textH + UI_FRAME_PADDING_Y;
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#define UI_INITIAL_NO_CARD_INDEX_CONTINUE 1
|
#define UI_INITIAL_NO_CARD_INDEX_CONTINUE 1
|
||||||
#define UI_INITIAL_NO_CARD_ITEM_COUNT 2
|
#define UI_INITIAL_NO_CARD_ITEM_COUNT 2
|
||||||
#define UI_INITIAL_NO_CARD_MIN_WIDTH 220.0f
|
#define UI_INITIAL_NO_CARD_MIN_WIDTH 220.0f
|
||||||
|
#define UI_INITIAL_NO_CARD_TEXT_MAX 256
|
||||||
|
#define UI_INITIAL_NO_CARD_LABEL_MAX 32
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback invoked once the no-save-device modal is dismissed.
|
* Callback invoked once the no-save-device modal is dismissed.
|
||||||
@@ -28,6 +30,9 @@ typedef struct {
|
|||||||
uiinitialnocardcallback_t callback;
|
uiinitialnocardcallback_t callback;
|
||||||
void *user;
|
void *user;
|
||||||
bool_t retry;
|
bool_t retry;
|
||||||
|
char_t text[UI_INITIAL_NO_CARD_TEXT_MAX];
|
||||||
|
char_t retryLabel[UI_INITIAL_NO_CARD_LABEL_MAX];
|
||||||
|
char_t continueLabel[UI_INITIAL_NO_CARD_LABEL_MAX];
|
||||||
} uiinitialnocard_t;
|
} uiinitialnocard_t;
|
||||||
|
|
||||||
extern uiinitialnocard_t UI_INITIAL_NO_CARD;
|
extern uiinitialnocard_t UI_INITIAL_NO_CARD;
|
||||||
|
|||||||
@@ -8,19 +8,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
#include "ui/widget/uimenu.h"
|
#include "ui/widget/uimenu.h"
|
||||||
|
#include "locale/localemanager.h"
|
||||||
|
|
||||||
#define UI_SETTINGS_GENERAL_ITEM_COUNT 3
|
#define UI_SETTINGS_GENERAL_ITEM_COUNT 3
|
||||||
#define UI_SETTINGS_GENERAL_INDEX_LANGUAGE 0
|
#define UI_SETTINGS_GENERAL_INDEX_LANGUAGE 0
|
||||||
#define UI_SETTINGS_GENERAL_INDEX_LANGUAGE_DETAIL 1
|
#define UI_SETTINGS_GENERAL_INDEX_LANGUAGE_DETAIL 1
|
||||||
#define UI_SETTINGS_GENERAL_INDEX_APPLY 2
|
#define UI_SETTINGS_GENERAL_INDEX_APPLY 2
|
||||||
#define UI_SETTINGS_GENERAL_LOCALE_COUNT 3
|
|
||||||
#define UI_SETTINGS_GENERAL_LABEL_MAX 32
|
#define UI_SETTINGS_GENERAL_LABEL_MAX 32
|
||||||
#define UI_SETTINGS_GENERAL_INFO_MAX 64
|
#define UI_SETTINGS_GENERAL_INFO_MAX 96
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uimenu_t menu;
|
uimenu_t menu;
|
||||||
uimenuitem_t items[UI_SETTINGS_GENERAL_ITEM_COUNT];
|
uimenuitem_t items[UI_SETTINGS_GENERAL_ITEM_COUNT];
|
||||||
const char_t *localeNames[UI_SETTINGS_GENERAL_LOCALE_COUNT];
|
const char_t *localeNames[LOCALE_LIST_COUNT];
|
||||||
char_t languageLabel[UI_SETTINGS_GENERAL_LABEL_MAX];
|
char_t languageLabel[UI_SETTINGS_GENERAL_LABEL_MAX];
|
||||||
char_t labelInfo[UI_SETTINGS_GENERAL_INFO_MAX];
|
char_t labelInfo[UI_SETTINGS_GENERAL_INFO_MAX];
|
||||||
} uisettingsgeneral_t;
|
} uisettingsgeneral_t;
|
||||||
|
|||||||
@@ -9,18 +9,15 @@
|
|||||||
#include "uisettings.h"
|
#include "uisettings.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/string.h"
|
|
||||||
#include "locale/localemanager.h"
|
#include "locale/localemanager.h"
|
||||||
#include "locale/localeinfo.h"
|
#include "locale/localeinfo.h"
|
||||||
#include "asset/loader/locale/assetlocaleloader.h"
|
#include "asset/loader/locale/assetlocaleloader.h"
|
||||||
|
#include "save/save.h"
|
||||||
|
#include "error/error.h"
|
||||||
|
|
||||||
static const localeinfo_t *const UI_SETTINGS_GENERAL_LOCALES[
|
static void uiSettingsGeneralSaveComplete(errorret_t result, void *user) {
|
||||||
UI_SETTINGS_GENERAL_LOCALE_COUNT
|
if(errorIsNotOk(result)) errorCatch(errorPrint(result));
|
||||||
] = {
|
}
|
||||||
&LOCALE_EN_US,
|
|
||||||
&LOCALE_JP_JP,
|
|
||||||
&LOCALE_ES_MX
|
|
||||||
};
|
|
||||||
|
|
||||||
void uiSettingsGeneralSelected(
|
void uiSettingsGeneralSelected(
|
||||||
const uimenu_t *menu,
|
const uimenu_t *menu,
|
||||||
@@ -41,8 +38,8 @@ errorret_t uiSettingsGeneralInit(uisettingsdata_t *data) {
|
|||||||
uisettingsgeneral_t *general = &data->general;
|
uisettingsgeneral_t *general = &data->general;
|
||||||
memoryZero(general, sizeof(uisettingsgeneral_t));
|
memoryZero(general, sizeof(uisettingsgeneral_t));
|
||||||
|
|
||||||
for(uint8_t i = 0; i < UI_SETTINGS_GENERAL_LOCALE_COUNT; i++) {
|
for(uint8_t i = 0; i < LOCALE_LIST_COUNT; i++) {
|
||||||
general->localeNames[i] = UI_SETTINGS_GENERAL_LOCALES[i]->name;
|
general->localeNames[i] = LOCALE_LIST[i]->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
errorChain(assetLocaleGetString(
|
errorChain(assetLocaleGetString(
|
||||||
@@ -67,7 +64,7 @@ errorret_t uiSettingsGeneralInit(uisettingsdata_t *data) {
|
|||||||
|
|
||||||
MENU_DROPDOWN(
|
MENU_DROPDOWN(
|
||||||
general->languageLabel, general->localeNames,
|
general->languageLabel, general->localeNames,
|
||||||
UI_SETTINGS_GENERAL_LOCALE_COUNT, 0
|
LOCALE_LIST_COUNT, 0
|
||||||
);
|
);
|
||||||
MENU_LABEL(general->labelInfo);
|
MENU_LABEL(general->labelInfo);
|
||||||
|
|
||||||
@@ -80,14 +77,7 @@ errorret_t uiSettingsGeneralInit(uisettingsdata_t *data) {
|
|||||||
void uiSettingsGeneralLoad(void) {
|
void uiSettingsGeneralLoad(void) {
|
||||||
uisettingsgeneral_t *general = &UI_SETTINGS.data.general;
|
uisettingsgeneral_t *general = &UI_SETTINGS.data.general;
|
||||||
|
|
||||||
uint8_t index = 0;
|
uint8_t index = localeManagerGetIndex(LOCALE.locale);
|
||||||
for(uint8_t i = 0; i < UI_SETTINGS_GENERAL_LOCALE_COUNT; i++) {
|
|
||||||
if(stringCompare(LOCALE.locale->file, UI_SETTINGS_GENERAL_LOCALES[i]->file) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uiDropdownSetSelectedIndex(
|
uiDropdownSetSelectedIndex(
|
||||||
&general->items[UI_SETTINGS_GENERAL_INDEX_LANGUAGE].dropdown, index
|
&general->items[UI_SETTINGS_GENERAL_INDEX_LANGUAGE].dropdown, index
|
||||||
@@ -100,7 +90,10 @@ void uiSettingsGeneralApply(void) {
|
|||||||
uint8_t index = uiDropdownGetSelectedIndex(
|
uint8_t index = uiDropdownGetSelectedIndex(
|
||||||
&general->items[UI_SETTINGS_GENERAL_INDEX_LANGUAGE].dropdown
|
&general->items[UI_SETTINGS_GENERAL_INDEX_LANGUAGE].dropdown
|
||||||
);
|
);
|
||||||
errorCatch(localeManagerSetLocale(UI_SETTINGS_GENERAL_LOCALES[index]));
|
errorCatch(localeManagerSetLocale(LOCALE_LIST[index]));
|
||||||
|
|
||||||
|
saveGetMeta()->language = index;
|
||||||
|
saveWriteMeta(uiSettingsGeneralSaveComplete, NULL);
|
||||||
|
|
||||||
uiMenuClose(&general->menu);
|
uiMenuClose(&general->menu);
|
||||||
}
|
}
|
||||||
@@ -111,7 +104,5 @@ bool_t uiSettingsGeneralHasChanges(void) {
|
|||||||
uint8_t index = uiDropdownGetSelectedIndex(
|
uint8_t index = uiDropdownGetSelectedIndex(
|
||||||
&general->items[UI_SETTINGS_GENERAL_INDEX_LANGUAGE].dropdown
|
&general->items[UI_SETTINGS_GENERAL_INDEX_LANGUAGE].dropdown
|
||||||
);
|
);
|
||||||
return stringCompare(
|
return localeManagerGetIndex(LOCALE.locale) != index;
|
||||||
LOCALE.locale->file, UI_SETTINGS_GENERAL_LOCALES[index]->file
|
|
||||||
) != 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ void saveJsonWriterAddFloatLinux(
|
|||||||
yyjson_mut_obj_add_real(writer->doc, writer->root, key, (double)value);
|
yyjson_mut_obj_add_real(writer->doc, writer->root, key, (double)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void saveJsonWriterAddUInt8Linux(
|
||||||
|
savejsonwriterlinux_t *writer, const char_t *key, const uint8_t value
|
||||||
|
) {
|
||||||
|
yyjson_mut_obj_add_uint(writer->doc, writer->root, key, (uint64_t)value);
|
||||||
|
}
|
||||||
|
|
||||||
void saveJsonWriterAddStringLinux(
|
void saveJsonWriterAddStringLinux(
|
||||||
savejsonwriterlinux_t *writer, const char_t *key, const char_t *value
|
savejsonwriterlinux_t *writer, const char_t *key, const char_t *value
|
||||||
) {
|
) {
|
||||||
@@ -122,6 +128,14 @@ float_t saveJsonReadFloatLinux(
|
|||||||
return (float_t)yyjson_get_num(val);
|
return (float_t)yyjson_get_num(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t saveJsonReadUInt8Linux(
|
||||||
|
yyjson_val *root, const char_t *key, const uint8_t defaultValue
|
||||||
|
) {
|
||||||
|
yyjson_val *val = yyjson_obj_get(root, key);
|
||||||
|
if(!val || !yyjson_is_num(val)) return defaultValue;
|
||||||
|
return (uint8_t)yyjson_get_uint(val);
|
||||||
|
}
|
||||||
|
|
||||||
void saveJsonReadStringLinux(
|
void saveJsonReadStringLinux(
|
||||||
yyjson_val *root, const char_t *key, char_t *out, const size_t maxLen,
|
yyjson_val *root, const char_t *key, char_t *out, const size_t maxLen,
|
||||||
const char_t *defaultValue
|
const char_t *defaultValue
|
||||||
|
|||||||
@@ -42,6 +42,13 @@ void saveJsonWriterAddFloatLinux(
|
|||||||
savejsonwriterlinux_t *writer, const char_t *key, const float_t value
|
savejsonwriterlinux_t *writer, const char_t *key, const float_t value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a "key": <uint> field to the root object.
|
||||||
|
*/
|
||||||
|
void saveJsonWriterAddUInt8Linux(
|
||||||
|
savejsonwriterlinux_t *writer, const char_t *key, const uint8_t value
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a string field to the root object. The value is copied into the
|
* Adds a string field to the root object. The value is copied into the
|
||||||
* document, so the caller's buffer doesn't need to outlive the call.
|
* document, so the caller's buffer doesn't need to outlive the call.
|
||||||
@@ -120,6 +127,14 @@ float_t saveJsonReadFloatLinux(
|
|||||||
yyjson_val *root, const char_t *key, const float_t defaultValue
|
yyjson_val *root, const char_t *key, const float_t defaultValue
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a uint8 field, falling back to defaultValue if the key is
|
||||||
|
* missing or not a number.
|
||||||
|
*/
|
||||||
|
uint8_t saveJsonReadUInt8Linux(
|
||||||
|
yyjson_val *root, const char_t *key, const uint8_t defaultValue
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a string field into out, falling back to defaultValue if the key
|
* Reads a string field into out, falling back to defaultValue if the key
|
||||||
* is missing or not a string. Always null-terminates.
|
* is missing or not a string. Always null-terminates.
|
||||||
|
|||||||
@@ -120,6 +120,9 @@ errorret_t saveMetaLoadLinux(savemeta_t *out) {
|
|||||||
out->deadzone = saveJsonReadFloatLinux(
|
out->deadzone = saveJsonReadFloatLinux(
|
||||||
root, "deadzone", SAVE_META_DEADZONE_DEFAULT
|
root, "deadzone", SAVE_META_DEADZONE_DEFAULT
|
||||||
);
|
);
|
||||||
|
out->language = saveJsonReadUInt8Linux(
|
||||||
|
root, "language", SAVE_META_LANGUAGE_DEFAULT
|
||||||
|
);
|
||||||
out->exists = true;
|
out->exists = true;
|
||||||
|
|
||||||
yyjson_doc_free(doc);
|
yyjson_doc_free(doc);
|
||||||
@@ -136,6 +139,7 @@ errorret_t saveMetaWriteLinux(savemeta_t *meta) {
|
|||||||
errorChain(saveJsonWriterInitLinux(&writer));
|
errorChain(saveJsonWriterInitLinux(&writer));
|
||||||
saveJsonWriterAddUInt32Linux(&writer, "version", meta->version);
|
saveJsonWriterAddUInt32Linux(&writer, "version", meta->version);
|
||||||
saveJsonWriterAddFloatLinux(&writer, "deadzone", meta->deadzone);
|
saveJsonWriterAddFloatLinux(&writer, "deadzone", meta->deadzone);
|
||||||
|
saveJsonWriterAddUInt8Linux(&writer, "language", meta->language);
|
||||||
|
|
||||||
errorret_t ret = saveJsonWriterSaveLinux(&writer, path);
|
errorret_t ret = saveJsonWriterSaveLinux(&writer, path);
|
||||||
saveJsonWriterDisposeLinux(&writer);
|
saveJsonWriterDisposeLinux(&writer);
|
||||||
|
|||||||
Reference in New Issue
Block a user