diff --git a/src/dusk/scene/mainmenu/scenemainmenu.c b/src/dusk/scene/mainmenu/scenemainmenu.c index f1f8299f..2acb030d 100644 --- a/src/dusk/scene/mainmenu/scenemainmenu.c +++ b/src/dusk/scene/mainmenu/scenemainmenu.c @@ -7,6 +7,73 @@ #include "scenemainmenu.h" #include "ui/screen/mainmenu/uimainmenu.h" +#include "ui/dialog/save/uiselectsave.h" +#include "rpg/cutscene/cutscene.h" +#include "rpg/cutscene/cutscenesystem.h" +#include "scene/scene.h" + +void sceneMainMenuOpenSelectSave(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(0.2f), + 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(sceneMainMenuOpenSelectSave) +); + +void sceneMainMenuSelectSaveResult(const uint8_t slotIndex, void *user) { + if(slotIndex == UI_SELECT_SAVE_RESULT_NONE) { + uiMainMenuOpen(); + return; + } + + // TODO: load/start the game using the chosen save slot. + sceneSet(SCENE_TYPE_OVERWORLD); +} + +void sceneMainMenuOpenSelectSave(void *userData) { + uiSelectSaveOpen( + UI_SELECT_SAVE_TYPE_LOAD, sceneMainMenuSelectSaveResult, NULL + ); +} + +void sceneMainMenuStartGame(void) { + cutsceneSystemStartCutscene(&CUTSCENE_MAIN_MENU_START_GAME); +} errorret_t sceneMainMenuInit(scenedata_t *sceneData) { uiMainMenuOpen(); diff --git a/src/dusk/scene/mainmenu/scenemainmenu.h b/src/dusk/scene/mainmenu/scenemainmenu.h index 0d824425..fa29bfdb 100644 --- a/src/dusk/scene/mainmenu/scenemainmenu.h +++ b/src/dusk/scene/mainmenu/scenemainmenu.h @@ -8,7 +8,7 @@ #pragma once #include "scene/scenebase.h" -// Empty - the menu itself lives in ui/frame/mainmenu/uimainmenu.c. A byte +// Empty - the menu itself lives in ui/screen/mainmenu/uimainmenu.c. A byte // placeholder keeps the struct non-empty for portability. typedef struct { uint8_t reserved; @@ -22,6 +22,14 @@ typedef struct { */ errorret_t sceneMainMenuInit(scenedata_t *sceneData); +/** + * Starts the "Start Game" flow: runs a cutscene that loads every save + * slot (retrying on error, prompting if no save device is found) and + * opens the load-game picker once it succeeds. Called by + * ui/screen/mainmenu/uimainmenu.c when the player selects Start Game. + */ +void sceneMainMenuStartGame(void); + /** * Updates the main menu scene. Currently a no-op - the menu drives * itself via the global UI element pipeline. diff --git a/src/dusk/ui/screen/mainmenu/uimainmenu.c b/src/dusk/ui/screen/mainmenu/uimainmenu.c index 4a74c033..4dd78f3d 100644 --- a/src/dusk/ui/screen/mainmenu/uimainmenu.c +++ b/src/dusk/ui/screen/mainmenu/uimainmenu.c @@ -16,80 +16,18 @@ #include "locale/localemanager.h" #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 "scene/mainmenu/scenemainmenu.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(0.2f), - 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) { if(result) ENGINE.running = false; } -void uiMainMenuSelectSaveResult(const uint8_t slotIndex, void *user) { - if(slotIndex == UI_SELECT_SAVE_RESULT_NONE) { - uiMainMenuOpen(); - return; - } - - // TODO: load/start the game using the chosen save slot. - sceneSet(SCENE_TYPE_OVERWORLD); -} - -void uiMainMenuOpenSelectSave(void *userData) { - uiSelectSaveOpen( - UI_SELECT_SAVE_TYPE_LOAD, uiMainMenuSelectSaveResult, NULL - ); -} - void uiMainMenuSelected( const uimenu_t *menu, const uint8_t index, @@ -99,7 +37,7 @@ void uiMainMenuSelected( switch(index) { case UI_MAIN_MENU_INDEX_START_GAME: uiMenuClose(&UI_MAIN_MENU.menu); - cutsceneSystemStartCutscene(&CUTSCENE_MAIN_MENU_START_GAME); + sceneMainMenuStartGame(); break; case UI_MAIN_MENU_INDEX_OPTIONS: