diff --git a/src/dusk/ui/screen/mainmenu/uimainmenu.c b/src/dusk/ui/screen/mainmenu/uimainmenu.c index 7b75ccb7..4508b2cd 100644 --- a/src/dusk/ui/screen/mainmenu/uimainmenu.c +++ b/src/dusk/ui/screen/mainmenu/uimainmenu.c @@ -15,9 +15,11 @@ #include "locale/localemanager.h" #include "asset/loader/locale/assetlocaleloader.h" #include "ui/dialog/save/uiselectsave.h" +#include "ui/overlay/uifatalerror.h" #include "rpg/cutscene/cutscenesystem.h" #include "scene/scene.h" #include "asset/asset.h" +#include "save/save.h" #define UI_MAIN_MENU_INDEX_START_GAME 0 #define UI_MAIN_MENU_INDEX_OPTIONS 1 @@ -47,7 +49,15 @@ void uiMainMenuSelectSaveResult(const uint8_t slotIndex, void *user) { return; } - // TODO: load/start the game using the chosen save slot. + SAVE.slotCurrent = slotIndex; + saveSlotInit(&SAVE.slot); + errorret_t result = saveLoadSlot(); + if(errorIsNotOk(result)) { + errorCatch(errorPrint(result)); + uiFatalErrorOpen(result.state->message); + return; + } + sceneSet(SCENE_TYPE_OVERWORLD); } diff --git a/src/dusk/ui/transition/uitransition.c b/src/dusk/ui/transition/uitransition.c index 4ed0026e..32f5dce9 100644 --- a/src/dusk/ui/transition/uitransition.c +++ b/src/dusk/ui/transition/uitransition.c @@ -54,7 +54,15 @@ errorret_t uiTransitionUpdate(void) { ); if(UI_TRANSITION.data.t >= 1.0f && UI_TRANSITION.finished) { - UI_TRANSITION.finished(UI_TRANSITION.user); + // Saved and cleared before firing so a callback that immediately + // starts another transition isn't clobbered by this function's own + // cleanup running after it - same reentrancy hazard as uiFocusPop, + // see src/dusk/ui/focus/uifocus.c. Without this, finished would also + // just keep re-firing every frame forever once t reaches 1.0. + uitransitioncallback_t finished = UI_TRANSITION.finished; + void *user = UI_TRANSITION.user; + UI_TRANSITION.finished = NULL; + finished(user); } errorOk();