Add menu icons and text for save/load/delete

This commit is contained in:
Matt Penny 2023-12-21 12:19:53 -05:00
parent 5036b40505
commit 4e4a5e6ed0
7 changed files with 136 additions and 20 deletions

View file

@ -159,7 +159,7 @@ int controlsMeasureIcons(enum ControllerAction action) {
return result;
}
Gfx* controlsRenderIcons(Gfx* dl, enum ControllerAction action, int x, int y) {
Gfx* controlsRenderActionIcons(Gfx* dl, enum ControllerAction action, int x, int y) {
struct ControllerSourceWithController sources[MAX_SOURCES_PER_ACTION];
int sourceCount = controllerSourcesForAction(action, sources, MAX_SOURCES_PER_ACTION);
@ -192,12 +192,31 @@ Gfx* controlsRenderIcons(Gfx* dl, enum ControllerAction action, int x, int y) {
return dl;
}
void controlsRenderButtonIcon(enum ControllerActionSource source, int x, int y, struct RenderState* renderState) {
struct ControllerIcon icon;
source = controllerSourceMapAction(source);
if (!IS_VALID_SOURCE(source)) {
return;
}
icon = gControllerButtonIcons[(int)gControllerActionToButtonIcon[(int)source]];
gSPTextureRectangle(
renderState->dl++,
x << 2, y << 2,
(x + icon.w) << 2, (y + icon.h) << 2,
G_TX_RENDERTILE,
icon.x << 5, icon.y << 5,
0x400, 0x400
);
}
void controlsLayoutRow(struct ControlsMenuRow* row, struct ControlActionDataRow* data, int x, int y) {
struct PrerenderedText* copy = prerenderedTextCopy(row->actionText);
menuFreePrerenderedDeferred(row->actionText);
row->actionText = copy;
prerenderedTextRelocate(row->actionText, x + ROW_PADDING, y);
Gfx* dl = controlsRenderIcons(row->sourceIcons, data->action, CONTROLS_X + CONTROLS_WIDTH - ROW_PADDING * 2, y);
Gfx* dl = controlsRenderActionIcons(row->sourceIcons, data->action, CONTROLS_X + CONTROLS_WIDTH - ROW_PADDING * 2, y);
gSPEndDisplayList(dl++);
row->y = y;
}
@ -521,7 +540,7 @@ void controlsRenderPrompt(enum ControllerAction action, char* message, float opa
gSPDisplayList(renderState->dl++, ui_material_list[BUTTON_ICONS_INDEX]);
gDPSetEnvColor(renderState->dl++, 232, 206, 80, opacityAsInt);
renderState->dl = controlsRenderIcons(renderState->dl, action, textPositionX - CONTROL_PROMPT_PADDING, textPositionY);
renderState->dl = controlsRenderActionIcons(renderState->dl, action, textPositionX - CONTROL_PROMPT_PADDING, textPositionY);
gSPDisplayList(renderState->dl++, ui_material_revert_list[BUTTON_ICONS_INDEX]);
stackMallocFree(fontRender);

View file

@ -46,5 +46,6 @@ void controlsMenuRender(struct ControlsMenu* controlsMenu, struct RenderState* r
void controlsRenderPrompt(enum ControllerAction action, char* message, float opacity, struct RenderState* renderState);
void controlsRenderSubtitle(char* message, float textOpacity, float backgroundOpacity, struct RenderState* renderState, enum SubtitleType subtitleType);
void controlsRenderButtonIcon(enum ControllerActionSource source, int x, int y, struct RenderState* renderState);
#endif

View file

@ -25,9 +25,16 @@ void loadGamePopulate(struct LoadGameMenu* loadGame) {
savefileInfo[i].testchamberDisplayNumber = saveSlots[i].testChamber;
savefileInfo[i].savefileName = saveSlots[i].saveSlot == 0 ? translationsGet(GAMEUI_AUTOSAVE) : NULL;
savefileInfo[i].screenshot = (u16*)SCREEN_SHOT_SRAM(saveSlots[i].saveSlot);
savefileInfo[i].isFree = 0;
}
savefileUseList(loadGame->savefileList, translationsGet(GAMEUI_LOADGAME), savefileInfo, numberOfSaves);
savefileUseList(
loadGame->savefileList,
translationsGet(GAMEUI_LOADGAME),
translationsGet(GAMEUI_LOAD),
savefileInfo,
numberOfSaves
);
}
enum InputCapture loadGameUpdate(struct LoadGameMenu* loadGame) {

View file

@ -28,6 +28,7 @@ void saveGamePopulate(struct SaveGameMenu* saveGame, int includeNew) {
savefileInfo[i].testchamberDisplayNumber = saveSlots[i].testChamber;
savefileInfo[i].savefileName = NULL;
savefileInfo[i].screenshot = (u16*)SCREEN_SHOT_SRAM(saveSlots[i].saveSlot);
savefileInfo[i].isFree = 0;
if (suggestedSlot == saveSlots[i].saveSlot) {
startSelection = i;
@ -41,6 +42,7 @@ void saveGamePopulate(struct SaveGameMenu* saveGame, int includeNew) {
savefileInfo[numberOfSaves].savefileName = translationsGet(GAMEUI_NEWSAVEGAME);
savefileInfo[numberOfSaves].testchamberDisplayNumber = getChamberDisplayNumberFromLevelIndex(gCurrentLevelIndex, gScene.player.body.currentRoom);
savefileInfo[numberOfSaves].screenshot = gScreenGrabBuffer;
savefileInfo[numberOfSaves].isFree = 1;
if (suggestedSlot == 0) {
startSelection = numberOfSaves;
@ -49,7 +51,13 @@ void saveGamePopulate(struct SaveGameMenu* saveGame, int includeNew) {
++numberOfSaves;
}
savefileUseList(saveGame->savefileList, translationsGet(GAMEUI_SAVEGAME), savefileInfo, numberOfSaves);
savefileUseList(
saveGame->savefileList,
translationsGet(GAMEUI_SAVEGAME),
translationsGet(GAMEUI_SAVE),
savefileInfo,
numberOfSaves
);
if (startSelection == -1) {
saveGame->savefileList->selectedSave = numberOfSaves - 1;
@ -71,19 +79,19 @@ enum InputCapture saveGameUpdate(struct SaveGameMenu* saveGame) {
}
stackMallocFree(save);
} else if (controllerGetButtonDown(0, Z_TRIG)) {
int selectedSlotIndex = savefileGetSlot(saveGame->savefileList);
if (selectedSlotIndex == savefileFirstFreeSlot()) {
// Disallow deleting "new save" entry
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);
} else {
short selectedListIndex = saveGame->savefileList->selectedSave;
savefileDeleteGame(selectedSlotIndex);
savefileDeleteGame(selectedSave->slotIndex);
saveGamePopulate(saveGame, 1);
if (selectedListIndex >= saveGame->savefileList->numberOfSaves) {
--selectedListIndex;
if (selectedSaveIndex >= saveGame->savefileList->numberOfSaves) {
--selectedSaveIndex;
}
saveGame->savefileList->selectedSave = selectedListIndex;
saveGame->savefileList->selectedSave = selectedSaveIndex;
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL, SoundTypeAll);
}

View file

@ -6,6 +6,8 @@
#include "../graphics/image.h"
#include "../audio/soundplayer.h"
#include "./text_manipulation.h"
#include "./controls.h"
#include "./translations.h"
#include <string.h>
#include "../build/assets/materials/ui.h"
@ -72,15 +74,19 @@ void savefileListSlotInit(struct SavefileListSlot* savefileListSlot, int x, int
}
#define LOAD_GAME_LEFT 40
#define LOAD_GAME_TOP 20
#define LOAD_GAME_TOP 15
#define FILE_OFFSET_X 16
#define FILE_OFFSET_Y 28
#define CONTROLS_HEIGHT 10
#define CONTROL_TEXT_PADDING 12
#define CONTROL_TEXT_MARGIN 2
#define CONTENT_X (LOAD_GAME_LEFT + 8)
#define CONTENT_Y (LOAD_GAME_TOP + FILE_OFFSET_Y - 8)
#define CONTENT_WIDTH (SCREEN_WD - CONTENT_X * 2)
#define CONTENT_HEIGHT (SCREEN_HT - CONTENT_Y - LOAD_GAME_TOP - 8)
#define CONTENT_HEIGHT (SCREEN_HT - CONTENT_Y - LOAD_GAME_TOP - CONTROLS_HEIGHT - 8)
#define SCROLLED_ROW_Y(rowIndex, scrollOffset) (LOAD_GAME_TOP + (rowIndex) * ROW_HEIGHT + FILE_OFFSET_Y + (scrollOffset))
@ -117,6 +123,8 @@ void savefileListMenuSetScroll(struct SavefileListMenu* savefileList, int amount
void savefileListMenuInit(struct SavefileListMenu* savefileList) {
savefileList->menuOutline = menuBuildBorder(LOAD_GAME_LEFT, LOAD_GAME_TOP, SCREEN_WD - LOAD_GAME_LEFT * 2, SCREEN_HT - LOAD_GAME_TOP * 2);
savefileList->savefileListTitleText = NULL;
savefileList->deleteText = NULL;
savefileList->confirmText = NULL;
savefileList->numberOfSaves = 3;
savefileList->scrollOffset = 0;
@ -130,12 +138,42 @@ void savefileListMenuInit(struct SavefileListMenu* savefileList) {
}
}
void savefileUseList(struct SavefileListMenu* savefileList, char* title, struct SavefileInfo* savefileInfo, int slotCount) {
void savefileUseList(struct SavefileListMenu* savefileList, char* title, char* confirmLabel, struct SavefileInfo* savefileInfo, int slotCount) {
if (savefileList->savefileListTitleText) {
prerenderedTextFree(savefileList->savefileListTitleText);
}
if (savefileList->deleteText) {
prerenderedTextFree(savefileList->deleteText);
}
if (savefileList->confirmText) {
prerenderedTextFree(savefileList->confirmText);
}
savefileList->savefileListTitleText = menuBuildPrerenderedText(&gDejaVuSansFont, title, 48, LOAD_GAME_TOP + 4, SCREEN_WD);
savefileList->savefileListTitleText = menuBuildPrerenderedText(
&gDejaVuSansFont,
title,
CONTENT_X,
LOAD_GAME_TOP + 4,
SCREEN_WD
);
savefileList->deleteText = menuBuildPrerenderedText(&gDejaVuSansFont,
translationsGet(GAMEUI_DELETE),
CONTENT_X + CONTROL_TEXT_PADDING,
CONTENT_Y + CONTENT_HEIGHT + CONTROL_TEXT_MARGIN,
120
);
savefileList->confirmText = menuBuildPrerenderedText(
&gDejaVuSansFont,
confirmLabel,
0,
CONTENT_Y + CONTENT_HEIGHT + CONTROL_TEXT_MARGIN,
120
);
prerenderedTextRelocate(
savefileList->confirmText,
CONTENT_X + CONTENT_WIDTH - savefileList->confirmText->width - 1,
savefileList->confirmText->y
);
for (int i = 0; i < slotCount; ++i) {
savefileList->savefileInfo[i] = savefileInfo[i];
@ -185,6 +223,40 @@ enum InputCapture savefileListUpdate(struct SavefileListMenu* savefileList) {
return InputCapturePass;
}
static void savefileListRenderControls(struct SavefileListMenu* savefileList, struct RenderState* renderState) {
if (savefileList->numberOfSaves == 0) {
return;
}
struct SavefileInfo* selectedSave = &savefileList->savefileInfo[savefileList->selectedSave];
struct PrerenderedTextBatch* batch = prerenderedBatchStart();
gSPDisplayList(renderState->dl++, ui_material_list[BUTTON_ICONS_INDEX]);
if (savefileList->confirmText) {
controlsRenderButtonIcon(
ControllerActionSourceAButton,
savefileList->confirmText->x - CONTROL_TEXT_PADDING - 2,
savefileList->confirmText->y,
renderState
);
prerenderedBatchAdd(batch, savefileList->confirmText, NULL);
}
if (savefileList->deleteText && !selectedSave->isFree) {
controlsRenderButtonIcon(
ControllerActionSourceZTrig,
savefileList->deleteText->x - CONTROL_TEXT_PADDING - 1,
savefileList->deleteText->y,
renderState
);
prerenderedBatchAdd(batch, savefileList->deleteText, NULL);
}
gSPDisplayList(renderState->dl++, ui_material_revert_list[BUTTON_ICONS_INDEX]);
renderState->dl = prerenderedBatchFinish(batch, gDejaVuSansImages, renderState->dl);
}
void savefileListRender(struct SavefileListMenu* savefileList, struct RenderState* renderState, struct GraphicsTask* task) {
gSPDisplayList(renderState->dl++, ui_material_list[DEFAULT_UI_INDEX]);
@ -229,6 +301,8 @@ void savefileListRender(struct SavefileListMenu* savefileList, struct RenderStat
renderState->dl = prerenderedBatchFinish(batch, gDejaVuSansImages, renderState->dl);
savefileListRenderControls(savefileList, renderState);
gDPPipeSync(renderState->dl++);
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, CONTENT_X, CONTENT_Y, CONTENT_X + CONTENT_WIDTH, CONTENT_Y + CONTENT_HEIGHT);
@ -252,6 +326,7 @@ void savefileListRender(struct SavefileListMenu* savefileList, struct RenderStat
renderState->dl = prerenderedBatchFinish(batch, gDejaVuSansImages, renderState->dl);
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_0_INDEX]);
gSPDisplayList(renderState->dl++, ui_material_list[IMAGE_COPY_INDEX]);

View file

@ -12,6 +12,7 @@ struct SavefileInfo {
short testchamberDisplayNumber;
char* savefileName;
u16* screenshot;
int isFree;
};
struct SavefileListSlot {
@ -28,6 +29,8 @@ struct SavefileListSlot {
struct SavefileListMenu {
Gfx* menuOutline;
struct PrerenderedText* savefileListTitleText;
struct PrerenderedText* deleteText;
struct PrerenderedText* confirmText;
struct SavefileInfo savefileInfo[MAX_SAVE_SLOTS];
struct SavefileListSlot slots[MAX_VISIBLE_SLOTS];
short numberOfSaves;
@ -37,7 +40,7 @@ struct SavefileListMenu {
};
void savefileListMenuInit(struct SavefileListMenu* savefileList);
void savefileUseList(struct SavefileListMenu* savefileList, char* title, struct SavefileInfo* savefileInfo, int slotCount);
void savefileUseList(struct SavefileListMenu* savefileList, char* title, char* confirmLabel, struct SavefileInfo* savefileInfo, int slotCount);
enum InputCapture savefileListUpdate(struct SavefileListMenu* savefileList);
void savefileListRender(struct SavefileListMenu* savefileList, struct RenderState* renderState, struct GraphicsTask* task);
int savefileGetSlot(struct SavefileListMenu* savefileList);

View file

@ -11,9 +11,11 @@ hl_gameui_whitelist = {
"GAMEUI_AUTOSAVE",
"GAMEUI_CAPTIONING",
"GAMEUI_CHAPTER",
"GAMEUI_DELETE",
"GAMEUI_GAMEMENU_QUIT",
"GAMEUI_GAMEMENU_RESUMEGAME",
"GAMEUI_JOYSTICKINVERTED",
"GAMEUI_LOAD",
"GAMEUI_LOADGAME",
"GAMEUI_MUSICVOLUME",
"GAMEUI_NEWGAME",
@ -23,6 +25,7 @@ hl_gameui_whitelist = {
"GAMEUI_PORTAL",
"GAMEUI_PORTALDEPTHLABEL",
"GAMEUI_PORTALFUNNEL",
"GAMEUI_SAVE",
"GAMEUI_SAVEGAME",
"GAMEUI_SOUNDEFFECTVOLUME",
"GAMEUI_SUBTITLES",