From 4f1a322c46c6b9b3083f8937355cde8f8bb7842f Mon Sep 17 00:00:00 2001 From: Matt Penny Date: Sun, 24 Dec 2023 13:17:57 -0500 Subject: [PATCH] Confirm before deleting or overwriting save --- src/menu/confirmation_dialog.c | 223 +++++++++++++++++++++++ src/menu/confirmation_dialog.h | 35 ++++ src/menu/load_game.c | 38 ++-- src/menu/menu.c | 24 ++- src/menu/menu.h | 2 + src/menu/save_game_menu.c | 82 +++++++-- src/menu/savefile_list.c | 38 +++- src/menu/savefile_list.h | 4 + tools/level_scripts/subtitle_generate.py | 9 +- 9 files changed, 418 insertions(+), 37 deletions(-) create mode 100644 src/menu/confirmation_dialog.c create mode 100644 src/menu/confirmation_dialog.h diff --git a/src/menu/confirmation_dialog.c b/src/menu/confirmation_dialog.c new file mode 100644 index 0000000..8892432 --- /dev/null +++ b/src/menu/confirmation_dialog.c @@ -0,0 +1,223 @@ +#include "./confirmation_dialog.h" + +#include "../font/dejavusans.h" +#include "../controls/controller.h" +#include "../audio/soundplayer.h" +#include "./translations.h" + +#include "../build/assets/materials/ui.h" +#include "../build/src/audio/clips.h" +#include "../build/src/audio/subtitles.h" + +#define DIALOG_LEFT 40 +#define DIALOG_WIDTH (SCREEN_WD - (DIALOG_LEFT * 2)) +#define DIALOG_PADDING 8 + +#define TEXT_MARGIN 4 + +#define CONTENT_LEFT (DIALOG_LEFT + DIALOG_PADDING) +#define CONTENT_WIDTH (DIALOG_WIDTH - (DIALOG_PADDING * 2)) +#define CONTENT_CENTER_X (CONTENT_LEFT + (CONTENT_WIDTH / 2)) +#define CONTENT_MARGIN 20 + +#define BUTTON_HEIGHT 16 +#define BUTTON_MARGIN 8 + +static struct Coloru8 gDialogColor = {164, 164, 164, 255}; + +void confirmationDialogInit(struct ConfirmationDialog* confirmationDialog) { + confirmationDialog->menuOutline = menuBuildBorder(0, 0, 0, 0); + confirmationDialog->titleText = NULL; + confirmationDialog->messageText = NULL; + confirmationDialog->selectedButton = NULL; + confirmationDialog->closeCallback = NULL; + confirmationDialog->callbackData = NULL; + confirmationDialog->isShown = 0; + + confirmationDialog->confirmButton = menuBuildButton( + &gDejaVuSansFont, "", + 0, + 0, + BUTTON_HEIGHT, + 0 + ); + confirmationDialog->cancelButton = menuBuildButton( + &gDejaVuSansFont, "", + 0, + 0, + BUTTON_HEIGHT, + 0 + ); +} + +static void confirmationDialogLayout(struct ConfirmationDialog* confirmationDialog) { + int dialogHeight = CONTENT_MARGIN + confirmationDialog->messageText->height + BUTTON_MARGIN + BUTTON_HEIGHT + DIALOG_PADDING; + int dialogTop = (SCREEN_HT - dialogHeight) / 2; + + menuRerenderBorder( + DIALOG_LEFT, + dialogTop, + DIALOG_WIDTH, + dialogHeight, + confirmationDialog->menuOutline + ); + prerenderedTextRelocate( + confirmationDialog->titleText, + CONTENT_LEFT, + dialogTop + TEXT_MARGIN + ); + prerenderedTextRelocate( + confirmationDialog->messageText, + CONTENT_LEFT, + dialogTop + CONTENT_MARGIN + ); + + int buttonsWidth = confirmationDialog->confirmButton.w + confirmationDialog->cancelButton.w + BUTTON_MARGIN; + int buttonsX = CONTENT_CENTER_X - (buttonsWidth / 2); + int buttonsY = confirmationDialog->messageText->y + confirmationDialog->messageText->height + BUTTON_MARGIN; + + menuRelocateButton( + &confirmationDialog->confirmButton, + buttonsX, + buttonsY, + 0 + ); + menuRelocateButton( + &confirmationDialog->cancelButton, + buttonsX + confirmationDialog->confirmButton.w + BUTTON_MARGIN, + buttonsY, + 0 + ); +} + +void confirmationDialogShow(struct ConfirmationDialog* confirmationDialog, struct ConfirmationDialogParams* params) { + if (confirmationDialog->titleText) { + prerenderedTextFree(confirmationDialog->titleText); + } + if (confirmationDialog->messageText) { + prerenderedTextFree(confirmationDialog->messageText); + } + + confirmationDialog->titleText = menuBuildPrerenderedText( + &gDejaVuSansFont, params->title, + 0, + 0, + SCREEN_WD + ); + confirmationDialog->messageText = menuBuildPrerenderedText( + &gDejaVuSansFont, params->message, + 0, + 0, + CONTENT_WIDTH + ); + + menuRebuildButtonText( + &confirmationDialog->confirmButton, + &gDejaVuSansFont, + params->confirmLabel, + 0 + ); + menuRebuildButtonText( + &confirmationDialog->cancelButton, + &gDejaVuSansFont, + params->cancelLabel, + 0 + ); + + confirmationDialogLayout(confirmationDialog); + + confirmationDialog->selectedButton = &confirmationDialog->cancelButton; + confirmationDialog->closeCallback = params->closeCallback; + confirmationDialog->callbackData = params->callbackData; + confirmationDialog->isShown = 1; +} + +static void confirmationDialogClose(struct ConfirmationDialog* confirmationDialog, int isConfirmed) { + ConfirmationDialogCallback callback = confirmationDialog->closeCallback; + if (callback) { + callback(confirmationDialog->callbackData, isConfirmed); + } + + confirmationDialog->isShown = 0; +} + +enum InputCapture confirmationDialogUpdate(struct ConfirmationDialog* confirmationDialog) { + if (controllerGetButtonDown(0, B_BUTTON)) { + confirmationDialogClose(confirmationDialog, 0); + } else if (controllerGetButtonDown(0, A_BUTTON)) { + if (confirmationDialog->selectedButton == &confirmationDialog->confirmButton) { + confirmationDialogClose(confirmationDialog, 1); + } else { + confirmationDialogClose(confirmationDialog, 0); + } + + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + } + + int controllerDir = controllerGetDirectionDown(0); + if (controllerDir & (ControllerDirectionLeft | ControllerDirectionRight)) { + if (confirmationDialog->selectedButton == &confirmationDialog->confirmButton) { + confirmationDialog->selectedButton = &confirmationDialog->cancelButton; + } else { + confirmationDialog->selectedButton = &confirmationDialog->confirmButton; + } + soundPlayerPlay(SOUNDS_BUTTONROLLOVER, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + } + + return InputCaptureGrab; +} + +static void renderButtonText(struct ConfirmationDialog* confirmationDialog, struct MenuButton* button, struct PrerenderedTextBatch* batch) { + struct Coloru8* color = confirmationDialog->selectedButton == button ? &gColorBlack : &gColorWhite; + prerenderedBatchAdd(batch, button->text, color); +} + +void confirmationDialogRender(struct ConfirmationDialog* confirmationDialog, struct RenderState* renderState) { + gSPDisplayList(renderState->dl++, ui_material_list[DEFAULT_UI_INDEX]); + gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD, SCREEN_HT); + + gSPDisplayList(renderState->dl++, ui_material_list[SOLID_TRANSPARENT_OVERLAY_INDEX]); + gDPFillRectangle(renderState->dl++, 0, 0, SCREEN_WD, SCREEN_HT); + gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_TRANSPARENT_OVERLAY_INDEX]); + + gSPDisplayList(renderState->dl++, ui_material_list[ROUNDED_CORNERS_INDEX]); + gDPPipeSync(renderState->dl++); + gDPSetEnvColor(renderState->dl++, gDialogColor.r, gDialogColor.g, gDialogColor.b, gDialogColor.a); + gSPDisplayList(renderState->dl++, confirmationDialog->menuOutline); + gSPDisplayList(renderState->dl++, ui_material_revert_list[ROUNDED_CORNERS_INDEX]); + + gSPDisplayList(renderState->dl++, ui_material_list[SOLID_ENV_INDEX]); + + if (confirmationDialog->selectedButton != NULL) { + gDPPipeSync(renderState->dl++); + gDPSetEnvColor(renderState->dl++, gSelectionOrange.r, gSelectionOrange.g, gSelectionOrange.b, gSelectionOrange.a); + gDPFillRectangle( + renderState->dl++, + confirmationDialog->selectedButton->x, + confirmationDialog->selectedButton->y, + confirmationDialog->selectedButton->x + confirmationDialog->selectedButton->w, + confirmationDialog->selectedButton->y + confirmationDialog->selectedButton->h + ); + } + + gSPDisplayList(renderState->dl++, confirmationDialog->confirmButton.outline); + gSPDisplayList(renderState->dl++, confirmationDialog->cancelButton.outline); + + gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_ENV_INDEX]); + + struct PrerenderedTextBatch* batch = prerenderedBatchStart(); + + if (confirmationDialog->titleText) { + prerenderedBatchAdd(batch, confirmationDialog->titleText, NULL); + } + if (confirmationDialog->messageText) { + prerenderedBatchAdd(batch, confirmationDialog->messageText, NULL); + } + + renderButtonText(confirmationDialog, &confirmationDialog->confirmButton, batch); + renderButtonText(confirmationDialog, &confirmationDialog->cancelButton, batch); + + renderState->dl = prerenderedBatchFinish(batch, gDejaVuSansImages, renderState->dl); + + gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD, SCREEN_HT); +} diff --git a/src/menu/confirmation_dialog.h b/src/menu/confirmation_dialog.h new file mode 100644 index 0000000..02ef167 --- /dev/null +++ b/src/menu/confirmation_dialog.h @@ -0,0 +1,35 @@ +#ifndef __MENU_CONFIRMATION_DIALOG_H__ +#define __MENU_CONFIRMATION_DIALOG_H__ + +#include "./menu.h" +#include "../graphics/graphics.h" + +typedef void (*ConfirmationDialogCallback)(void* data, int isConfirmed); + +struct ConfirmationDialogParams { + char* title; + char* message; + char* confirmLabel; + char* cancelLabel; + ConfirmationDialogCallback closeCallback; + void* callbackData; +}; + +struct ConfirmationDialog { + Gfx* menuOutline; + struct PrerenderedText* titleText; + struct PrerenderedText* messageText; + struct MenuButton confirmButton; + struct MenuButton cancelButton; + struct MenuButton* selectedButton; + ConfirmationDialogCallback closeCallback; + void* callbackData; + int isShown; +}; + +void confirmationDialogInit(struct ConfirmationDialog* confirmationDialog); +void confirmationDialogShow(struct ConfirmationDialog* confirmationDialog, struct ConfirmationDialogParams* params); +enum InputCapture confirmationDialogUpdate(struct ConfirmationDialog* confirmationDialog); +void confirmationDialogRender(struct ConfirmationDialog* confirmationDialog, struct RenderState* renderState); + +#endif diff --git a/src/menu/load_game.c b/src/menu/load_game.c index 85b56c4..2f0b997 100644 --- a/src/menu/load_game.c +++ b/src/menu/load_game.c @@ -37,7 +37,27 @@ void loadGamePopulate(struct LoadGameMenu* loadGame) { ); } +static void loadGameConfirmDeletionClosed(struct LoadGameMenu* loadGame, int isConfirmed) { + if (isConfirmed) { + short selectedSaveIndex = loadGame->savefileList->selectedSave; + struct SavefileInfo* selectedSave = &loadGame->savefileList->savefileInfo[selectedSaveIndex]; + + savefileDeleteGame(selectedSave->slotIndex); + loadGamePopulate(loadGame); + + if (selectedSaveIndex >= loadGame->savefileList->numberOfSaves) { + --selectedSaveIndex; + } + loadGame->savefileList->selectedSave = selectedSaveIndex; + } +} + enum InputCapture loadGameUpdate(struct LoadGameMenu* loadGame) { + enum InputCapture capture = savefileListUpdate(loadGame->savefileList); + if (capture != InputCapturePass) { + return capture; + } + if (loadGame->savefileList->numberOfSaves) { if (controllerGetButtonDown(0, A_BUTTON)) { Checkpoint* save = stackMalloc(MAX_CHECKPOINT_SIZE); @@ -53,22 +73,16 @@ enum InputCapture loadGameUpdate(struct LoadGameMenu* loadGame) { soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } else if (controllerGetButtonDown(0, Z_TRIG)) { - short selectedSaveIndex = loadGame->savefileList->selectedSave; - struct SavefileInfo* selectedSave = &loadGame->savefileList->savefileInfo[selectedSaveIndex]; - - savefileDeleteGame(selectedSave->slotIndex); - loadGamePopulate(loadGame); - - if (selectedSaveIndex >= loadGame->savefileList->numberOfSaves) { - --selectedSaveIndex; - } - loadGame->savefileList->selectedSave = selectedSaveIndex; - + savefileListConfirmDeletion( + loadGame->savefileList, + (ConfirmationDialogCallback)&loadGameConfirmDeletionClosed, + loadGame + ); soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } } - return savefileListUpdate(loadGame->savefileList); + return InputCapturePass; } void loadGameRender(struct LoadGameMenu* loadGame, struct RenderState* renderState, struct GraphicsTask* task) { diff --git a/src/menu/menu.c b/src/menu/menu.c index ae7842e..6f83f4b 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -16,10 +16,7 @@ struct PrerenderedText* menuBuildPrerenderedText(struct Font* font, char* messag return result; } -Gfx* menuBuildBorder(int x, int y, int width, int height) { - Gfx* result = malloc(sizeof(Gfx) * 7 * 3 + 1); - Gfx* dl = result; - +Gfx* menuRerenderBorder(int x, int y, int width, int height, Gfx* dl) { gSPTextureRectangle( dl++, x << 2, y << 2, @@ -83,6 +80,13 @@ Gfx* menuBuildBorder(int x, int y, int width, int height) { 0x400, 0x400 ); + return dl; +} + +Gfx* menuBuildBorder(int x, int y, int width, int height) { + Gfx* result = malloc(sizeof(Gfx) * 7 * 3 + 1); + Gfx* dl = menuRerenderBorder(x, y, width, height, result); + gSPEndDisplayList(dl++); return result; @@ -193,6 +197,18 @@ void menuRebuildButtonText(struct MenuButton* button, struct Font* font, char* m menuRenderOutline(button->x, button->y, button->w, button->h, 0, button->outline); } +void menuRelocateButton(struct MenuButton* button, int x, int y, int rightAlign) { + if (rightAlign) { + x -= button->w; + } + + menuRenderOutline(x, y, button->w, button->h, 0, button->outline); + prerenderedTextRelocate(button->text, x + BUTTON_LEFT_PADDING, y + BUTTON_TOP_PADDING); + + button->x = x; + button->y = y; +} + void menuSetRenderColor(struct RenderState* renderState, int isSelected, struct Coloru8* selected, struct Coloru8* defaultColor) { if (isSelected) { gDPSetEnvColor(renderState->dl++, selected->r, selected->g, selected->b, selected->a); diff --git a/src/menu/menu.h b/src/menu/menu.h index 75f0157..b5fb7a5 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -47,6 +47,7 @@ extern struct Coloru8 gBorderDark; struct PrerenderedText* menuBuildPrerenderedText(struct Font* font, char* message, int x, int y, int maxWidth); +Gfx* menuRerenderBorder(int x, int y, int width, int height, Gfx* dl); Gfx* menuBuildBorder(int x, int y, int width, int height); Gfx* menuBuildHorizontalLine(int x, int y, int width); Gfx* menuRerenderSolidBorder(int x, int y, int w, int h, int nx, int ny, int nw, int nh, Gfx* dl); @@ -56,6 +57,7 @@ Gfx* menuBuildOutline(int x, int y, int width, int height, int invert); struct MenuButton menuBuildButton(struct Font* font, char* message, int x, int y, int height, int rightAlign); void menuSetRenderColor(struct RenderState* renderState, int isSelected, struct Coloru8* selected, struct Coloru8* defaultColor); void menuRebuildButtonText(struct MenuButton* button, struct Font* font, char* message, int rightAlign); +void menuRelocateButton(struct MenuButton* button, int x, int y, int rightAlign); struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, int y); Gfx* menuCheckboxRender(struct MenuCheckbox* checkbox, Gfx* dl); diff --git a/src/menu/save_game_menu.c b/src/menu/save_game_menu.c index 1c5684a..c4bb3ee 100644 --- a/src/menu/save_game_menu.c +++ b/src/menu/save_game_menu.c @@ -66,39 +66,83 @@ void saveGamePopulate(struct SaveGameMenu* saveGame, int includeNew) { } } +static void saveGameSaveInSelectedSlot(struct SaveGameMenu* saveGame) { + Checkpoint* save = stackMalloc(MAX_CHECKPOINT_SIZE); + if (checkpointSaveInto(&gScene, save)) { + savefileSaveGame( + save, + gScreenGrabBuffer, + getChamberDisplayNumberFromLevelIndex(gCurrentLevelIndex, gScene.player.body.currentRoom), + gCurrentTestSubject, + savefileGetSlot(saveGame->savefileList) + ); + saveGamePopulate(saveGame, 1); + + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + } else { + soundPlayerPlay(SOUNDS_WPN_DENYSELECT, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + } + stackMallocFree(save); +} + +static void saveGameConfirmDeletionClosed(struct SaveGameMenu* saveGame, int isConfirmed) { + if (isConfirmed) { + short selectedSaveIndex = saveGame->savefileList->selectedSave; + struct SavefileInfo* selectedSave = &saveGame->savefileList->savefileInfo[selectedSaveIndex]; + + savefileDeleteGame(selectedSave->slotIndex); + saveGamePopulate(saveGame, 1); + + if (selectedSaveIndex >= saveGame->savefileList->numberOfSaves) { + --selectedSaveIndex; + } + saveGame->savefileList->selectedSave = selectedSaveIndex; + } +} + +static void saveGameConfirmOverwriteClosed(void* saveGame, int isConfirmed) { + if (isConfirmed) { + saveGameSaveInSelectedSlot(saveGame); + } +} + enum InputCapture saveGameUpdate(struct SaveGameMenu* saveGame) { + enum InputCapture capture = savefileListUpdate(saveGame->savefileList); + if (capture != InputCapturePass) { + return capture; + } + if (saveGame->savefileList->numberOfSaves) { if (controllerGetButtonDown(0, A_BUTTON)) { - Checkpoint* save = stackMalloc(MAX_CHECKPOINT_SIZE); - if (checkpointSaveInto(&gScene, save)) { - savefileSaveGame(save, gScreenGrabBuffer, getChamberDisplayNumberFromLevelIndex(gCurrentLevelIndex, gScene.player.body.currentRoom), gCurrentTestSubject, savefileGetSlot(saveGame->savefileList)); - saveGamePopulate(saveGame, 1); - soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); - } else { - soundPlayerPlay(SOUNDS_WPN_DENYSELECT, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); - } - stackMallocFree(save); - } else if (controllerGetButtonDown(0, Z_TRIG)) { short selectedSaveIndex = saveGame->savefileList->selectedSave; struct SavefileInfo* selectedSave = &saveGame->savefileList->savefileInfo[selectedSaveIndex]; if (selectedSave->isFree) { - soundPlayerPlay(SOUNDS_WPN_DENYSELECT, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + saveGameSaveInSelectedSlot(saveGame); } else { - savefileDeleteGame(selectedSave->slotIndex); - saveGamePopulate(saveGame, 1); - - if (selectedSaveIndex >= saveGame->savefileList->numberOfSaves) { - --selectedSaveIndex; - } - saveGame->savefileList->selectedSave = selectedSaveIndex; + savefileListConfirmOverwrite( + saveGame->savefileList, + (ConfirmationDialogCallback)&saveGameConfirmOverwriteClosed, + saveGame + ); + soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); + } + } else if (controllerGetButtonDown(0, Z_TRIG)) { + short selectedSaveIndex = saveGame->savefileList->selectedSave; + struct SavefileInfo* selectedSave = &saveGame->savefileList->savefileInfo[selectedSaveIndex]; + if (!selectedSave->isFree) { + savefileListConfirmDeletion( + saveGame->savefileList, + (ConfirmationDialogCallback)&saveGameConfirmDeletionClosed, + saveGame + ); soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll); } } } - return savefileListUpdate(saveGame->savefileList); + return InputCapturePass; } void saveGameRender(struct SaveGameMenu* saveGame, struct RenderState* renderState, struct GraphicsTask* task) { diff --git a/src/menu/savefile_list.c b/src/menu/savefile_list.c index 94ec45a..f4b996c 100644 --- a/src/menu/savefile_list.c +++ b/src/menu/savefile_list.c @@ -136,6 +136,8 @@ void savefileListMenuInit(struct SavefileListMenu* savefileList) { LOAD_GAME_TOP + i * ROW_HEIGHT + FILE_OFFSET_Y ); } + + confirmationDialogInit(&savefileList->confirmationDialog); } void savefileUseList(struct SavefileListMenu* savefileList, char* title, char* confirmLabel, struct SavefileInfo* savefileInfo, int slotCount) { @@ -186,6 +188,10 @@ void savefileUseList(struct SavefileListMenu* savefileList, char* title, char* c } enum InputCapture savefileListUpdate(struct SavefileListMenu* savefileList) { + if (savefileList->confirmationDialog.isShown) { + return confirmationDialogUpdate(&savefileList->confirmationDialog); + } + if (controllerGetButtonDown(0, B_BUTTON)) { return InputCaptureExit; } @@ -364,10 +370,40 @@ void savefileListRender(struct SavefileListMenu* savefileList, struct RenderStat gSPDisplayList(renderState->dl++, ui_material_revert_list[IMAGE_COPY_INDEX]); + if (savefileList->confirmationDialog.isShown) { + confirmationDialogRender(&savefileList->confirmationDialog, renderState); + } + gDPPipeSync(renderState->dl++); gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD, SCREEN_HT); } int savefileGetSlot(struct SavefileListMenu* savefileList) { return savefileList->savefileInfo[savefileList->selectedSave].slotIndex; -} \ No newline at end of file +} + +void savefileListConfirmDeletion(struct SavefileListMenu* savefileList, ConfirmationDialogCallback callback, void* callbackData) { + struct ConfirmationDialogParams dialogParams = { + translationsGet(GAMEUI_CONFIRMDELETESAVEGAME_TITLE), + translationsGet(GAMEUI_CONFIRMDELETESAVEGAME_INFO), + translationsGet(GAMEUI_CONFIRMDELETESAVEGAME_OK), + translationsGet(GAMEUI_CANCEL), + callback, + callbackData + }; + + confirmationDialogShow(&savefileList->confirmationDialog, &dialogParams); +} + +void savefileListConfirmOverwrite(struct SavefileListMenu* savefileList, ConfirmationDialogCallback callback, void* callbackData) { + struct ConfirmationDialogParams dialogParams = { + translationsGet(GAMEUI_CONFIRMOVERWRITESAVEGAME_TITLE), + translationsGet(GAMEUI_CONFIRMOVERWRITESAVEGAME_INFO), + translationsGet(GAMEUI_CONFIRMOVERWRITESAVEGAME_OK), + translationsGet(GAMEUI_CANCEL), + callback, + callbackData + }; + + confirmationDialogShow(&savefileList->confirmationDialog, &dialogParams); +} diff --git a/src/menu/savefile_list.h b/src/menu/savefile_list.h index 46140b6..917f567 100644 --- a/src/menu/savefile_list.h +++ b/src/menu/savefile_list.h @@ -6,6 +6,7 @@ #include "../graphics/graphics.h" #include "../savefile/savefile.h" #include "./new_game_menu.h" +#include "./confirmation_dialog.h" struct SavefileInfo { short slotIndex; @@ -31,6 +32,7 @@ struct SavefileListMenu { struct PrerenderedText* savefileListTitleText; struct PrerenderedText* deleteText; struct PrerenderedText* confirmText; + struct ConfirmationDialog confirmationDialog; struct SavefileInfo savefileInfo[MAX_SAVE_SLOTS]; struct SavefileListSlot slots[MAX_VISIBLE_SLOTS]; short numberOfSaves; @@ -44,5 +46,7 @@ void savefileUseList(struct SavefileListMenu* savefileList, char* title, char* c enum InputCapture savefileListUpdate(struct SavefileListMenu* savefileList); void savefileListRender(struct SavefileListMenu* savefileList, struct RenderState* renderState, struct GraphicsTask* task); int savefileGetSlot(struct SavefileListMenu* savefileList); +void savefileListConfirmDeletion(struct SavefileListMenu* savefileList, ConfirmationDialogCallback callback, void* callbackData); +void savefileListConfirmOverwrite(struct SavefileListMenu* savefileList, ConfirmationDialogCallback callback, void* callbackData); #endif \ No newline at end of file diff --git a/tools/level_scripts/subtitle_generate.py b/tools/level_scripts/subtitle_generate.py index f7d43cc..18e928b 100644 --- a/tools/level_scripts/subtitle_generate.py +++ b/tools/level_scripts/subtitle_generate.py @@ -9,8 +9,15 @@ hl_gameui_whitelist = { "GAMEUI_ASPECTWIDE", "GAMEUI_AUDIO", "GAMEUI_AUTOSAVE", + "GAMEUI_CANCEL", "GAMEUI_CAPTIONING", "GAMEUI_CHAPTER", + "GAMEUI_CONFIRMDELETESAVEGAME_INFO", + "GAMEUI_CONFIRMDELETESAVEGAME_OK", + "GAMEUI_CONFIRMDELETESAVEGAME_TITLE", + "GAMEUI_CONFIRMOVERWRITESAVEGAME_INFO", + "GAMEUI_CONFIRMOVERWRITESAVEGAME_OK", + "GAMEUI_CONFIRMOVERWRITESAVEGAME_TITLE", "GAMEUI_DELETE", "GAMEUI_GAMEMENU_QUIT", "GAMEUI_GAMEMENU_RESUMEGAME", @@ -142,7 +149,7 @@ def get_caption_keys_values_language(lines): keyval[1] = keyval[1].replace("[$WIN32]", "") key = keyval[0].replace('"', "").replace(".", "_").replace("-", "_").replace('\\', "_").replace('#', "").upper() - val = keyval[1].replace('"', "").replace("\n", "").replace("\\", "").strip() + val = keyval[1].replace('"', "").replace("\n", "").replace("\\n", " ").replace("\\", "").strip() val = re.sub(r'\','',val) val = re.sub(r'\','',val) val = val.replace("", "")