From a8d847227d1efad133e7c80ece12cdd5614b28d8 Mon Sep 17 00:00:00 2001 From: SinnamonLat Date: Wed, 27 Jul 2022 12:04:52 +0200 Subject: [PATCH] WIP: time attack, kinda works but crashes when you finish lol --- src/k_menu.h | 15 ++++++++ src/k_menudef.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++-- src/k_menudraw.c | 52 +++++++++++++++++++++----- src/k_menufunc.c | 85 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 234 insertions(+), 14 deletions(-) diff --git a/src/k_menu.h b/src/k_menu.h index c018c7614..eb6e166cc 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -205,6 +205,15 @@ extern menu_t PLAY_LevelSelectDef; extern menuitem_t PLAY_TimeAttack[]; extern menu_t PLAY_TimeAttackDef; +extern menuitem_t PLAY_TAReplay[]; +extern menu_t PLAY_TAReplayDef; + +extern menuitem_t PLAY_TAReplayGuest[]; +extern menu_t PLAY_TAReplayGuestDef; + +extern menuitem_t PLAY_TAGhosts[]; +extern menu_t PLAY_TAGhostsDef; + extern menuitem_t PLAY_MP_OptSelect[]; extern menu_t PLAY_MP_OptSelectDef; @@ -677,6 +686,12 @@ extern struct mpmenu_s { } mpmenu; +// Time Attack +void M_StartTimeAttack(INT32 choice); +void M_ReplayTimeAttack(INT32 choice); +void M_HandleStaffReplay(INT32 choice); +void M_SetGuestReplay(INT32 choice); + // MP selection void M_MPOptSelect(INT32 choice); void M_MPOptSelectInit(INT32 choice); diff --git a/src/k_menudef.c b/src/k_menudef.c index bd810c9e0..fc9439e14 100644 --- a/src/k_menudef.c +++ b/src/k_menudef.c @@ -204,10 +204,11 @@ menu_t PLAY_LevelSelectDef = { menuitem_t PLAY_TimeAttack[] = { - {IT_STRING, "Replay...", NULL, NULL, {NULL}, 0, 0}, - {IT_STRING, "Ghosts...", NULL, NULL, {NULL}, 0, 0}, - {IT_SPACE, NULL, NULL, NULL, {NULL}, 0, 0}, - {IT_STRING, "Start", NULL, NULL, {NULL}, 0, 0}, + {IT_STRING | IT_SUBMENU, "Replay...", NULL, NULL, {.submenu = &PLAY_TAReplayDef}, 0, 0}, + {IT_STRING | IT_SUBMENU, "Guest...", NULL, NULL, {.submenu = &PLAY_TAReplayGuestDef}, 0, 0}, + {IT_STRING | IT_SUBMENU, "Ghosts...", NULL, NULL, {.submenu = &PLAY_TAGhostsDef}, 0, 0}, + {IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0}, + {IT_STRING | IT_CALL, "Start", NULL, NULL, {.routine = M_StartTimeAttack}, 0, 0}, }; menu_t PLAY_TimeAttackDef = { @@ -225,6 +226,93 @@ menu_t PLAY_TimeAttackDef = { NULL }; + +menuitem_t PLAY_TAReplay[] = +{ + {IT_STRING | IT_CALL, "Replay Best Time", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0}, + {IT_STRING | IT_CALL, "Replay Best Lap", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0}, + {IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0}, + {IT_STRING | IT_CALL, "Replay Last", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0}, + {IT_STRING | IT_CALL, "Replay Guest", NULL, NULL, {.routine = M_ReplayTimeAttack}, 0, 0}, + {IT_STRING | IT_CALL, "Replay Staff", NULL, NULL, {.routine = M_HandleStaffReplay}, 0, 0}, + {IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0}, + + {IT_STRING | IT_SUBMENU, "Back", NULL, NULL, {.submenu = &PLAY_TimeAttackDef}, 0, 0}, +}; + +menu_t PLAY_TAReplayDef = { + sizeof(PLAY_TAReplay) / sizeof(menuitem_t), + &PLAY_TimeAttackDef, + 0, + PLAY_TAReplay, + 0, 0, + 0, 0, + 2, 5, + M_DrawTimeAttack, + NULL, + NULL, + NULL, + NULL +}; + +menuitem_t PLAY_TAReplayGuest[] = +{ + {IT_HEADERTEXT|IT_HEADER, "Save as guest...", NULL, NULL, {NULL}, 0, 0}, + + {IT_STRING | IT_CALL, "Best Time", NULL, NULL, {.routine = M_SetGuestReplay}, 0, 0}, + {IT_STRING | IT_CALL, "Best Lap", NULL, NULL, {.routine = M_SetGuestReplay}, 0, 0}, + {IT_STRING | IT_CALL, "Last Run", NULL, NULL, {.routine = M_SetGuestReplay}, 0, 0}, + + {IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0}, + {IT_STRING | IT_CALL, "Delete Guest", NULL, NULL, {.routine = M_SetGuestReplay}, 0, 0}, + + {IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0}, + {IT_STRING | IT_SUBMENU, "Back", NULL, NULL, {.submenu = &PLAY_TimeAttackDef}, 0, 0}, + +}; + +menu_t PLAY_TAReplayGuestDef = { + sizeof(PLAY_TAReplayGuest) / sizeof(menuitem_t), + &PLAY_TimeAttackDef, + 0, + PLAY_TAReplayGuest, + 0, 0, + 0, 0, + 2, 5, + M_DrawTimeAttack, + NULL, + NULL, + NULL, + NULL +}; + +menuitem_t PLAY_TAGhosts[] = +{ + {IT_STRING | IT_CVAR, "Best Time", NULL, NULL, {.cvar = &cv_ghost_besttime}, 0, 0}, + {IT_STRING | IT_CVAR, "Best Lap", NULL, NULL, {.cvar = &cv_ghost_bestlap}, 0, 0}, + {IT_STRING | IT_CVAR, "Last", NULL, NULL, {.cvar = &cv_ghost_last}, 0, 0}, + {IT_DISABLED, "Guest", NULL, NULL, {.cvar = &cv_ghost_guest}, 0, 0}, + {IT_DISABLED, "Staff", NULL, NULL, {.cvar = &cv_ghost_staff}, 0, 0}, + + {IT_HEADERTEXT|IT_HEADER, "", NULL, NULL, {NULL}, 0, 0}, + {IT_STRING | IT_SUBMENU, "Back", NULL, NULL, {.submenu = &PLAY_TimeAttackDef}, 0, 0}, +}; + +menu_t PLAY_TAGhostsDef = { + sizeof(PLAY_TAGhosts) / sizeof(menuitem_t), + &PLAY_TimeAttackDef, + 0, + PLAY_TAGhosts, + 0, 0, + 0, 0, + 2, 5, + M_DrawTimeAttack, + NULL, + NULL, + NULL, + NULL +}; + // BATTLE menuitem_t PLAY_BattleGamemodesMenu[] = diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 5fb105090..ce4f93e49 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2000,38 +2000,70 @@ void M_DrawTimeAttack(void) INT16 t = (48*menutransition.tics); INT16 leftedge = 149+t+16; INT16 rightedge = 149+t+155; - INT16 opty = 152; + INT16 opty = 140; + INT32 w; lumpnum_t lumpnum; UINT8 i; + consvar_t *cv; M_DrawLevelSelectBlock(0, 2, map, true, false); //V_DrawFill(24-t, 82, 100, 100, 36); // size test - lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(map+1))); - if (lumpnum != LUMPERROR) - V_DrawScaledPatch(24-t, 82, 0, W_CachePatchNum(lumpnum, PU_CACHE)); - V_DrawScaledPatch(149+t, 70, 0, W_CachePatchName("BESTTIME", PU_CACHE)); - V_DrawRightAlignedString(rightedge-12, 82, highlightflags, "BEST LAP:"); - K_drawKartTimestamp(0, 162+t, 88, 0, 2); + if (currentMenu == &PLAY_TimeAttackDef) + { + lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(map+1))); + if (lumpnum != LUMPERROR) + V_DrawScaledPatch(24-t, 82, 0, W_CachePatchNum(lumpnum, PU_CACHE)); - V_DrawRightAlignedString(rightedge-12, 112, highlightflags, "BEST TIME:"); - K_drawKartTimestamp(0, 162+t, 118, map, 1); + V_DrawRightAlignedString(rightedge-12, 82, highlightflags, "BEST LAP:"); + K_drawKartTimestamp(0, 162+t, 88, 0, 2); + + V_DrawRightAlignedString(rightedge-12, 112, highlightflags, "BEST TIME:"); + K_drawKartTimestamp(0, 162+t, 118, map, 1); + } + else + opty = 80; for (i = 0; i < currentMenu->numitems; i++) { - UINT32 f = (i == itemOn) ? recommendedflags : highlightflags; + UINT32 f = (i == itemOn) ? highlightflags : 0; switch (currentMenu->menuitems[i].status & IT_DISPLAY) { + + case IT_HEADERTEXT: + + V_DrawString(leftedge, opty, highlightflags, currentMenu->menuitems[i].text); + opty += 10; + break; + case IT_STRING: + if (i >= currentMenu->numitems-1) V_DrawRightAlignedString(rightedge, opty, f, currentMenu->menuitems[i].text); else V_DrawString(leftedge, opty, f, currentMenu->menuitems[i].text); opty += 10; + + // Cvar specific handling + + if (currentMenu->menuitems[i].status & IT_CVAR) + { + cv = currentMenu->menuitems[i].itemaction.cvar; + + w = V_StringWidth(cv->string, 0); + V_DrawString(leftedge, opty, f, cv->string); + if (i == itemOn) + { + V_DrawCharacter(leftedge - 10 - (skullAnimCounter/5), opty, '\x1C' | f, false); // left arrow + V_DrawCharacter(leftedge + w + 2+ (skullAnimCounter/5), opty, '\x1D' | f, false); // right arrow + } + opty += 10; + } + break; case IT_SPACE: opty += 4; diff --git a/src/k_menufunc.c b/src/k_menufunc.c index 925552aed..f2b9133fb 100644 --- a/src/k_menufunc.c +++ b/src/k_menufunc.c @@ -3454,6 +3454,9 @@ void M_CupSelectHandler(INT32 choice) if (cupgrid.grandprix == true) { + + UINT8 ssplayers = cv_splitplayers.value-1; + S_StartSound(NULL, sfx_s3k63); // Early fadeout to let the sound finish playing @@ -3464,6 +3467,15 @@ void M_CupSelectHandler(INT32 choice) memset(&grandprixinfo, 0, sizeof(struct grandprixinfo)); + if (cv_maxplayers.value < ssplayers+1) + CV_SetValue(&cv_maxplayers, ssplayers+1); + + if (splitscreen != ssplayers) + { + splitscreen = ssplayers; + SplitScreen_OnChange(); + } + // read our dummy cvars grandprixinfo.gamespeed = min(KARTSPEED_HARD, cv_dummygpdifficulty.value); @@ -3677,6 +3689,79 @@ void M_LevelSelectTick(void) levellist.y += dist/2; } + +// time attack stuff... +void M_HandleStaffReplay(INT32 choice) +{ + // @TODO: + (void) choice; +} + +void M_ReplayTimeAttack(INT32 choice) +{ + // @TODO: + (void) choice; +} + +void M_SetGuestReplay(INT32 choice) +{ + // @TODO: + (void) choice; +} + +void M_StartTimeAttack(INT32 choice) +{ + char *gpath; + const size_t glen = strlen("media")+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; + char nameofdemo[256]; + (void)choice; + emeralds = 0; + + modeattacking = ATTACKING_TIME; + + // Still need to reset devmode + cv_debug = 0; + + if (demo.playback) + G_StopDemo(); + if (metalrecording) + G_StopMetalDemo(); + + splitscreen = 0; + SplitScreen_OnChange(); + + S_StartSound(NULL, sfx_s3k63); + + paused = false; + + // Early fadeout to let the sound finish playing + F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false); + + SV_StartSinglePlayerServer(); + + gpath = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s", + srb2home, timeattackfolder); + M_MkdirEach(gpath, M_PathParts(gpath) - 3, 0755); + + if ((gpath = malloc(glen)) == NULL) + I_Error("Out of memory for replay filepath\n"); + + sprintf(gpath,"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", timeattackfolder, G_BuildMapName(levellist.choosemap+1)); + snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, cv_skin[0].string); + + if (!cv_autorecord.value) + remove(va("%s"PATHSEP"%s.lmp", srb2home, nameofdemo)); + else + G_RecordDemo(nameofdemo); + + M_ClearMenus(true); + D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_dummygpencore.value == 1), 1, 1, false, false); +} + + struct mpmenu_s mpmenu; // MULTIPLAYER OPTION SELECT