Confirm before deleting or overwriting save
This commit is contained in:
parent
4e4a5e6ed0
commit
4f1a322c46
223
src/menu/confirmation_dialog.c
Normal file
223
src/menu/confirmation_dialog.c
Normal file
|
@ -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);
|
||||||
|
}
|
35
src/menu/confirmation_dialog.h
Normal file
35
src/menu/confirmation_dialog.h
Normal file
|
@ -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
|
|
@ -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 loadGameUpdate(struct LoadGameMenu* loadGame) {
|
||||||
|
enum InputCapture capture = savefileListUpdate(loadGame->savefileList);
|
||||||
|
if (capture != InputCapturePass) {
|
||||||
|
return capture;
|
||||||
|
}
|
||||||
|
|
||||||
if (loadGame->savefileList->numberOfSaves) {
|
if (loadGame->savefileList->numberOfSaves) {
|
||||||
if (controllerGetButtonDown(0, A_BUTTON)) {
|
if (controllerGetButtonDown(0, A_BUTTON)) {
|
||||||
Checkpoint* save = stackMalloc(MAX_CHECKPOINT_SIZE);
|
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);
|
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
|
||||||
} else if (controllerGetButtonDown(0, Z_TRIG)) {
|
} else if (controllerGetButtonDown(0, Z_TRIG)) {
|
||||||
short selectedSaveIndex = loadGame->savefileList->selectedSave;
|
savefileListConfirmDeletion(
|
||||||
struct SavefileInfo* selectedSave = &loadGame->savefileList->savefileInfo[selectedSaveIndex];
|
loadGame->savefileList,
|
||||||
|
(ConfirmationDialogCallback)&loadGameConfirmDeletionClosed,
|
||||||
savefileDeleteGame(selectedSave->slotIndex);
|
loadGame
|
||||||
loadGamePopulate(loadGame);
|
);
|
||||||
|
|
||||||
if (selectedSaveIndex >= loadGame->savefileList->numberOfSaves) {
|
|
||||||
--selectedSaveIndex;
|
|
||||||
}
|
|
||||||
loadGame->savefileList->selectedSave = selectedSaveIndex;
|
|
||||||
|
|
||||||
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
|
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) {
|
void loadGameRender(struct LoadGameMenu* loadGame, struct RenderState* renderState, struct GraphicsTask* task) {
|
||||||
|
|
|
@ -16,10 +16,7 @@ struct PrerenderedText* menuBuildPrerenderedText(struct Font* font, char* messag
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx* menuBuildBorder(int x, int y, int width, int height) {
|
Gfx* menuRerenderBorder(int x, int y, int width, int height, Gfx* dl) {
|
||||||
Gfx* result = malloc(sizeof(Gfx) * 7 * 3 + 1);
|
|
||||||
Gfx* dl = result;
|
|
||||||
|
|
||||||
gSPTextureRectangle(
|
gSPTextureRectangle(
|
||||||
dl++,
|
dl++,
|
||||||
x << 2, y << 2,
|
x << 2, y << 2,
|
||||||
|
@ -83,6 +80,13 @@ Gfx* menuBuildBorder(int x, int y, int width, int height) {
|
||||||
0x400, 0x400
|
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++);
|
gSPEndDisplayList(dl++);
|
||||||
|
|
||||||
return result;
|
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);
|
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) {
|
void menuSetRenderColor(struct RenderState* renderState, int isSelected, struct Coloru8* selected, struct Coloru8* defaultColor) {
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
gDPSetEnvColor(renderState->dl++, selected->r, selected->g, selected->b, selected->a);
|
gDPSetEnvColor(renderState->dl++, selected->r, selected->g, selected->b, selected->a);
|
||||||
|
|
|
@ -47,6 +47,7 @@ extern struct Coloru8 gBorderDark;
|
||||||
|
|
||||||
struct PrerenderedText* menuBuildPrerenderedText(struct Font* font, char* message, int x, int y, int maxWidth);
|
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* menuBuildBorder(int x, int y, int width, int height);
|
||||||
Gfx* menuBuildHorizontalLine(int x, int y, int width);
|
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);
|
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);
|
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 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 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);
|
struct MenuCheckbox menuBuildCheckbox(struct Font* font, char* message, int x, int y);
|
||||||
Gfx* menuCheckboxRender(struct MenuCheckbox* checkbox, Gfx* dl);
|
Gfx* menuCheckboxRender(struct MenuCheckbox* checkbox, Gfx* dl);
|
||||||
|
|
|
@ -66,25 +66,30 @@ void saveGamePopulate(struct SaveGameMenu* saveGame, int includeNew) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum InputCapture saveGameUpdate(struct SaveGameMenu* saveGame) {
|
static void saveGameSaveInSelectedSlot(struct SaveGameMenu* saveGame) {
|
||||||
if (saveGame->savefileList->numberOfSaves) {
|
|
||||||
if (controllerGetButtonDown(0, A_BUTTON)) {
|
|
||||||
Checkpoint* save = stackMalloc(MAX_CHECKPOINT_SIZE);
|
Checkpoint* save = stackMalloc(MAX_CHECKPOINT_SIZE);
|
||||||
if (checkpointSaveInto(&gScene, save)) {
|
if (checkpointSaveInto(&gScene, save)) {
|
||||||
savefileSaveGame(save, gScreenGrabBuffer, getChamberDisplayNumberFromLevelIndex(gCurrentLevelIndex, gScene.player.body.currentRoom), gCurrentTestSubject, savefileGetSlot(saveGame->savefileList));
|
savefileSaveGame(
|
||||||
|
save,
|
||||||
|
gScreenGrabBuffer,
|
||||||
|
getChamberDisplayNumberFromLevelIndex(gCurrentLevelIndex, gScene.player.body.currentRoom),
|
||||||
|
gCurrentTestSubject,
|
||||||
|
savefileGetSlot(saveGame->savefileList)
|
||||||
|
);
|
||||||
saveGamePopulate(saveGame, 1);
|
saveGamePopulate(saveGame, 1);
|
||||||
|
|
||||||
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
|
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
|
||||||
} else {
|
} else {
|
||||||
soundPlayerPlay(SOUNDS_WPN_DENYSELECT, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
|
soundPlayerPlay(SOUNDS_WPN_DENYSELECT, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
|
||||||
}
|
}
|
||||||
stackMallocFree(save);
|
stackMallocFree(save);
|
||||||
} else if (controllerGetButtonDown(0, Z_TRIG)) {
|
}
|
||||||
|
|
||||||
|
static void saveGameConfirmDeletionClosed(struct SaveGameMenu* saveGame, int isConfirmed) {
|
||||||
|
if (isConfirmed) {
|
||||||
short selectedSaveIndex = saveGame->savefileList->selectedSave;
|
short selectedSaveIndex = saveGame->savefileList->selectedSave;
|
||||||
struct SavefileInfo* selectedSave = &saveGame->savefileList->savefileInfo[selectedSaveIndex];
|
struct SavefileInfo* selectedSave = &saveGame->savefileList->savefileInfo[selectedSaveIndex];
|
||||||
|
|
||||||
if (selectedSave->isFree) {
|
|
||||||
soundPlayerPlay(SOUNDS_WPN_DENYSELECT, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
|
|
||||||
} else {
|
|
||||||
savefileDeleteGame(selectedSave->slotIndex);
|
savefileDeleteGame(selectedSave->slotIndex);
|
||||||
saveGamePopulate(saveGame, 1);
|
saveGamePopulate(saveGame, 1);
|
||||||
|
|
||||||
|
@ -92,13 +97,52 @@ enum InputCapture saveGameUpdate(struct SaveGameMenu* saveGame) {
|
||||||
--selectedSaveIndex;
|
--selectedSaveIndex;
|
||||||
}
|
}
|
||||||
saveGame->savefileList->selectedSave = 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)) {
|
||||||
|
short selectedSaveIndex = saveGame->savefileList->selectedSave;
|
||||||
|
struct SavefileInfo* selectedSave = &saveGame->savefileList->savefileInfo[selectedSaveIndex];
|
||||||
|
|
||||||
|
if (selectedSave->isFree) {
|
||||||
|
saveGameSaveInSelectedSlot(saveGame);
|
||||||
|
} else {
|
||||||
|
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);
|
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) {
|
void saveGameRender(struct SaveGameMenu* saveGame, struct RenderState* renderState, struct GraphicsTask* task) {
|
||||||
|
|
|
@ -136,6 +136,8 @@ void savefileListMenuInit(struct SavefileListMenu* savefileList) {
|
||||||
LOAD_GAME_TOP + i * ROW_HEIGHT + FILE_OFFSET_Y
|
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) {
|
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) {
|
enum InputCapture savefileListUpdate(struct SavefileListMenu* savefileList) {
|
||||||
|
if (savefileList->confirmationDialog.isShown) {
|
||||||
|
return confirmationDialogUpdate(&savefileList->confirmationDialog);
|
||||||
|
}
|
||||||
|
|
||||||
if (controllerGetButtonDown(0, B_BUTTON)) {
|
if (controllerGetButtonDown(0, B_BUTTON)) {
|
||||||
return InputCaptureExit;
|
return InputCaptureExit;
|
||||||
}
|
}
|
||||||
|
@ -364,6 +370,10 @@ void savefileListRender(struct SavefileListMenu* savefileList, struct RenderStat
|
||||||
|
|
||||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[IMAGE_COPY_INDEX]);
|
gSPDisplayList(renderState->dl++, ui_material_revert_list[IMAGE_COPY_INDEX]);
|
||||||
|
|
||||||
|
if (savefileList->confirmationDialog.isShown) {
|
||||||
|
confirmationDialogRender(&savefileList->confirmationDialog, renderState);
|
||||||
|
}
|
||||||
|
|
||||||
gDPPipeSync(renderState->dl++);
|
gDPPipeSync(renderState->dl++);
|
||||||
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD, SCREEN_HT);
|
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WD, SCREEN_HT);
|
||||||
}
|
}
|
||||||
|
@ -371,3 +381,29 @@ void savefileListRender(struct SavefileListMenu* savefileList, struct RenderStat
|
||||||
int savefileGetSlot(struct SavefileListMenu* savefileList) {
|
int savefileGetSlot(struct SavefileListMenu* savefileList) {
|
||||||
return savefileList->savefileInfo[savefileList->selectedSave].slotIndex;
|
return savefileList->savefileInfo[savefileList->selectedSave].slotIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../graphics/graphics.h"
|
#include "../graphics/graphics.h"
|
||||||
#include "../savefile/savefile.h"
|
#include "../savefile/savefile.h"
|
||||||
#include "./new_game_menu.h"
|
#include "./new_game_menu.h"
|
||||||
|
#include "./confirmation_dialog.h"
|
||||||
|
|
||||||
struct SavefileInfo {
|
struct SavefileInfo {
|
||||||
short slotIndex;
|
short slotIndex;
|
||||||
|
@ -31,6 +32,7 @@ struct SavefileListMenu {
|
||||||
struct PrerenderedText* savefileListTitleText;
|
struct PrerenderedText* savefileListTitleText;
|
||||||
struct PrerenderedText* deleteText;
|
struct PrerenderedText* deleteText;
|
||||||
struct PrerenderedText* confirmText;
|
struct PrerenderedText* confirmText;
|
||||||
|
struct ConfirmationDialog confirmationDialog;
|
||||||
struct SavefileInfo savefileInfo[MAX_SAVE_SLOTS];
|
struct SavefileInfo savefileInfo[MAX_SAVE_SLOTS];
|
||||||
struct SavefileListSlot slots[MAX_VISIBLE_SLOTS];
|
struct SavefileListSlot slots[MAX_VISIBLE_SLOTS];
|
||||||
short numberOfSaves;
|
short numberOfSaves;
|
||||||
|
@ -44,5 +46,7 @@ void savefileUseList(struct SavefileListMenu* savefileList, char* title, char* c
|
||||||
enum InputCapture savefileListUpdate(struct SavefileListMenu* savefileList);
|
enum InputCapture savefileListUpdate(struct SavefileListMenu* savefileList);
|
||||||
void savefileListRender(struct SavefileListMenu* savefileList, struct RenderState* renderState, struct GraphicsTask* task);
|
void savefileListRender(struct SavefileListMenu* savefileList, struct RenderState* renderState, struct GraphicsTask* task);
|
||||||
int savefileGetSlot(struct SavefileListMenu* savefileList);
|
int savefileGetSlot(struct SavefileListMenu* savefileList);
|
||||||
|
void savefileListConfirmDeletion(struct SavefileListMenu* savefileList, ConfirmationDialogCallback callback, void* callbackData);
|
||||||
|
void savefileListConfirmOverwrite(struct SavefileListMenu* savefileList, ConfirmationDialogCallback callback, void* callbackData);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -9,8 +9,15 @@ hl_gameui_whitelist = {
|
||||||
"GAMEUI_ASPECTWIDE",
|
"GAMEUI_ASPECTWIDE",
|
||||||
"GAMEUI_AUDIO",
|
"GAMEUI_AUDIO",
|
||||||
"GAMEUI_AUTOSAVE",
|
"GAMEUI_AUTOSAVE",
|
||||||
|
"GAMEUI_CANCEL",
|
||||||
"GAMEUI_CAPTIONING",
|
"GAMEUI_CAPTIONING",
|
||||||
"GAMEUI_CHAPTER",
|
"GAMEUI_CHAPTER",
|
||||||
|
"GAMEUI_CONFIRMDELETESAVEGAME_INFO",
|
||||||
|
"GAMEUI_CONFIRMDELETESAVEGAME_OK",
|
||||||
|
"GAMEUI_CONFIRMDELETESAVEGAME_TITLE",
|
||||||
|
"GAMEUI_CONFIRMOVERWRITESAVEGAME_INFO",
|
||||||
|
"GAMEUI_CONFIRMOVERWRITESAVEGAME_OK",
|
||||||
|
"GAMEUI_CONFIRMOVERWRITESAVEGAME_TITLE",
|
||||||
"GAMEUI_DELETE",
|
"GAMEUI_DELETE",
|
||||||
"GAMEUI_GAMEMENU_QUIT",
|
"GAMEUI_GAMEMENU_QUIT",
|
||||||
"GAMEUI_GAMEMENU_RESUMEGAME",
|
"GAMEUI_GAMEMENU_RESUMEGAME",
|
||||||
|
@ -142,7 +149,7 @@ def get_caption_keys_values_language(lines):
|
||||||
keyval[1] = keyval[1].replace("[$WIN32]", "")
|
keyval[1] = keyval[1].replace("[$WIN32]", "")
|
||||||
|
|
||||||
key = keyval[0].replace('"', "").replace(".", "_").replace("-", "_").replace('\\', "_").replace('#', "").upper()
|
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'\<clr.+\>','',val)
|
val = re.sub(r'\<clr.+\>','',val)
|
||||||
val = re.sub(r'\<norepeat.+\>','',val)
|
val = re.sub(r'\<norepeat.+\>','',val)
|
||||||
val = val.replace("<sfx>", "")
|
val = val.replace("<sfx>", "")
|
||||||
|
|
Loading…
Reference in a new issue