From 4522ba3b4dbbbe9d9ad70ae0e36e815baa4dbff1 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 5 Feb 2023 16:13:16 +0000 Subject: [PATCH] stickermedalinfo, UpdateTimeStickerMedals: A centralised struct for Medal info attached to the time sticker. - K_drawKartTimestamp: Significantly less messy, no longer dependent on static variables, and no longer iterates over M_GetLevelEmblems every rendered frame(!!) - TODO: Still handles playing sound in the drawer - K_PrepareTimeAttack: Initial generation of a struct of emblems/text is handled on the menu - G_UpdateRecords: Updated in-game if you unlock the next medal there This commit was amended to centralise the new material in g_game.c and reduce the number of header additions required. --- src/g_game.c | 90 +++++++++++++++- src/g_game.h | 12 +++ src/k_hud.c | 133 +++++++----------------- src/k_hud.h | 2 +- src/k_menudraw.c | 4 +- src/menus/play-local-race-time-attack.c | 5 + 6 files changed, 144 insertions(+), 102 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 6b46afcd8..709018aed 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -465,11 +465,6 @@ void G_ClearRecords(void) Z_Free(mapheaderinfo[i]->mainrecord); mapheaderinfo[i]->mainrecord = NULL; } - /*if (nightsrecords[i]) - { - Z_Free(nightsrecords[i]); - nightsrecords[i] = NULL; - }*/ } } @@ -495,6 +490,84 @@ tic_t G_GetBestLap(INT16 map) } */ +struct stickermedalinfo stickermedalinfo; + +void G_UpdateTimeStickerMedals(UINT16 map) +{ + emblem_t *emblem = M_GetLevelEmblems(map+1); + boolean gonnadrawtime = false; + + stickermedalinfo.visiblecount = 0; + stickermedalinfo.targettext[0] = '\0'; + stickermedalinfo.emblems[0] = stickermedalinfo.regenemblem = NULL; + stickermedalinfo.timetoreach = UINT32_MAX; + stickermedalinfo.canplaysound = true; + + while (emblem != NULL) + { + UINT8 i = 0; + + switch (emblem->type) + { + case ET_TIME: + { + break; + } + default: + goto bademblem; + } + + if (!gamedata->collected[(emblem-emblemlocations)] && gonnadrawtime) + break; + + // Simpler than having two checks + if (stickermedalinfo.visiblecount == MAXMEDALVISIBLECOUNT) + stickermedalinfo.visiblecount--; + + // Shuffle along, so [0] is the "main focus" + for (i = stickermedalinfo.visiblecount; i > 0; i--) + { + stickermedalinfo.emblems[i] = stickermedalinfo.emblems[i-1]; + } + stickermedalinfo.emblems[0] = emblem; + stickermedalinfo.visiblecount++; + + if (!gamedata->collected[(emblem-emblemlocations)] || Playing()) + gonnadrawtime = true; + +bademblem: + emblem = M_GetLevelEmblems(-1); + } + + if (stickermedalinfo.visiblecount > 0) + { + if (emblem != NULL && emblem != stickermedalinfo.emblems[0]) + { + // Regenerate the entire array if this is unlocked + stickermedalinfo.regenemblem = emblem; + } + emblem = stickermedalinfo.emblems[0]; + + if (gonnadrawtime) + { + stickermedalinfo.timetoreach = emblem->var; + if (emblem->tag > 0) + { + if (emblem->tag > mapheaderinfo[map]->ghostCount + || mapheaderinfo[map]->ghostBrief[emblem->tag-1] == NULL) + goto bademblem; + + stickermedalinfo.timetoreach = mapheaderinfo[map]->ghostBrief[emblem->tag-1]->time; + } + + snprintf(stickermedalinfo.targettext, 9, "%i'%02i\"%02i", + G_TicsToMinutes(stickermedalinfo.timetoreach, false), + G_TicsToSeconds(stickermedalinfo.timetoreach), + G_TicsToCentiseconds(stickermedalinfo.timetoreach)); + } + } +} + // // G_UpdateRecords // @@ -534,7 +607,14 @@ void G_UpdateRecords(void) // Check emblems when level data is updated if ((earnedEmblems = M_CheckLevelEmblems())) + { CONS_Printf(M_GetText("\x82" "Earned %hu medal%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); + if (stickermedalinfo.regenemblem != NULL + && gamedata->collected[(stickermedalinfo.regenemblem-emblemlocations)]) + { + G_UpdateTimeStickerMedals(gamemap-1); + } + } M_UpdateUnlockablesAndExtraEmblems(true); G_SaveGameData(); diff --git a/src/g_game.h b/src/g_game.h index c2f1c5830..1782a6b30 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -201,6 +201,18 @@ void G_UseContinue(void); void G_AfterIntermission(void); void G_EndGame(void); // moved from y_inter.c/h and renamed +#define MAXMEDALVISIBLECOUNT 3 +extern struct stickermedalinfo +{ + UINT8 visiblecount; + boolean canplaysound; + tic_t timetoreach; + emblem_t *emblems[MAXMEDALVISIBLECOUNT]; + emblem_t *regenemblem; + char targettext[9]; +} stickermedalinfo; + +void G_UpdateTimeStickerMedals(UINT16 map); void G_UpdateRecords(void); void G_Ticker(boolean run); diff --git a/src/k_hud.c b/src/k_hud.c index e44d8ddd6..d48730b12 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1466,14 +1466,11 @@ static void K_drawKartItem(void) } } -void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode) +void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, UINT8 mode) { // TIME_X = BASEVIDWIDTH-124; // 196 // TIME_Y = 6; // 6 - static UINT8 prevmode = UINT8_MAX; - static emblem_t *maxemblem = NULL; - tic_t worktime; INT32 jitter = 0; @@ -1513,10 +1510,6 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI } } - if (mode != prevmode) - maxemblem = NULL; - prevmode = mode; - V_DrawScaledPatch(TX, TY, splitflags, ((mode == 2) ? kp_lapstickerwide : kp_timestickerwide)); TX += 33; @@ -1557,105 +1550,57 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI V_DrawKartString(TX+84, TY+3-jitter, splitflags, va("%d", worktime%10)); } - if (emblemmap && (modeattacking || (mode == 1)) && !demo.playback) // emblem time! + // Medal data! + if ((modeattacking || (mode == 1)) + && !demo.playback + && stickermedalinfo.visiblecount > 0) { INT32 workx = TX + 96, worky = TY+18; - SINT8 curemb = 0; - patch_t *emblempic[3] = {NULL, NULL, NULL}; - UINT8 *emblemcol[3] = {NULL, NULL, NULL}; + UINT8 i = stickermedalinfo.visiblecount; - emblem_t *emblem = M_GetLevelEmblems(emblemmap); - - while (emblem) + if (stickermedalinfo.targettext[0] != '\0') { - char targettext[9]; - - emblem_t *nextemblem = M_GetLevelEmblems(-1); - - switch (emblem->type) + if (!mode) { - case ET_TIME: + if (stplyr->realtime > stickermedalinfo.timetoreach) + { + splitflags = (splitflags &~ V_HUDTRANS)|V_HUDTRANSHALF; + if (stickermedalinfo.canplaysound) { - static boolean canplaysound = true; - tic_t timetoreach = emblem->var; - - if (gamedata->collected[(emblem-emblemlocations)]) - { - emblempic[curemb] = W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE); - emblemcol[curemb] = R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE); - curemb++; - - if (emblem == maxemblem - && nextemblem != NULL - && nextemblem->type == emblem->type - && gamedata->collected[(nextemblem-emblemlocations)]) - maxemblem = NULL; - - if (emblem != maxemblem) - goto bademblem; - } - - maxemblem = emblem; - - if (emblem->tag > 0) - { - if (emblem->tag > mapheaderinfo[emblemmap-1]->ghostCount - || mapheaderinfo[emblemmap-1]->ghostBrief[emblem->tag-1] == NULL) - goto bademblem; - - timetoreach = mapheaderinfo[emblemmap-1]->ghostBrief[emblem->tag-1]->time; - } - - snprintf(targettext, 9, "%i'%02i\"%02i", - G_TicsToMinutes(timetoreach, false), - G_TicsToSeconds(timetoreach), - G_TicsToCentiseconds(timetoreach)); - - if (!mode) - { - if (stplyr->realtime > timetoreach) - { - splitflags = (splitflags &~ V_HUDTRANS)|V_HUDTRANSHALF; - if (canplaysound) - { - S_StartSound(NULL, sfx_s3k72); //sfx_s26d); -- you STOLE fizzy lifting drinks - canplaysound = false; - } - } - else if (!canplaysound) - canplaysound = true; - } - - targettext[8] = 0; + S_StartSound(NULL, sfx_s3k72); //sfx_s26d); -- you STOLE fizzy lifting drinks + stickermedalinfo.canplaysound = false; } - break; - default: - goto bademblem; + } } - workx -= V_ThinStringWidth(targettext, splitflags|V_6WIDTHSPACE); - V_DrawThinString(workx, worky, splitflags|V_6WIDTHSPACE, targettext); - - if (emblem != maxemblem || !gamedata->collected[(emblem-emblemlocations)]) - { - emblempic[curemb] = W_CachePatchName("NEEDIT", PU_CACHE); - curemb++; - } - - break; - -bademblem: - if (emblem == maxemblem || curemb == 3) - break; - emblem = nextemblem; + workx -= V_ThinStringWidth(stickermedalinfo.targettext, splitflags|V_6WIDTHSPACE); + V_DrawThinString(workx, worky, splitflags|V_6WIDTHSPACE, stickermedalinfo.targettext); } + workx -= (6 + (i*5)); + if (!mode) splitflags = (splitflags &~ V_HUDTRANSHALF)|V_HUDTRANS; - while (curemb--) + while (i > 0) { - workx -= 11; - V_DrawSmallMappedPatch(workx, worky, splitflags, emblempic[curemb], emblemcol[curemb]); + i--; + + if (gamedata->collected[(stickermedalinfo.emblems[i]-emblemlocations)]) + { + V_DrawSmallMappedPatch(workx, worky, splitflags, + W_CachePatchName(M_GetEmblemPatch(stickermedalinfo.emblems[i], false), PU_CACHE), + R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(stickermedalinfo.emblems[i]), GTC_CACHE) + ); + } + else + { + V_DrawSmallMappedPatch(workx, worky, splitflags, + W_CachePatchName("NEEDIT", PU_CACHE), + NULL + ); + } + + workx += 6; } } } @@ -5089,7 +5034,7 @@ void K_drawKartHUD(void) { // Draw the timestamp if (LUA_HudEnabled(hud_time)) - K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y, gamemap, 0); + K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y, 0); islonesome = K_drawKartPositionFaces(); } diff --git a/src/k_hud.h b/src/k_hud.h index 7960c0aba..982cc76f5 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -40,7 +40,7 @@ const char *K_GetItemPatch(UINT8 item, boolean tiny); void K_LoadKartHUDGraphics(void); void K_drawKartHUD(void); void K_drawKartFreePlay(void); -void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode); +void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, UINT8 mode); void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol); void K_DrawMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, UINT16 map, UINT8 *colormap); void K_DrawLikeMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, patch_t *patch, UINT8 *colormap); diff --git a/src/k_menudraw.c b/src/k_menudraw.c index c64636abe..0963909b7 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2266,7 +2266,7 @@ void M_DrawTimeAttack(void) && (mapheaderinfo[map]->numlaps != 1)) { V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST LAP:"); - K_drawKartTimestamp(laprec, 162+t, timeheight+6, 0, 2); + K_drawKartTimestamp(laprec, 162+t, timeheight+6, 2); timeheight += 30; } else @@ -2275,7 +2275,7 @@ void M_DrawTimeAttack(void) } V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST TIME:"); - K_drawKartTimestamp(timerec, 162+t, timeheight+6, map+1, 1); + K_drawKartTimestamp(timerec, 162+t, timeheight+6, 1); } else opty = 80; diff --git a/src/menus/play-local-race-time-attack.c b/src/menus/play-local-race-time-attack.c index 9443379f1..b64fd2715 100644 --- a/src/menus/play-local-race-time-attack.c +++ b/src/menus/play-local-race-time-attack.c @@ -178,6 +178,7 @@ void M_PrepareTimeAttack(INT32 choice) { (void) choice; + // Gametype guess if (levellist.guessgt != MAXGAMETYPES) { levellist.newgametype = levellist.guessgt; @@ -189,6 +190,10 @@ void M_PrepareTimeAttack(INT32 choice) } } + // Time-sticker Medals + G_UpdateTimeStickerMedals(levellist.choosemap); + + // Menu options { // see also p_setup.c's P_LoadRecordGhosts char *gpath = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(levellist.choosemap+1)));