Wire keyboard into save naming, add fatal error overlay, cutscene keyboard item

- uimainmenu: removed the temporary keyboard test entry now that the
  keyboard has a real caller.
- uiselectsave: picking an empty save slot now opens the keyboard to
  name it (localized title "Enter game save file name"), writes the
  named slot to disk (mirroring the existing delete-confirm write
  pattern), and on a write failure opens the new fatal error overlay.
- uikeyboardopen_t gains a title override (NULL keeps the default
  "ENTER YOUR TEXT").
- New ui/overlay/uifatalerror: a minimal fullscreen, non-dismissible
  overlay (message + QUIT button, back disabled) for unrecoverable
  errors - a nicer alternative to a raw assert crash. Draws above
  everything else in the UI element list.
- New CUTSCENE_ITEM_TYPE_KEYBOARD cutscene item: opens the keyboard
  with an embedded uikeyboardopen_t, blocks the cutscene until it
  closes, then caches the entered text via a new general-purpose
  cutscenesystem_t.textCache (CUTSCENE_TEXT_CACHE_MAX, with get/set
  accessors) mirroring the existing entity/area/text-mini id caching
  pattern.
This commit is contained in:
2026-08-28 08:29:07 -05:00
parent a6e4e3f71f
commit 51f262efa0
19 changed files with 399 additions and 72 deletions
+3
View File
@@ -82,6 +82,9 @@ msgstr "Delete a Save"
msgid "ui.select_save.delete_confirm"
msgstr "Are you sure you want to delete this save?"
msgid "ui.select_save.name_title"
msgstr "Enter game save file name"
msgid "ui.save_slot.number_format"
msgstr "Slot %d"
+10
View File
@@ -161,6 +161,16 @@ typedef struct cutscene_s {
#define CUTSCENE_MODAL_CLOSE() \
{ .type = CUTSCENE_ITEM_TYPE_MODAL_CLOSE }
// Opens the on-screen keyboard and blocks the cutscene until it closes,
// then caches whatever was typed - see cutsceneSystemGetTextCache to
// read it back afterwards. __VA_ARGS__ are uikeyboardopen_t designated
// initializers, e.g. CUTSCENE_KEYBOARD(.cancel = true, .maxLength = 8).
#define CUTSCENE_KEYBOARD(...) \
{ \
.type = CUTSCENE_ITEM_TYPE_KEYBOARD, \
.keyboard = { .open = { __VA_ARGS__ } } \
}
// (Re)requests an available save device and jumps straight to
// SUCCESS_MARKER or FAILURE_MARKER once it resolves, same as a
// CUTSCENE_MODAL_OPTIONS callback - it does not fall through to
+13
View File
@@ -35,6 +35,7 @@ void cutsceneSystemPrepare(
CUTSCENE_SYSTEM.entityLastRef = NULL;
CUTSCENE_SYSTEM.areaLastCreated = CUTSCENE_AREA_LAST_CREATED;
CUTSCENE_SYSTEM.textMiniLastCreated = CUTSCENE_TEXT_MINI_LAST_CREATED;
CUTSCENE_SYSTEM.textCache[0] = '\0';
CUTSCENE_SYSTEM.currentItem = 0xFF;// Set to 0xFF so Next wraps to 0.
CUTSCENE_SYSTEM.onComplete = NULL;
}
@@ -109,6 +110,7 @@ void cutsceneSystemNext() {
CUTSCENE_SYSTEM.entityLastRef = NULL;
CUTSCENE_SYSTEM.areaLastCreated = CUTSCENE_AREA_LAST_CREATED;
CUTSCENE_SYSTEM.textMiniLastCreated = CUTSCENE_TEXT_MINI_LAST_CREATED;
CUTSCENE_SYSTEM.textCache[0] = '\0';
CUTSCENE_SYSTEM.onComplete = NULL;
if(onComplete != NULL) onComplete(userData);
@@ -218,6 +220,16 @@ uint8_t cutsceneSystemGetTextMiniId(const uint8_t index) {
return index;
}
const char_t * cutsceneSystemGetTextCache(void) {
return CUTSCENE_SYSTEM.textCache;
}
void cutsceneSystemSetTextCache(const char_t *text) {
stringCopy(
CUTSCENE_SYSTEM.textCache, text, CUTSCENE_TEXT_CACHE_MAX - 1
);
}
void cutsceneSystemDispose() {
CUTSCENE_SYSTEM.scene = NULL;
CUTSCENE_SYSTEM.currentItem = 0xFF;
@@ -228,5 +240,6 @@ void cutsceneSystemDispose() {
CUTSCENE_SYSTEM.entityLastRef = NULL;
CUTSCENE_SYSTEM.areaLastCreated = CUTSCENE_AREA_LAST_CREATED;
CUTSCENE_SYSTEM.textMiniLastCreated = CUTSCENE_TEXT_MINI_LAST_CREATED;
CUTSCENE_SYSTEM.textCache[0] = '\0';
CUTSCENE_SYSTEM.onComplete = NULL;
}
+32
View File
@@ -21,6 +21,11 @@ typedef struct entity_s entity_t;
// cutscene_t.dataSize.
#define CUTSCENE_SYSTEM_SIZE_MAX 8192
// Size of CUTSCENE_SYSTEM.textCache - keep >= UI_KEYBOARD_TEXT_MAX (see
// ui/dialog/keyboard/uikeyboard.h) so text entered via a
// CUTSCENE_ITEM_TYPE_KEYBOARD item is never truncated caching it here.
#define CUTSCENE_TEXT_CACHE_MAX 64
typedef struct {
const cutscene_t *scene;
uint8_t currentItem;
@@ -32,6 +37,12 @@ typedef struct {
uint8_t areaLastCreated;
uint8_t textMiniLastCreated;
// Free-form text cache, e.g. holding whatever was last typed via a
// CUTSCENE_ITEM_TYPE_KEYBOARD item - see cutsceneSystemGetTextCache/
// cutsceneSystemSetTextCache. Not tied to any one item type; any item
// may read or write it.
char_t textCache[CUTSCENE_TEXT_CACHE_MAX];
// Data (used by the current item).
cutsceneitemdata_t data;
@@ -141,6 +152,27 @@ uint8_t cutsceneSystemGetAreaId(const uint8_t areaId);
*/
uint8_t cutsceneSystemGetTextMiniId(const uint8_t index);
/**
* Returns CUTSCENE_SYSTEM.textCache - whatever was last written there via
* cutsceneSystemSetTextCache (e.g. by a CUTSCENE_ITEM_TYPE_KEYBOARD item
* once its keyboard closes). Empty ("") if nothing has been cached yet
* for the running cutscene.
*
* @returns The cached text.
*/
const char_t * cutsceneSystemGetTextCache(void);
/**
* Overwrites CUTSCENE_SYSTEM.textCache with a copy of text. Any item may
* call this - it isn't tied to any one item type - so later items can
* read back whatever the caller wants to pass along, up to
* CUTSCENE_TEXT_CACHE_MAX - 1 characters.
*
* @param text The text to cache; copied internally, safe to be
* transient. Must not exceed CUTSCENE_TEXT_CACHE_MAX - 1 characters.
*/
void cutsceneSystemSetTextCache(const char_t *text);
/**
* Advance to the next item in the cutscene.
*/
@@ -172,6 +172,11 @@ cutsceneitemcallbacks_t CUTSCENE_ITEM_CALLBACKS[CUTSCENE_ITEM_TYPE_COUNT] = {
[CUTSCENE_ITEM_TYPE_SAVE_LOAD_ALL_SLOTS] = {
.init = cutsceneSaveLoadAllSlotsStart,
.update = cutsceneSaveLoadAllSlotsUpdate
},
[CUTSCENE_ITEM_TYPE_KEYBOARD] = {
.init = cutsceneKeyboardStart,
.update = cutsceneKeyboardUpdate
}
};
@@ -28,6 +28,7 @@
#include "ui/cutsceneshake.h"
#include "ui/cutscenemodal.h"
#include "ui/cutscenemodaloptionsmarkers.h"
#include "ui/cutscenekeyboard.h"
#include "item/cutsceneitemgive.h"
#include "maparea/cutscenemapareaadd.h"
#include "maparea/cutscenemaparearemove.h"
@@ -76,6 +77,7 @@ typedef enum {
CUTSCENE_ITEM_TYPE_SCENE,
CUTSCENE_ITEM_TYPE_SAVE_DEVICE_CHECK,
CUTSCENE_ITEM_TYPE_SAVE_LOAD_ALL_SLOTS,
CUTSCENE_ITEM_TYPE_KEYBOARD,
CUTSCENE_ITEM_TYPE_COUNT
} cutsceneitemtype_t;
@@ -115,6 +117,7 @@ struct cutsceneitem_s {
cutscenescene_t sceneChange;
cutscenesavedevicecheck_t saveDeviceCheck;
cutscenesaveloadallslots_t saveLoadAllSlots;
cutscenekeyboard_t keyboard;
};
};
@@ -13,4 +13,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
cutsceneshake.c
cutscenemodal.c
cutscenemodaloptionsmarkers.c
cutscenekeyboard.c
)
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "rpg/cutscene/item/cutsceneitem.h"
#include "rpg/cutscene/cutscenesystem.h"
#include "ui/dialog/keyboard/uikeyboard.h"
void cutsceneKeyboardStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
uiKeyboardOpen(&item->keyboard.open);
}
bool_t cutsceneKeyboardUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
if(uiKeyboardIsOpen()) return false;
cutsceneSystemSetTextCache(UI_KEYBOARD.text);
return true;
}
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
#include "ui/dialog/keyboard/uikeyboard.h"
typedef struct cutsceneitem_s cutsceneitem_t;
typedef union cutsceneitemdata_u cutsceneitemdata_t;
typedef struct {
// Passed straight through to uiKeyboardOpen - see uikeyboardopen_t.
uikeyboardopen_t open;
} cutscenekeyboard_t;
/**
* Starts a keyboard item (opens the on-screen keyboard with the item's
* open parameters, unmodified - see uiKeyboardOpen).
*
* @param item The cutscene item.
* @param data Runtime data storage.
*/
void cutsceneKeyboardStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
/**
* Updates a keyboard item. Blocks the cutscene while the keyboard is
* open; once it closes (confirmed or cancelled), caches its resulting
* text via cutsceneSystemSetTextCache (see cutsceneSystemGetTextCache)
* before completing, regardless of whether confirm or cancel was
* picked - check UI_KEYBOARD.confirmed from the item's own onInput
* callback if that distinction matters.
*
* @param item The cutscene item.
* @param data Runtime data storage.
* @returns true once the keyboard has closed; false while still open.
*/
bool_t cutsceneKeyboardUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
+2 -1
View File
@@ -424,7 +424,8 @@ void uiKeyboardOpen(const uikeyboardopen_t *open) {
);
stringCopy(
UI_KEYBOARD.titleText, UI_KEYBOARD_TITLE_DEFAULT,
UI_KEYBOARD.titleText,
open->title != NULL ? open->title : UI_KEYBOARD_TITLE_DEFAULT,
UI_KEYBOARD_TITLE_TEXT_MAX - 1
);
UI_KEYBOARD.titleLabel.dirty = true;
+8 -2
View File
@@ -118,10 +118,16 @@ typedef void (*uikeyboardinputcallback_t)(
typedef bool_t (*uikeyboardkeypresscallback_t)(const char_t c, void *user);
/**
* Parameters for uiKeyboardOpen. Expect this to grow (e.g. title/button
* text overrides) as more dialogs start using the keyboard.
* Parameters for uiKeyboardOpen. Expect this to grow (e.g. button text
* overrides) as more dialogs start using the keyboard.
*/
typedef struct {
// Title text shown above the entered text; copied internally, safe to
// be transient. Displayed as-is - resolve any locale string yourself
// before passing it in. NULL uses UI_KEYBOARD_TITLE_DEFAULT ("ENTER
// YOUR TEXT").
const char_t *title;
// Fired once the dialog is dismissed, confirmed or cancelled. May be
// NULL.
uikeyboardinputcallback_t onInput;
+59
View File
@@ -8,10 +8,13 @@
#include "uiselectsave.h"
#include "ui/widget/uiframe.h"
#include "ui/dialog/uiconfirm.h"
#include "ui/dialog/keyboard/uikeyboard.h"
#include "ui/overlay/uifatalerror.h"
#include "save/save.h"
#include "time/timeepoch.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "util/string.h"
#include "display/screen/screen.h"
#include "display/text/text.h"
#include "display/color.h"
@@ -89,6 +92,57 @@ void uiSelectSaveConfirmDelete(const uint8_t index) {
);
}
void uiSelectSaveNameEntered(
const char_t *text,
const bool_t confirmed,
void *user
) {
if(!confirmed) return;
assertTrue(SAVE.deviceCurrent != 0xFF, "No current device");
const uint8_t index = UI_SELECT_SAVE.pendingNameIndex;
saveslot_t slot;
saveSlotInit(&slot);
stringCopy(slot.cachedData.name, text, SAVE_SLOT_NAME_LENGTH);
errorret_t writeResult = saveDeviceSlotWrite(
&SAVE.devices[SAVE.deviceCurrent], &slot, index
);
if(errorIsNotOk(writeResult)) {
errorCatch(errorPrint(writeResult));
uiFatalErrorOpen(writeResult.state->message);
return;
}
SAVE.caches[index] = slot.cachedData;
uiSelectSaveRefreshSlot(index);
UI_SELECT_SAVE.result = index;
uiSelectSaveClose();
}
void uiSelectSaveNameEmptySlot(const uint8_t index) {
UI_SELECT_SAVE.pendingNameIndex = index;
char_t title[UI_KEYBOARD_TITLE_TEXT_MAX];
errorret_t result = assetLocaleGetString(
&LOCALE.entry->data.locale, "ui.select_save.name_title", 0,
title, sizeof(title)
);
if(errorIsNotOk(result)) errorCatch(result);
uikeyboardopen_t open = {
.title = title,
.onInput = uiSelectSaveNameEntered,
.cancel = true,
.maxLength = SAVE_SLOT_NAME_LENGTH,
.trimmed = true,
.allowBlank = false
};
uiKeyboardOpen(&open);
}
void uiSelectSaveSetActionLabel(const uiselectsavetype_t type) {
const char_t *labelKey = type == UI_SELECT_SAVE_TYPE_LOAD ?
"ui.select_save.delete_mode" : "ui.confirm.cancel";
@@ -132,6 +186,11 @@ void uiSelectSaveSlotSelected(
return;
}
if(!saveSlotInUse(&SAVE.caches[index])) {
uiSelectSaveNameEmptySlot(index);
return;
}
UI_SELECT_SAVE.result = index;
uiSelectSaveClose();
}
+1
View File
@@ -62,6 +62,7 @@ typedef struct {
uisaveslot_t slots[SAVE_SLOT_COUNT];
uiscrolling_t scroll;
uint8_t pendingDeleteIndex;
uint8_t pendingNameIndex;
uiselectsaveresultcallback_t callback;
void *user;
+1
View File
@@ -8,4 +8,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
uicrop.c
uifullbox.c
uiloading.c
uifatalerror.c
)
+108
View File
@@ -0,0 +1,108 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "uifatalerror.h"
#include "ui/widget/uiframe.h"
#include "ui/widget/uibutton.h"
#include "engine/engine.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "util/string.h"
#include "util/math.h"
#include "display/screen/screen.h"
#include "display/color.h"
#include "display/text/font.h"
#include "display/spritebatch/spritebatch.h"
uifatalerror_t UI_FATAL_ERROR;
void uiFatalErrorMenuSelected(
const uimenu_t *menu,
const uint8_t index,
const uimenuitem_t *item
) {
ENGINE.running = false;
}
errorret_t uiFatalErrorInit(void) {
memoryZero(&UI_FATAL_ERROR, sizeof(uifatalerror_t));
uiLabelInit(
&UI_FATAL_ERROR.messageLabel, UI_FATAL_ERROR.messageText,
UI_FATAL_ERROR.messageSprites, UI_FATAL_ERROR_MESSAGE_SPRITES_MAX
);
errorOk();
}
void uiFatalErrorOpen(const char_t *message) {
assertNotNull(message, "Message cannot be NULL");
// This is the last line of defense - it must never itself fail, so a
// second fatal error while one is already showing is silently dropped
// rather than asserting.
if(UI_FATAL_ERROR.open) return;
stringCopy(
UI_FATAL_ERROR.messageText, message, UI_FATAL_ERROR_MESSAGE_MAX - 1
);
UI_FATAL_ERROR.messageLabel.dirty = true;
uiLabelRebuffer(&UI_FATAL_ERROR.messageLabel);
UI_FATAL_ERROR.open = true;
uiMenuInit(&UI_FATAL_ERROR.menu, uiFatalErrorMenuSelected, NULL, NULL);
UI_FATAL_ERROR.items[0].type = UI_MENU_WIDGET_TYPE_BUTTON;
uiButtonInit(&UI_FATAL_ERROR.items[0].button, UI_FATAL_ERROR_QUIT_LABEL);
uiMenuSetItems(
&UI_FATAL_ERROR.menu, UI_FATAL_ERROR.items, UI_FATAL_ERROR_ITEM_COUNT, 1
);
// No way out but the QUIT button - this is a fatal, unrecoverable
// condition.
uiMenuSetDisableBack(&UI_FATAL_ERROR.menu, true);
uiMenuOpen(&UI_FATAL_ERROR.menu);
}
bool_t uiFatalErrorIsOpen(void) {
return UI_FATAL_ERROR.open;
}
errorret_t uiFatalErrorDraw(void) {
if(!UI_FATAL_ERROR.open) errorOk();
const float_t x = (float_t)SCREEN.scanX;
const float_t y = (float_t)SCREEN.scanY;
const float_t width = (float_t)SCREEN.scanWidth;
const float_t height = (float_t)SCREEN.scanHeight;
errorChain(uiFrameDraw(x, y, width, height));
const float_t rowHeight = (float_t)FONT_DEFAULT.tileset->tileHeight;
const float_t contentWidth = mathMax(
(float_t)UI_FATAL_ERROR.messageLabel.width,
(float_t)UI_FATAL_ERROR.items[0].button.label.width
);
const float_t contentHeight = (float_t)UI_FATAL_ERROR.messageLabel.height +
UI_FRAME_PADDING_Y + rowHeight;
const float_t contentX = x + (width - contentWidth) * 0.5f;
const float_t contentY = y + (height - contentHeight) * 0.5f;
uiLabelSetX(&UI_FATAL_ERROR.messageLabel, contentX);
uiLabelSetY(&UI_FATAL_ERROR.messageLabel, contentY);
errorChain(uiLabelRender(&UI_FATAL_ERROR.messageLabel, COLOR_WHITE));
const float_t menuY = contentY +
(float_t)UI_FATAL_ERROR.messageLabel.height + UI_FRAME_PADDING_Y;
errorChain(uiMenuDraw(&UI_FATAL_ERROR.menu, contentX, menuY, contentWidth, rowHeight));
errorChain(spriteBatchFlush());
errorOk();
}
errorret_t uiFatalErrorDispose(void) {
errorOk();
}
+71
View File
@@ -0,0 +1,71 @@
/**
* 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 "ui/widget/uilabel.h"
#include "ui/widget/uimenu.h"
#define UI_FATAL_ERROR_MESSAGE_MAX 256
#define UI_FATAL_ERROR_MESSAGE_SPRITES_MAX UI_FATAL_ERROR_MESSAGE_MAX
#define UI_FATAL_ERROR_ITEM_COUNT 1
#define UI_FATAL_ERROR_QUIT_LABEL "QUIT"
typedef struct {
bool_t open;
uilabel_t messageLabel;
char_t messageText[UI_FATAL_ERROR_MESSAGE_MAX];
spritebatchsprite_t messageSprites[UI_FATAL_ERROR_MESSAGE_SPRITES_MAX];
uimenu_t menu;
uimenuitem_t items[UI_FATAL_ERROR_ITEM_COUNT];
} uifatalerror_t;
extern uifatalerror_t UI_FATAL_ERROR;
/**
* Initializes the fatal error overlay.
*
* @return Any error that occurs.
*/
errorret_t uiFatalErrorInit(void);
/**
* Opens the fatal error overlay, a fullscreen, non-dismissible display
* for an unrecoverable error - the only way out is its QUIT button,
* which sets ENGINE.running to false. Intended as a last-resort, nicer-
* looking alternative to a raw assert crash for a genuinely fatal
* condition, so it must never itself fail: a second call while already
* open is silently ignored rather than asserting, and it draws above
* every other UI element.
*
* @param message The error text to display; copied internally, safe to
* be transient. Truncated to UI_FATAL_ERROR_MESSAGE_MAX - 1 characters.
*/
void uiFatalErrorOpen(const char_t *message);
/**
* Returns whether the fatal error overlay is currently open.
*
* @returns True if open.
*/
bool_t uiFatalErrorIsOpen(void);
/**
* Draws the fatal error overlay. No-op when not open.
*
* @return Any error that occurs.
*/
errorret_t uiFatalErrorDraw(void);
/**
* Disposes of the fatal error overlay.
*
* @return Any error that occurs.
*/
errorret_t uiFatalErrorDispose(void);
-38
View File
@@ -16,15 +16,11 @@
#include "locale/localemanager.h"
#include "asset/loader/locale/assetlocaleloader.h"
#include "ui/dialog/uiconfirm.h"
#include "ui/dialog/keyboard/uikeyboard.h"
#include "scene/mainmenu/scenemainmenu.h"
#include "console/console.h"
#define UI_MAIN_MENU_INDEX_START_GAME 0
#define UI_MAIN_MENU_INDEX_OPTIONS 1
#define UI_MAIN_MENU_INDEX_QUIT 2
// TODO: temporary - see UI_MAIN_MENU_ITEM_COUNT in uimainmenu.h.
#define UI_MAIN_MENU_INDEX_LOAD_GAME_TEST 3
uimainmenu_t UI_MAIN_MENU;
@@ -32,22 +28,6 @@ void uiMainMenuQuitConfirmed(const bool_t result, void *user) {
if(result) ENGINE.running = false;
}
bool_t uiMainMenuKeyboardTestKeyPress(const char_t c, void *user) {
consolePrint("uiKeyboard onKeyPress: '%c'", c);
return true;
}
void uiMainMenuKeyboardTestInput(
const char_t *text,
const bool_t confirmed,
void *user
) {
consolePrint(
"uiKeyboard onInput: confirmed=%s text='%s'",
confirmed ? "true" : "false", text
);
}
void uiMainMenuSelected(
const uimenu_t *menu,
const uint8_t index,
@@ -68,22 +48,6 @@ void uiMainMenuSelected(
uiConfirmOpen("main_menu.quit_confirm", uiMainMenuQuitConfirmed, NULL);
break;
case UI_MAIN_MENU_INDEX_LOAD_GAME_TEST: {
uikeyboardopen_t open = {
.onInput = uiMainMenuKeyboardTestInput,
.onKeyPress = uiMainMenuKeyboardTestKeyPress,
.cancel = true,
.confirm = true,
.cancelConfirm = true,
.user = NULL,
.maxLength = 6,
.lineCount = 2,
.allowBlank = true,
};
uiKeyboardOpen(&open);
break;
}
default:
break;
}
@@ -120,8 +84,6 @@ errorret_t uiMainMenuInit(void) {
MENU_BUTTON(UI_MAIN_MENU.startGameLabel);
MENU_BUTTON(UI_MAIN_MENU.optionsLabel);
MENU_BUTTON(UI_MAIN_MENU.quitLabel);
// TODO: temporary - see UI_MAIN_MENU_ITEM_COUNT in uimainmenu.h.
MENU_BUTTON("LOAD GAME (TEST)");
MENU_END(UI_MAIN_MENU.items, 1);
// The main menu is the root screen once past the initial boot check -
+2 -31
View File
@@ -9,12 +9,9 @@
#include "error/error.h"
#include "ui/widget/uimenu.h"
// TODO: item count/height bumped for the temporary "LOAD GAME (TEST)"
// keyboard test entry in uiMainMenuSelected - drop back to 3/160 once
// the keyboard is wired up somewhere real and this is removed.
#define UI_MAIN_MENU_ITEM_COUNT 4
#define UI_MAIN_MENU_ITEM_COUNT 3
#define UI_MAIN_MENU_WIDTH 200.0f
#define UI_MAIN_MENU_HEIGHT 200.0f
#define UI_MAIN_MENU_HEIGHT 160.0f
#define UI_MAIN_MENU_LABEL_MAX 32
typedef struct {
@@ -52,29 +49,3 @@ errorret_t uiMainMenuDraw(void);
* @return Any error that occurs.
*/
errorret_t uiMainMenuDispose(void);
// TODO: temporary keyboard test hooks - see UI_MAIN_MENU_INDEX_LOAD_GAME_TEST
// in uimainmenu.c. Remove once the keyboard is wired up somewhere real.
/**
* Test onKeyPress callback - console-prints every key press and allows
* all of them.
*
* @param c The character about to be entered.
* @param user Unused.
* @returns Always true.
*/
bool_t uiMainMenuKeyboardTestKeyPress(const char_t c, void *user);
/**
* Test onInput callback - console-prints the final result.
*
* @param text The entered text.
* @param confirmed Whether confirm (vs cancel) was picked.
* @param user Unused.
*/
void uiMainMenuKeyboardTestInput(
const char_t *text,
const bool_t confirmed,
void *user
);
+6
View File
@@ -10,6 +10,7 @@
#include "ui/debug/uifps.h"
#include "ui/overlay/uifullbox.h"
#include "ui/overlay/uiloading.h"
#include "ui/overlay/uifatalerror.h"
#include "ui/debug/uiplayerpos.h"
#include "ui/overlay/uicrop.h"
#include "ui/transition/uitransition.h"
@@ -135,6 +136,11 @@ uielement_t UI_ELEMENTS[] = {
.update = uiLoadingUpdate,
.draw = uiLoadingDraw
},
{
.init = uiFatalErrorInit,
.draw = uiFatalErrorDraw,
.dispose = uiFatalErrorDispose
},
// ===========================================================================
// Important rendering components, lives outside the primary game engine