Add declarative cutscene items for save checks and marker-based modals

CUTSCENE_SAVE_DEVICE_CHECK and CUTSCENE_SAVE_LOAD_ALL_SLOTS wrap the
existing device-lookup/slot-load calls and jump straight to a
success/failure marker, and CUTSCENE_MODAL_OPTIONS_ONE/TWO do the same
for one/two-option modals, removing the need for a hand-written
goTo-only callback per use. Main menu's "Start Game" now runs a
cutscene (mirroring the initial scene's save-check flow) that loads all
slots before opening the load-game picker, retrying on error; the
initial scene's own device check is migrated onto the same items.
Backing out of the main menu now returns to the initial scene.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 20:29:57 -05:00
parent ec59e77867
commit 1a199f6ce3
16 changed files with 460 additions and 29 deletions
+27
View File
@@ -38,6 +38,33 @@ msgstr "Quit Game"
msgid "main_menu.quit_confirm"
msgstr "Are you sure you want to quit?"
msgid "main_menu.checking_save.title"
msgstr "Checking for save data"
msgid "main_menu.checking_save.message"
msgstr "Please wait..."
msgid "main_menu.no_device.title"
msgstr "No Save Device Found"
msgid "main_menu.no_device.message"
msgstr "Could not find a save device, ensure it is connected and try again. You can continue, but progress will not be saved."
msgid "main_menu.no_device.retry"
msgstr "Try again"
msgid "main_menu.no_device.continue"
msgstr "Continue without saving"
msgid "main_menu.save_load_error.title"
msgstr "Error"
msgid "main_menu.save_load_error.message"
msgstr "Failed to load save data. Please try again."
msgid "main_menu.save_load_error.retry"
msgstr "Try Again"
# Select Save Screen
msgid "ui.select_save.title"
+64
View File
@@ -120,6 +120,42 @@ typedef struct cutscene_s {
} \
}
// Same as CUTSCENE_MODAL_OPTIONS, but fixed to exactly one option and
// MARKER1 to jump straight to via cutsceneGoTo once it's selected (or
// the dialog is backed out of) - no callback function to write. Does
// not fall through to whatever follows this item, so MARKER1 must be
// scripted elsewhere in the same cutscene.
#define CUTSCENE_MODAL_OPTIONS_ONE(TITLE, MESSAGE, OPTION1, MARKER1) \
{ \
.type = CUTSCENE_ITEM_TYPE_MODAL_OPTIONS_MARKERS, \
.modalOptionsMarkers = { \
.title = TITLE, .message = MESSAGE, \
.options = { OPTION1 }, \
.markers = { MARKER1 }, \
.optionCount = 1 \
} \
}
// Same as CUTSCENE_MODAL_OPTIONS, but fixed to exactly two options,
// jumping straight to OPTION1_MARKER or OPTION2_MARKER via cutsceneGoTo
// once the corresponding option is selected - no callback function to
// write. Backing out without selecting (UI_MODAL_RESULT_NONE) is
// treated the same as selecting option 2. Does not fall through to
// whatever follows this item, so both markers must be scripted
// elsewhere in the same cutscene.
#define CUTSCENE_MODAL_OPTIONS_TWO( \
TITLE, MESSAGE, OPTION1, OPTION1_MARKER, OPTION2, OPTION2_MARKER \
) \
{ \
.type = CUTSCENE_ITEM_TYPE_MODAL_OPTIONS_MARKERS, \
.modalOptionsMarkers = { \
.title = TITLE, .message = MESSAGE, \
.options = { OPTION1, OPTION2 }, \
.markers = { OPTION1_MARKER, OPTION2_MARKER }, \
.optionCount = 2 \
} \
}
// Closes the currently open modal (if any). Useful when a modal was
// opened outside of a blocking CUTSCENE_MODAL item (e.g. directly via
// uiModalOpen) and this cutscene just needs to dismiss it and continue
@@ -127,6 +163,34 @@ typedef struct cutscene_s {
#define CUTSCENE_MODAL_CLOSE() \
{ .type = CUTSCENE_ITEM_TYPE_MODAL_CLOSE }
// (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
// whatever follows this item, so both markers must be scripted
// elsewhere in the same cutscene.
#define CUTSCENE_SAVE_DEVICE_CHECK(SUCCESS_MARKER, FAILURE_MARKER) \
{ \
.type = CUTSCENE_ITEM_TYPE_SAVE_DEVICE_CHECK, \
.saveDeviceCheck = { \
.successMarker = SUCCESS_MARKER, \
.failureMarker = FAILURE_MARKER \
} \
}
// (Re)loads every save slot via saveLoadAllSlots() and jumps straight to
// SUCCESS_MARKER or FAILURE_MARKER once it resolves, same shape as
// CUTSCENE_SAVE_DEVICE_CHECK - it does not fall through to whatever
// follows this item, so both markers must be scripted elsewhere in the
// same cutscene.
#define CUTSCENE_SAVE_LOAD_ALL_SLOTS(SUCCESS_MARKER, FAILURE_MARKER) \
{ \
.type = CUTSCENE_ITEM_TYPE_SAVE_LOAD_ALL_SLOTS, \
.saveLoadAllSlots = { \
.successMarker = SUCCESS_MARKER, \
.failureMarker = FAILURE_MARKER \
} \
}
#define CUTSCENE_ENTITY_WALK_TO(ENTITY_INDEX, X, Y, Z) \
{ \
.type = CUTSCENE_ITEM_TYPE_ENTITY_WALK_TO, \
@@ -16,3 +16,4 @@ add_subdirectory(item)
add_subdirectory(maparea)
add_subdirectory(ui)
add_subdirectory(battle)
add_subdirectory(save)
+15
View File
@@ -134,6 +134,11 @@ cutsceneitemcallbacks_t CUTSCENE_ITEM_CALLBACKS[CUTSCENE_ITEM_TYPE_COUNT] = {
.update = cutsceneModalUpdate
},
[CUTSCENE_ITEM_TYPE_MODAL_OPTIONS_MARKERS] = {
.init = cutsceneModalOptionsMarkersStart,
.update = cutsceneModalOptionsMarkersUpdate
},
[CUTSCENE_ITEM_TYPE_MODAL_CLOSE] = {
.init = cutsceneModalCloseStart,
.update = cutsceneModalCloseUpdate
@@ -157,6 +162,16 @@ cutsceneitemcallbacks_t CUTSCENE_ITEM_CALLBACKS[CUTSCENE_ITEM_TYPE_COUNT] = {
[CUTSCENE_ITEM_TYPE_SCENE] = {
.init = cutsceneSceneStart,
.update = cutsceneSceneUpdate
},
[CUTSCENE_ITEM_TYPE_SAVE_DEVICE_CHECK] = {
.init = cutsceneSaveDeviceCheckStart,
.update = cutsceneSaveDeviceCheckUpdate
},
[CUTSCENE_ITEM_TYPE_SAVE_LOAD_ALL_SLOTS] = {
.init = cutsceneSaveLoadAllSlotsStart,
.update = cutsceneSaveLoadAllSlotsUpdate
}
};
@@ -27,6 +27,7 @@
#include "ui/cutsceneemoji.h"
#include "ui/cutsceneshake.h"
#include "ui/cutscenemodal.h"
#include "ui/cutscenemodaloptionsmarkers.h"
#include "item/cutsceneitemgive.h"
#include "maparea/cutscenemapareaadd.h"
#include "maparea/cutscenemaparearemove.h"
@@ -34,6 +35,8 @@
#include "battle/cutscenestartbattle.h"
#include "battle/cutscenebattlewaitstate.h"
#include "battle/cutscenebattleforceaction.h"
#include "save/cutscenesavedevicecheck.h"
#include "save/cutscenesaveloadallslots.h"
typedef struct cutscene_s cutscene_t;
@@ -65,11 +68,14 @@ typedef enum {
CUTSCENE_ITEM_TYPE_BATTLE_WAIT_STATE,
CUTSCENE_ITEM_TYPE_BATTLE_FORCE_ACTION,
CUTSCENE_ITEM_TYPE_MODAL,
CUTSCENE_ITEM_TYPE_MODAL_OPTIONS_MARKERS,
CUTSCENE_ITEM_TYPE_MODAL_CLOSE,
CUTSCENE_ITEM_TYPE_PRINT,
CUTSCENE_ITEM_TYPE_MARKER,
CUTSCENE_ITEM_TYPE_RESTART,
CUTSCENE_ITEM_TYPE_SCENE,
CUTSCENE_ITEM_TYPE_SAVE_DEVICE_CHECK,
CUTSCENE_ITEM_TYPE_SAVE_LOAD_ALL_SLOTS,
CUTSCENE_ITEM_TYPE_COUNT
} cutsceneitemtype_t;
@@ -103,9 +109,12 @@ struct cutsceneitem_s {
cutscenebattlewaitstate_t battleWaitState;
cutscenebattleforceaction_t battleForceAction;
cutscenemodal_t modal;
cutscenemodaloptionsmarkers_t modalOptionsMarkers;
cutsceneprint_t print;
cutscenemarker_t marker;
cutscenescene_t sceneChange;
cutscenesavedevicecheck_t saveDeviceCheck;
cutscenesaveloadallslots_t saveLoadAllSlots;
};
};
@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
cutscenesavedevicecheck.c
cutscenesaveloadallslots.c
)
@@ -0,0 +1,33 @@
/**
* 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 "save/save.h"
void cutsceneSaveDeviceCheckCallback(savedevice_t *device, void *user) {
const cutsceneitem_t *item = cutsceneSystemGetCurrentItem();
cutsceneGoTo(
device != NULL ?
item->saveDeviceCheck.successMarker :
item->saveDeviceCheck.failureMarker
);
}
void cutsceneSaveDeviceCheckStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
saveFindAvailableDevice(cutsceneSaveDeviceCheckCallback, NULL);
}
bool_t cutsceneSaveDeviceCheckUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
return false;
}
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct cutsceneitem_s cutsceneitem_t;
typedef union cutsceneitemdata_u cutsceneitemdata_t;
typedef struct {
const char_t *successMarker;
const char_t *failureMarker;
} cutscenesavedevicecheck_t;
/**
* Starts a save-device-check item: (re)requests an available save
* device via saveFindAvailableDevice. Never completes on its own - see
* cutsceneSaveDeviceCheckUpdate.
*
* @param item The cutscene item.
* @param data Runtime data storage.
*/
void cutsceneSaveDeviceCheckStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
/**
* Updates a save-device-check item. Like a CUTSCENE_MODAL_OPTIONS item,
* this never completes on its own - once saveFindAvailableDevice's
* callback fires, it jumps straight to the item's successMarker or
* failureMarker via cutsceneGoTo.
*
* @param item The cutscene item.
* @param data Runtime data storage.
* @returns false always.
*/
bool_t cutsceneSaveDeviceCheckUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
@@ -0,0 +1,31 @@
/**
* 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 "save/save.h"
void cutsceneSaveLoadAllSlotsStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
errorret_t result = saveLoadAllSlots();
if(errorIsNotOk(result)) {
errorCatch(errorPrint(result));
cutsceneGoTo(item->saveLoadAllSlots.failureMarker);
return;
}
cutsceneGoTo(item->saveLoadAllSlots.successMarker);
}
bool_t cutsceneSaveLoadAllSlotsUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
return false;
}
@@ -0,0 +1,44 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct cutsceneitem_s cutsceneitem_t;
typedef union cutsceneitemdata_u cutsceneitemdata_t;
typedef struct {
const char_t *successMarker;
const char_t *failureMarker;
} cutscenesaveloadallslots_t;
/**
* Starts a save-load-all-slots item: calls saveLoadAllSlots() and jumps
* straight to the item's successMarker or failureMarker via
* cutsceneGoTo, depending on the result.
*
* @param item The cutscene item.
* @param data Runtime data storage.
*/
void cutsceneSaveLoadAllSlotsStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
/**
* Updates a save-load-all-slots item. Never completes on its own -
* Start already jumps to whichever marker applies before this would
* ever run.
*
* @param item The cutscene item.
* @param data Runtime data storage.
* @returns false always.
*/
bool_t cutsceneSaveLoadAllSlotsUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
@@ -12,4 +12,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
cutsceneemoji.c
cutsceneshake.c
cutscenemodal.c
cutscenemodaloptionsmarkers.c
)
@@ -0,0 +1,50 @@
/**
* 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/widget/uimodal.h"
void cutsceneModalOptionsMarkersCallback(
const uint8_t optionIndex,
void *userData
) {
const cutscenemodaloptionsmarkers_t *options =
&cutsceneSystemGetCurrentItem()->modalOptionsMarkers;
// A backed-out-of dialog (UI_MODAL_RESULT_NONE) falls back to the
// last option's marker, same as a hand-written two-option callback
// (e.g. sceneInitialSaveDeviceRetryCallback) treating "backed out" as
// the safe/continue choice rather than the destructive one.
const uint8_t index =
optionIndex < options->optionCount ? optionIndex : options->optionCount - 1;
cutsceneGoTo(options->markers[index]);
}
void cutsceneModalOptionsMarkersStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
const cutscenemodaloptionsmarkers_t *options = &item->modalOptionsMarkers;
uiModalOpen(
options->title,
options->message,
options->options,
options->optionCount,
cutsceneModalOptionsMarkersCallback,
NULL,
CUTSCENE_SYSTEM.userData
);
}
bool_t cutsceneModalOptionsMarkersUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
) {
return false;
}
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct cutsceneitem_s cutsceneitem_t;
typedef union cutsceneitemdata_u cutsceneitemdata_t;
// Backs CUTSCENE_MODAL_OPTIONS_ONE and CUTSCENE_MODAL_OPTIONS_TWO, so two
// is the most either macro ever needs.
#define CUTSCENE_MODAL_OPTIONS_MARKERS_MAX 2
typedef struct {
// Display text, or a locale message ID to translate - see
// uiModalLocalize.
char_t title[CUTSCENE_MODAL_TITLE_MAX_CHARS];
char_t message[CUTSCENE_MODAL_MESSAGE_MAX_CHARS];
// Each option's display text/locale message ID, and the marker to
// cutsceneGoTo when that option is selected.
const char_t *options[CUTSCENE_MODAL_OPTIONS_MARKERS_MAX];
const char_t *markers[CUTSCENE_MODAL_OPTIONS_MARKERS_MAX];
uint8_t optionCount;
} cutscenemodaloptionsmarkers_t;
/**
* Starts a modal-options-markers item (shows the modal dialog with the
* item's title, message, and options).
*
* @param item The cutscene item.
* @param data Runtime data storage.
*/
void cutsceneModalOptionsMarkersStart(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
/**
* Updates a modal-options-markers item. Never completes on its own -
* the cutscene blocks here indefinitely. Once an option is selected (or
* the dialog is backed out of, which is treated as selecting the last
* option), it jumps straight to that option's marker via cutsceneGoTo.
*
* @param item The cutscene item.
* @param data Runtime data storage.
* @returns false always.
*/
bool_t cutsceneModalOptionsMarkersUpdate(
const cutsceneitem_t *item,
cutsceneitemdata_t *data
);
+4 -21
View File
@@ -11,29 +11,24 @@
#include "error/error.h"
#include "display/screen/screen.h"
#include "console/console.h"
#include "save/save.h"
#include "ui/widget/uimodal.h"
#include "rpg/cutscene/cutscene.h"
#include "rpg/cutscene/cutscenesystem.h"
void sceneInitialAvailableDeviceCallback(savedevice_t *device, void *user);
void sceneInitialFindDevices(void *userData);
void sceneInitialSaveDeviceRetryCallback(const uint8_t opt, void *u);
CUTSCENE(INITIAL, 0, DEFAULT,
CUTSCENE_MODAL(
"initial.checking_save.title", "initial.checking_save.message"
),
CUTSCENE_WAIT(1.0f),
CUTSCENE_CALLBACK(sceneInitialFindDevices),
CUTSCENE_SAVE_DEVICE_CHECK("CONTINUE", "NO_DEVICE"),
CUTSCENE_MARKER("NO_DEVICE"),
CUTSCENE_MODAL_CLOSE(),
CUTSCENE_MODAL_OPTIONS(
CUTSCENE_MODAL_OPTIONS_TWO(
"initial.no_device.title",
"initial.no_device.message",
sceneInitialSaveDeviceRetryCallback,
"initial.no_device.retry", "initial.no_device.continue"
"initial.no_device.retry", "RETRY",
"initial.no_device.continue", "CONTINUE"
),
CUTSCENE_MARKER("RETRY"),
@@ -45,18 +40,6 @@ CUTSCENE(INITIAL, 0, DEFAULT,
CUTSCENE_SCENE(SCENE_TYPE_MAIN_MENU)
);
void sceneInitialAvailableDeviceCallback(savedevice_t *device, void *user) {
cutsceneGoTo(device == NULL ? "NO_DEVICE" : "CONTINUE");
}
void sceneInitialFindDevices(void *userData) {
saveFindAvailableDevice(sceneInitialAvailableDeviceCallback, NULL);
}
void sceneInitialSaveDeviceRetryCallback(const uint8_t opt, void *u) {
cutsceneGoTo(opt == 0 ? "RETRY" : "CONTINUE");
}
errorret_t sceneInitialInit(scenedata_t *sceneData) {
assertNotNull(sceneData, "Scene data cannot be null");
memoryZero(&sceneData->initial, sizeof(sceneinitial_t));
+64 -8
View File
@@ -17,13 +17,57 @@
#include "asset/loader/locale/assetlocaleloader.h"
#include "ui/dialog/uiconfirm.h"
#include "ui/dialog/save/uiselectsave.h"
#include "rpg/cutscene/cutscene.h"
#include "rpg/cutscene/cutscenesystem.h"
#include "scene/scene.h"
#include "save/save.h"
#define UI_MAIN_MENU_INDEX_START_GAME 0
#define UI_MAIN_MENU_INDEX_OPTIONS 1
#define UI_MAIN_MENU_INDEX_QUIT 2
void uiMainMenuOpenSelectSave(void *userData);
// Loads every save slot before opening the load-game picker, same
// checking/retry-on-error shape as the initial scene's device lookup
// (see scene/initial/sceneinitial.c) - the error branch loops back via
// CUTSCENE_RESTART.
CUTSCENE(MAIN_MENU_START_GAME, 0, DEFAULT,
CUTSCENE_MODAL(
"main_menu.checking_save.title",
"main_menu.checking_save.message"
),
CUTSCENE_WAIT(1.0f),
CUTSCENE_SAVE_DEVICE_CHECK("CONTINUE", "NO_DEVICE"),
CUTSCENE_MARKER("NO_DEVICE"),
CUTSCENE_MODAL_CLOSE(),
CUTSCENE_MODAL_OPTIONS_TWO(
"main_menu.no_device.title",
"main_menu.no_device.message",
"main_menu.no_device.retry", "RETRY",
"main_menu.no_device.continue", "CONTINUE"
),
CUTSCENE_MARKER("RETRY"),
CUTSCENE_MODAL_CLOSE(),
CUTSCENE_RESTART(),
CUTSCENE_MARKER("CONTINUE"),
CUTSCENE_MODAL_CLOSE(),
CUTSCENE_SAVE_LOAD_ALL_SLOTS("LOADED", "LOAD_ERROR"),
CUTSCENE_MARKER("LOAD_ERROR"),
CUTSCENE_MODAL_OPTIONS_ONE(
"main_menu.save_load_error.title",
"main_menu.save_load_error.message",
"main_menu.save_load_error.retry",
"RETRY"
),
CUTSCENE_MARKER("LOADED"),
CUTSCENE_CALLBACK(uiMainMenuOpenSelectSave)
);
uimainmenu_t UI_MAIN_MENU;
void uiMainMenuQuitConfirmed(const bool_t result, void *user) {
@@ -40,6 +84,21 @@ void uiMainMenuSelectSaveResult(const uint8_t slotIndex, void *user) {
sceneSet(SCENE_TYPE_OVERWORLD);
}
void uiMainMenuOpenSelectSave(void *userData) {
uiSelectSaveOpen(
UI_SELECT_SAVE_TYPE_LOAD, uiMainMenuSelectSaveResult, NULL
);
}
void uiMainMenuClosed(const uimenu_t *menu) {
if(UI_MAIN_MENU.suppressClosedSceneChange) {
UI_MAIN_MENU.suppressClosedSceneChange = false;
return;
}
sceneSet(SCENE_TYPE_INITIAL);
}
void uiMainMenuSelected(
const uimenu_t *menu,
const uint8_t index,
@@ -48,13 +107,9 @@ void uiMainMenuSelected(
switch(index) {
case UI_MAIN_MENU_INDEX_START_GAME:
UI_MAIN_MENU.suppressClosedSceneChange = true;
uiMenuClose(&UI_MAIN_MENU.menu);
errorCatch(errorPrint(saveLoadAllSlots()));
uiSelectSaveOpen(
UI_SELECT_SAVE_TYPE_LOAD, uiMainMenuSelectSaveResult, NULL
);
cutsceneSystemStartCutscene(&CUTSCENE_MAIN_MENU_START_GAME);
break;
case UI_MAIN_MENU_INDEX_OPTIONS:
@@ -96,7 +151,8 @@ errorret_t uiMainMenuInit(void) {
));
MENU_BEGIN(
&UI_MAIN_MENU.menu, UI_MAIN_MENU.items, uiMainMenuSelected, NULL, NULL
&UI_MAIN_MENU.menu, UI_MAIN_MENU.items, uiMainMenuSelected,
uiMainMenuClosed, NULL
);
MENU_BUTTON(UI_MAIN_MENU.startGameLabel);
MENU_BUTTON(UI_MAIN_MENU.optionsLabel);
+6
View File
@@ -20,6 +20,12 @@ typedef struct {
char_t startGameLabel[UI_MAIN_MENU_LABEL_MAX];
char_t optionsLabel[UI_MAIN_MENU_LABEL_MAX];
char_t quitLabel[UI_MAIN_MENU_LABEL_MAX];
// Set right before a uiMenuClose() call that hands off to something
// else (e.g. starting the start-game cutscene) rather than backing
// all the way out, so the menu's closed handler knows to skip
// returning to the initial scene for that one close.
bool_t suppressClosedSceneChange;
} uimainmenu_t;
extern uimainmenu_t UI_MAIN_MENU;