Skip to content

Commit

Permalink
requester: fix memory corruption and refactor
Browse files Browse the repository at this point in the history
Fixes issues with incorrectly sized items_flags, standardizes
requestor functions, and switches to snprintf during savegame
scanning.
  • Loading branch information
walkawayy committed Jun 27, 2024
1 parent e7cae39 commit 058f84b
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 108 deletions.
45 changes: 24 additions & 21 deletions src/game/option/option_passport.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,55 +48,58 @@ static PASSPORT_STATUS m_PassportStatus = {

static bool m_IsTextInit = false;
static TEXTSTRING *m_Text[TEXT_NUMBER_OF] = { 0 };
static char m_NewGameStrings[MAX_GAME_MODES][MAX_GAME_MODE_LENGTH] = { 0 };
static char **m_SelectLevelStrings = NULL;
static char *m_SelectLevelBuffer = NULL;

static REQUEST_INFO m_NewGameRequester = {
.items = MAX_GAME_MODES,
.items_used = 0,
.max_items = MAX_GAME_MODES,
.requested = 0,
.vis_lines = MAX_GAME_MODES,
.line_offset = 0,
.line_old_offset = 0,
.pix_width = 162,
.line_height = TEXT_HEIGHT + 7,
.flags = 0,
.item_flags = NULL,
.x = 0,
.y = 0,
.flags = 0,
.heading_text = NULL,
.item_texts = &m_NewGameStrings[0][0],
.item_texts = NULL,
.item_text_len = MAX_GAME_MODE_LENGTH,
0,
};

static REQUEST_INFO m_SelectLevelRequester = {
.items = 1,
.items_used = 0,
.max_items = 2,
.requested = 0,
.vis_lines = -1,
.line_offset = 0,
.line_old_offset = 0,
.pix_width = 292,
.line_height = TEXT_HEIGHT + 7,
.flags = 0,
.item_flags = NULL,
.x = 0,
.y = -32,
.flags = 0,
.heading_text = NULL,
.item_texts = NULL,
.item_text_len = MAX_LEVEL_NAME_LENGTH,
0,
};

REQUEST_INFO g_SavegameRequester = {
.items = 1,
.items_used = 0,
.max_items = 1,
.requested = 0,
.vis_lines = -1,
.line_offset = 0,
.line_old_offset = 0,
.pix_width = 292,
.line_height = TEXT_HEIGHT + 7,
.flags = 0,
.item_flags = NULL,
.x = 0,
.y = -32,
.flags = 0,
.heading_text = NULL,
.item_texts = NULL,
.item_text_len = MAX_LEVEL_NAME_LENGTH,
Expand All @@ -122,16 +125,16 @@ static void Option_PassportFlipLeft(INVENTORY_ITEM *inv_item);

void Option_PassportInit(void)
{
g_SavegameRequester.item_texts = Memory_Alloc(
g_Config.maximum_save_slots * g_SavegameRequester.item_text_len);
m_SelectLevelRequester.item_texts = Memory_Alloc(
(g_GameFlow.level_count + 1) * m_SelectLevelRequester.item_text_len);
Requester_Init(&g_SavegameRequester, g_Config.maximum_save_slots);
Requester_Init(&m_SelectLevelRequester, g_GameFlow.level_count + 1);
Requester_Init(&m_NewGameRequester, MAX_GAME_MODES);
}

void Option_PassportShutdown(void)
{
Memory_FreePointer(&g_SavegameRequester.item_texts);
Memory_FreePointer(&m_SelectLevelRequester.item_texts);
Requester_Shutdown(&g_SavegameRequester);
Requester_Shutdown(&m_SelectLevelRequester);
Requester_Shutdown(&m_NewGameRequester);
}

static void Option_PassportInitText(void)
Expand Down Expand Up @@ -272,7 +275,7 @@ static void Option_PassportDeterminePages(void)
static void Option_PassportInitSaveRequester(int16_t page_num)
{
REQUEST_INFO *req = &g_SavegameRequester;
Requester_Init(req);
Requester_ClearTextstrings(req);
Requester_SetHeading(
req,
page_num == PAGE_1 ? GS(PASSPORT_LOAD_GAME) : GS(PASSPORT_SAVE_GAME));
Expand Down Expand Up @@ -303,7 +306,7 @@ static void Option_PassportInitSelectLevelRequester(void)
{
REQUEST_INFO *req = &m_SelectLevelRequester;
req->flags |= RIF_BLOCKABLE;
Requester_Init(req);
Requester_ClearTextstrings(req);
Requester_SetHeading(req, GS(PASSPORT_SELECT_LEVEL));

if (Screen_GetResHeightDownscaled(RSR_TEXT) <= 240) {
Expand Down Expand Up @@ -331,7 +334,7 @@ static void Option_PassportInitSelectLevelRequester(void)
static void Option_PassportInitNewGameRequester(void)
{
REQUEST_INFO *req = &m_NewGameRequester;
Requester_Init(req);
Requester_ClearTextstrings(req);
Requester_SetHeading(req, GS(PASSPORT_SELECT_MODE));
Requester_AddItem(req, GS(PASSPORT_MODE_NEW_GAME), 0);
Requester_AddItem(req, GS(PASSPORT_MODE_NEW_GAME_PLUS), 0);
Expand Down Expand Up @@ -416,7 +419,7 @@ static void Option_PassportLoadGame(void)
if (g_InputDB.menu_right) {
g_GameInfo.current_save_slot = g_SavegameRequester.requested;
Text_Hide(m_Text[TEXT_LEVEL_ARROW_RIGHT], true);
Requester_Remove(&g_SavegameRequester);
Requester_ClearTextstrings(&g_SavegameRequester);
Option_PassportInitSelectLevelRequester();
m_PassportStatus.mode = PASSPORT_MODE_SELECT_LEVEL;
g_Input = (INPUT_STATE) { 0 };
Expand Down Expand Up @@ -456,7 +459,7 @@ static void Option_PassportSelectLevel(void)
{
if (g_InputDB.menu_left) {
Text_Hide(m_Text[TEXT_LEVEL_ARROW_LEFT], true);
Requester_Remove(&m_SelectLevelRequester);
Requester_ClearTextstrings(&m_SelectLevelRequester);
Option_PassportInitSaveRequester(m_PassportStatus.page);
m_PassportStatus.mode = PASSPORT_MODE_LOAD_GAME;
g_Input = (INPUT_STATE) { 0 };
Expand Down
31 changes: 21 additions & 10 deletions src/game/phase/phase_pause.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
#include "game/sound.h"
#include "game/text.h"
#include "global/types.h"
#include "global/vars.h"

#include <libtrx/memory.h>

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#define PAUSE_MAX_ITEMS 5
#define PAUSE_MAX_TEXT_LENGTH 50
#define PAUSE_NUM_ITEM_TEXTS 2

typedef enum STATE {
STATE_DEFAULT,
Expand All @@ -27,23 +31,26 @@ typedef enum STATE {
} STATE;

static STATE m_PauseState = STATE_DEFAULT;
static bool m_IsTextReady = false;

static TEXTSTRING *m_PausedText = NULL;

static char m_PauseStrings[PAUSE_MAX_ITEMS][PAUSE_MAX_TEXT_LENGTH] = { 0 };
static REQUEST_INFO m_PauseRequester = {
.items = 0,
.items_used = 0,
.max_items = PAUSE_NUM_ITEM_TEXTS,
.requested = 0,
.vis_lines = 0,
.line_offset = 0,
.line_old_offset = 0,
.pix_width = 160,
.line_height = TEXT_HEIGHT + 7,
.flags = 0,
.item_flags = NULL,
.x = 0,
.y = 0,
.flags = 0,
.heading_text = NULL,
.item_texts = &m_PauseStrings[0][0],
.item_texts = NULL,
.item_text_len = PAUSE_MAX_TEXT_LENGTH,
0,
};
Expand All @@ -53,7 +60,6 @@ static void Phase_Pause_UpdateText(void);
static int32_t Phase_Pause_DisplayRequester(
const char *header, const char *option1, const char *option2,
int16_t requested);

static void Phase_Pause_Start(void *arg);
static void Phase_Pause_End(void);
static GAMEFLOW_OPTION Phase_Pause_Control(int32_t nframes);
Expand All @@ -78,23 +84,27 @@ static int32_t Phase_Pause_DisplayRequester(
const char *header, const char *option1, const char *option2,
int16_t requested)
{
static bool is_pause_text_ready = false;
if (!is_pause_text_ready) {
Requester_Init(&m_PauseRequester);
if (!m_IsTextReady) {
Requester_ClearTextstrings(&m_PauseRequester);
Requester_SetSize(&m_PauseRequester, 2, -48);
m_PauseRequester.requested = requested;
Requester_SetHeading(&m_PauseRequester, header);
Requester_AddItem(&m_PauseRequester, option1, 0);
Requester_AddItem(&m_PauseRequester, option2, 0);
m_IsTextReady = true;
g_InputDB = (INPUT_STATE) { 0 };
g_Input = (INPUT_STATE) { 0 };
}

is_pause_text_ready = true;
// Don't allow back because it breaks the requestor items.
if (g_InputDB.menu_back) {
g_InputDB = (INPUT_STATE) { 0 };
g_Input = (INPUT_STATE) { 0 };
}

int select = Requester_Display(&m_PauseRequester);
if (select > 0) {
is_pause_text_ready = false;
m_IsTextReady = false;
} else {
g_InputDB = (INPUT_STATE) { 0 };
g_Input = (INPUT_STATE) { 0 };
Expand All @@ -114,15 +124,16 @@ static void Phase_Pause_Start(void *arg)

Output_FadeToSemiBlack(true);

Requester_Init(&m_PauseRequester, PAUSE_NUM_ITEM_TEXTS);
m_PauseState = STATE_DEFAULT;
}

static void Phase_Pause_End(void)
{
Output_FadeToTransparent(true);

Requester_Remove(&m_PauseRequester);
Phase_Pause_RemoveText();
Requester_Shutdown(&m_PauseRequester);
}

static GAMEFLOW_OPTION Phase_Pause_Control(int32_t nframes)
Expand Down
Loading

0 comments on commit 058f84b

Please sign in to comment.