From 85160b1dc12dc5ffd2ca3b18116bcb889486b595 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 1 Dec 2022 21:55:05 +0000 Subject: [PATCH] M_ChallengeGridExtraData Precalculates adjacency rules for challengegrid instead of doing it in the drawer - Simplifies `M_DrawChallenges` a lot, at the expense of a pretty complicated function living in `m_cond.c` - Handles registering entries both not to be drawn (for non-primary components of `majorunlock` unlockables) and for hint highlights (new for this commit) - Hint highlights are a sky blue --- src/k_menu.h | 2 + src/k_menudraw.c | 48 ++++++-------- src/k_menufunc.c | 8 +++ src/m_cond.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++ src/m_cond.h | 4 ++ 5 files changed, 197 insertions(+), 29 deletions(-) diff --git a/src/k_menu.h b/src/k_menu.h index 5a314ab0a..6ee3e6c4d 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -1091,6 +1091,8 @@ extern struct challengesmenu_s { UINT8 currentunlock; tic_t unlockanim; + UINT8 *extradata; + boolean pending; } challengesmenu; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 47705e6bb..784b2eaba 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -4461,7 +4461,7 @@ void M_DrawAddons(void) void M_DrawChallenges(void) { INT32 x = 20, y = 20; - UINT8 i, j, num; + UINT8 i, j, id, num, work; unlockable_t *ref = NULL; { @@ -4487,13 +4487,26 @@ void M_DrawChallenges(void) x = currentMenu->x; y = currentMenu->y; + if (!gamedata->challengegrid) + { + V_DrawString(x, y, V_REDMAP, "No challenges available!?"); + return; + } + for (i = 0; i < gamedata->challengegridwidth; i++) { y = currentMenu->y-16; for (j = 0; j < CHALLENGEGRIDHEIGHT; j++) { y += 16; - num = gamedata->challengegrid[(i * CHALLENGEGRIDHEIGHT) + j]; + id = (i * CHALLENGEGRIDHEIGHT) + j; + + if (challengesmenu.extradata[id] == CHE_DONTDRAW) + { + continue; + } + + num = gamedata->challengegrid[id]; // Empty spots in the grid are always unconnected. if (num >= MAXUNLOCKABLES) @@ -4502,30 +4515,6 @@ void M_DrawChallenges(void) continue; } - // Is the spot above me also me? - if (j > 0 && gamedata->challengegrid[(i * CHALLENGEGRIDHEIGHT) + (j - 1)] == num) - { - continue; - } - - // Is the spot to the left of me also me? - if (i > 0) - { - // Standard - if (gamedata->challengegrid[((i - 1) * CHALLENGEGRIDHEIGHT) + j] == num) - { - continue; - } - } - else if (gamedata->challengegridwidth > 2) - { - // Conditional modulo - if (gamedata->challengegrid[((gamedata->challengegridwidth - 1) * CHALLENGEGRIDHEIGHT) + j] == num) - { - continue; - } - } - // Okay, this is what we want to draw. ref = &unlockables[num]; @@ -4533,9 +4522,10 @@ void M_DrawChallenges(void) if ((gamedata->unlocked[num] == false) || (num == challengesmenu.currentunlock && challengesmenu.unlockanim < UNLOCKTIME/2)) { - num = (ref->majorunlock) ? 2 : 1; - V_DrawFill(x, y, 16*num, 16*num, - ((i & num) != (j & num) ? 12 : 14) + (num-1)*4); // funny checkerboard pattern + work = (ref->majorunlock) ? 2 : 1; + V_DrawFill(x, y, 16*work, 16*work, + ((challengesmenu.extradata[id] == CHE_HINT) ? 130 : 12) + + ((i & work) != (j & work) ? 0 : 2) + (work-1)); // funny checkerboard pattern continue; } diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 89bd748f2..abba32891 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -6837,6 +6837,8 @@ void M_ChallengesTick(void) challengesmenu.pending = false; G_SaveGameData(); } + Z_Free(challengesmenu.extradata); + challengesmenu.extradata = M_ChallengeGridExtraData(); } else if (challengesmenu.unlockanim >= UNLOCKTIME) { @@ -6865,6 +6867,8 @@ boolean M_ChallengesInputs(INT32 ch) gamedata->challengegrid = NULL; gamedata->challengegridwidth = 0; M_PopulateChallengeGrid(); + Z_Free(challengesmenu.extradata); + challengesmenu.extradata = M_ChallengeGridExtraData(); challengesmenu.unlockanim = 0; return true; } @@ -6882,6 +6886,10 @@ boolean M_ChallengesInputs(INT32 ch) { M_GoBack(0); M_SetMenuDelay(pid); + + Z_Free(challengesmenu.extradata); + challengesmenu.extradata = NULL; + return true; } diff --git a/src/m_cond.c b/src/m_cond.c index 02e86b018..edad6b4c5 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -233,6 +233,170 @@ quickcheckagain: } } +UINT8 *M_ChallengeGridExtraData(void) +{ + UINT8 i, j, num, id, tempid, work; + UINT8 *extradata; + boolean idchange; + + if (!gamedata->challengegrid) + { + return NULL; + } + + extradata = Z_Malloc( + (gamedata->challengegridwidth * CHALLENGEGRIDHEIGHT * sizeof(UINT8)), + PU_STATIC, NULL); + + if (!extradata) + { + I_Error("M_ChallengeGridExtraData: was not able to allocate extradata"); + } + + //CONS_Printf(" --- \n"); + + for (i = 0; i < gamedata->challengegridwidth; i++) + { + for (j = 0; j < CHALLENGEGRIDHEIGHT; j++) + { + id = (i * CHALLENGEGRIDHEIGHT) + j; + num = gamedata->challengegrid[id]; + idchange = false; + + extradata[id] = CHE_NONE; + + // Empty spots in the grid are always unconnected. + if (num >= MAXUNLOCKABLES) + { + continue; + } + + // Check the spot above. + if (j > 0) + { + tempid = (i * CHALLENGEGRIDHEIGHT) + (j - 1); + work = gamedata->challengegrid[tempid]; + if (work == num) + { + extradata[id] = CHE_DONTDRAW; + + // Get the id to write extra hint data to. + // This check is safe because extradata's order of population + if (extradata[tempid] == CHE_DONTDRAW) + { + //CONS_Printf(" %d - %d above %d is invalid, check to left\n", num, tempid, id); + if (i > 0) + { + tempid -= CHALLENGEGRIDHEIGHT; + } + else + { + tempid = ((gamedata->challengegridwidth - 1) * CHALLENGEGRIDHEIGHT) + j - 1; + } + } + /*else + CONS_Printf(" %d - %d above %d is valid\n", num, tempid, id);*/ + + id = tempid; + idchange = true; + + if (extradata[id] == CHE_HINT) + { + continue; + } + } + else if (work < MAXUNLOCKABLES && gamedata->unlocked[work]) + { + extradata[id] = CHE_HINT; + } + } + + // Check the spot to the left. + { + if (i > 0) + { + tempid = ((i - 1) * CHALLENGEGRIDHEIGHT) + j; + } + else + { + tempid = ((gamedata->challengegridwidth - 1) * CHALLENGEGRIDHEIGHT) + j; + } + work = gamedata->challengegrid[tempid]; + + if (work == num) + { + if (!idchange && (i > 0 || gamedata->challengegridwidth > 2)) + { + //CONS_Printf(" %d - %d to left of %d is valid\n", work, tempid, id); + // If we haven't already updated our id, it's the one to our left. + if (extradata[id] == CHE_HINT) + { + extradata[tempid] = CHE_HINT; + } + extradata[id] = CHE_DONTDRAW; + id = tempid; + } + /*else + CONS_Printf(" %d - %d to left of %d is invalid\n", work, tempid, id);*/ + } + else if (work < MAXUNLOCKABLES && gamedata->unlocked[work]) + { + extradata[id] = CHE_HINT; + continue; + } + } + + // Since we're not modifying id past this point, the conditions become much simpler. + if (extradata[id] == CHE_HINT) + { + continue; + } + + // Check the spot below. + if (j < CHALLENGEGRIDHEIGHT-1) + { + tempid = (i * CHALLENGEGRIDHEIGHT) + (j + 1); + work = gamedata->challengegrid[tempid]; + + if (work == num) + { + ; + } + else if (work < MAXUNLOCKABLES && gamedata->unlocked[work]) + { + extradata[id] = CHE_HINT; + continue; + } + } + + // Check the spot to the right. + { + if (i < (gamedata->challengegridwidth - 1)) + { + tempid = ((i + 1) * CHALLENGEGRIDHEIGHT) + j; + } + else + { + tempid = j; + } + work = gamedata->challengegrid[tempid]; + + if (work == num) + { + ; + } + else if (work < MAXUNLOCKABLES && gamedata->unlocked[work]) + { + extradata[id] = CHE_HINT; + continue; + } + } + } + } + + return extradata; +} + void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2) { condition_t *cond; diff --git a/src/m_cond.h b/src/m_cond.h index 54f266859..1447e2206 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -175,6 +175,10 @@ extern UINT32 unlocktriggers; void M_NewGameDataStruct(void); void M_PopulateChallengeGrid(void); +UINT8 *M_ChallengeGridExtraData(void); +#define CHE_NONE 0 +#define CHE_HINT 1 +#define CHE_DONTDRAW 2 // Condition set setup void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2);