From 522fccaf2e507ac805d05de46d0d516cfb001c95 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 13 Jun 2018 17:52:23 +0100 Subject: [PATCH 01/20] * Record attack tab-HUD tweaks. * Do not subtract a life when retrying if you have infinite lives. --- src/g_game.c | 2 +- src/hu_stuff.c | 20 ++++++++++++-------- src/st_stuff.c | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index e5077fb21..2acafddb3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1893,7 +1893,7 @@ void G_Ticker(boolean run) G_ClearRetryFlag(); // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE) + if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) players[consoleplayer].lives -= 1; G_DoReborn(consoleplayer); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index a13801388..bc57931f5 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1029,25 +1029,29 @@ UINT16 hu_demorings; static void HU_DrawDemoInfo(void) { - V_DrawString(4, 188-24, V_YELLOWMAP, va(M_GetText("%s's replay"), player_names[0])); + INT32 h = 188; + if (modeattacking == ATTACKING_NIGHTS) + h -= 12; + + V_DrawString(4, h-24, V_YELLOWMAP|V_ALLOWLOWERCASE, va(M_GetText("%s's replay"), player_names[0])); if (modeattacking) { - V_DrawString(4, 188-16, V_YELLOWMAP|V_MONOSPACE, "SCORE:"); - V_DrawRightAlignedString(120, 188-16, V_MONOSPACE, va("%d", hu_demoscore)); + V_DrawString(4, h-16, V_YELLOWMAP|V_MONOSPACE, "SCORE:"); + V_DrawRightAlignedString(120, h-16, V_MONOSPACE, va("%d", hu_demoscore)); - V_DrawString(4, 188- 8, V_YELLOWMAP|V_MONOSPACE, "TIME:"); + V_DrawString(4, h-8, V_YELLOWMAP|V_MONOSPACE, "TIME:"); if (hu_demotime != UINT32_MAX) - V_DrawRightAlignedString(120, 188- 8, V_MONOSPACE, va("%i:%02i.%02i", + V_DrawRightAlignedString(120, h-8, V_MONOSPACE, va("%i:%02i.%02i", G_TicsToMinutes(hu_demotime,true), G_TicsToSeconds(hu_demotime), G_TicsToCentiseconds(hu_demotime))); else - V_DrawRightAlignedString(120, 188- 8, V_MONOSPACE, "--:--.--"); + V_DrawRightAlignedString(120, h-8, V_MONOSPACE, "--:--.--"); if (modeattacking == ATTACKING_RECORD) { - V_DrawString(4, 188 , V_YELLOWMAP|V_MONOSPACE, "RINGS:"); - V_DrawRightAlignedString(120, 188 , V_MONOSPACE, va("%d", hu_demorings)); + V_DrawString(4, h, V_YELLOWMAP|V_MONOSPACE, "RINGS:"); + V_DrawRightAlignedString(120, h, V_MONOSPACE, va("%d", hu_demorings)); } } } diff --git a/src/st_stuff.c b/src/st_stuff.c index d5cc9cf29..2a7e0636a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2393,7 +2393,7 @@ static void ST_overlayDrawer(void) ) ST_drawTextHUD(); - if (modeattacking) + if (modeattacking && !hu_showscores) ST_drawInput(); ST_drawDebugInfo(); From 62927bbb76fc045a8c7a61606ac99f8086d003ac Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 Jun 2018 00:58:28 +0100 Subject: [PATCH 02/20] * Hold the pause button to restart a record attack run! * Obligatory GIF: https://cdn.discordapp.com/attachments/400761370800422922/456586705424875520/srb20047.gif * Show powerup display in singleplayer even while holding Game Status button. --- src/g_game.c | 54 +++++++++++++++++++++++++++++++++++++------------- src/g_game.h | 1 + src/hu_stuff.c | 23 +++++++++++++++++++++ src/m_menu.c | 6 +++--- src/m_menu.h | 4 +++- src/p_setup.c | 10 +++++++++- src/st_stuff.c | 8 +++++--- 7 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2acafddb3..4463f55ce 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1672,7 +1672,7 @@ void G_DoLoadLevel(boolean resetplayer) CON_ClearHUD(); } -static INT32 pausedelay = 0; +INT32 pausedelay = 0; static INT32 camtoggledelay, camtoggledelay2 = 0; // @@ -1822,17 +1822,30 @@ boolean G_Responder(event_t *ev) if (ev->data1 == gamecontrol[gc_pause][0] || ev->data1 == gamecontrol[gc_pause][1]) { - if (!pausedelay) + if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { - // don't let busy scripts prevent pausing - pausedelay = NEWTICRATE/7; + if (menuactive || pausedelay < 0 || leveltime < 2) + return true; - // command will handle all the checks for us - COM_ImmedExecute("pause"); - return true; + if (++pausedelay > (NEWTICRATE/3)) + { + pausedelay = INT32_MIN; + G_SetRetryFlag(); + return true; + } + pausedelay++; // counteract subsequent subtraction this frame } else - pausedelay = NEWTICRATE/7; + { + INT32 oldpausedelay = pausedelay; + pausedelay = (NEWTICRATE/7); + if (!oldpausedelay) + { + // command will handle all the checks for us + COM_ImmedExecute("pause"); + return true; + } + } } if (ev->data1 == gamecontrol[gc_camtoggle][0] || ev->data1 == gamecontrol[gc_camtoggle][1]) @@ -1892,11 +1905,16 @@ void G_Ticker(boolean run) { G_ClearRetryFlag(); - // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) - players[consoleplayer].lives -= 1; + if (modeattacking) + M_ModeAttackRetry(0); + else + { + // Costs a life to retry ... unless the player in question is dead already. + if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) + players[consoleplayer].lives -= 1; - G_DoReborn(consoleplayer); + G_DoReborn(consoleplayer); + } } for (i = 0; i < MAXPLAYERS; i++) @@ -1994,8 +2012,13 @@ void G_Ticker(boolean run) if (run) { - if (pausedelay) - pausedelay--; + if (pausedelay && pausedelay != INT32_MIN) + { + if (pausedelay > 0) + pausedelay--; + else + pausedelay++; + } if (camtoggledelay) camtoggledelay--; @@ -2935,6 +2958,9 @@ static void G_DoCompleted(void) tokenlist = 0; // Reset the list + if (modeattacking && pausedelay) + pausedelay = 0; + gameaction = ga_nothing; if (metalplayback) diff --git a/src/g_game.h b/src/g_game.h index d6b41830e..3d04370aa 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -53,6 +53,7 @@ extern INT16 prevmap, nextmap; extern INT32 gameovertics; extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) extern INT16 rw_maximums[NUM_WEAPONS]; +extern INT32 pausedelay; // used in game menu extern consvar_t cv_crosshair, cv_crosshair2; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index bc57931f5..f4730005e 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1120,6 +1120,29 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } + + if (modeattacking && pausedelay > 1) + { + UINT8 strength = (pausedelay*10)/(NEWTICRATE/3); + INT32 y = hudinfo[HUD_LIVES].y - 13; + + if (strength > 9) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + else if (strength) + V_DrawFadeScreen(0, strength); + + if (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE) + y -= 16; + else + { + if (players[consoleplayer].pflags & PF_AUTOBRAKE) + y -= 8; + if (players[consoleplayer].pflags & PF_ANALOGMODE) + y -= 8; + } + + V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, hudinfo[HUD_LIVES].f|((leveltime & 2) ? V_SKYMAP : V_BLUEMAP), "RETRYING..."); + } } //====================================================================== diff --git a/src/m_menu.c b/src/m_menu.c index a866dac1b..5258f4b44 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -282,7 +282,6 @@ static void M_Statistics(INT32 choice); static void M_ReplayTimeAttack(INT32 choice); static void M_ChooseTimeAttack(INT32 choice); static void M_ChooseNightsAttack(INT32 choice); -static void M_ModeAttackRetry(INT32 choice); static void M_ModeAttackEndGame(INT32 choice); static void M_SetGuestReplay(INT32 choice); static void M_HandleChoosePlayerMenu(INT32 choice); @@ -1083,7 +1082,7 @@ static menuitem_t OP_ChangeControlsMenu[] = {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Game Status", M_ChangeControl, gc_scores }, - {IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause }, + {IT_CALL | IT_STRING2, NULL, "Pause / Run Retry", M_ChangeControl, gc_pause }, {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console }, {IT_HEADER, NULL, "Multiplayer", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding @@ -7841,9 +7840,10 @@ static void M_SetGuestReplay(INT32 choice) which(0); } -static void M_ModeAttackRetry(INT32 choice) +void M_ModeAttackRetry(INT32 choice) { (void)choice; + // todo -- maybe seperate this out and G_SetRetryFlag() here instead? is just calling this from the menu 100% safe? G_CheckDemoStatus(); // Cancel recording if (modeattacking == ATTACKING_RECORD) M_ChooseTimeAttack(0); diff --git a/src/m_menu.h b/src/m_menu.h index 9df56e897..c1e48912a 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -235,7 +235,7 @@ extern INT16 startmap; extern INT32 ultimate_selectable; extern INT16 char_on, startchar; -#define MAXSAVEGAMES 31 //note: last save game is "no save" +#define MAXSAVEGAMES 31 #define NOSAVESLOT 0 //slot where Play Without Saving appears #define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he @@ -244,6 +244,8 @@ void M_ForceSaveSlotSelected(INT32 sslot); void M_CheatActivationResponder(INT32 ch); +void M_ModeAttackRetry(INT32 choice); + // Level select updating void Nextmap_OnChange(void); diff --git a/src/p_setup.c b/src/p_setup.c index a5544c26b..11e6b4ef7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2728,7 +2728,9 @@ boolean P_SetupLevel(boolean skipprecip) // Special stage fade to white // This is handled BEFORE sounds are stopped. - if (rendermode != render_none && G_IsSpecialStage(gamemap)) + if (modeattacking && pausedelay == INT32_MIN) + ranspecialwipe = 2; + else if (rendermode != render_none && G_IsSpecialStage(gamemap)) { tic_t starttime = I_GetTime(); tic_t endtime = starttime + (3*TICRATE)/2; @@ -2778,6 +2780,12 @@ boolean P_SetupLevel(boolean skipprecip) F_RunWipe(wipedefs[wipe_level_toblack], false); } + if (ranspecialwipe == 2) + { + pausedelay = -NEWTICRATE; + S_StartSound(NULL, sfx_s3k73); + } + // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." if (!titlemapinaction && rendermode != render_none) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 2a7e0636a..698411533 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2367,11 +2367,13 @@ static void ST_overlayDrawer(void) { ST_drawFirstPersonHUD(); if (cv_powerupdisplay.value) - ST_drawPowerupHUD(); + ST_drawPowerupHUD(); // same as it ever was... } else if (cv_powerupdisplay.value == 2) - ST_drawPowerupHUD(); + ST_drawPowerupHUD(); // same as it ever was... } + else if (!(netgame || multiplayer) && cv_powerupdisplay.value == 2) + ST_drawPowerupHUD(); // same as it ever was... #ifdef HAVE_BLUA if (!(netgame || multiplayer) || !hu_showscores) @@ -2393,7 +2395,7 @@ static void ST_overlayDrawer(void) ) ST_drawTextHUD(); - if (modeattacking && !hu_showscores) + if (modeattacking && !(demoplayback && hu_showscores)) ST_drawInput(); ST_drawDebugInfo(); From a3f7e07e4d25bfae5be7eafa7190ba23422cafd2 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 Jun 2018 14:41:14 +0100 Subject: [PATCH 03/20] Improve retrying text presentation. * Now reads "HOLD TO RETRY...". * Behind the white flash. * Shows on button tap for about half a second. --- src/g_game.c | 4 +++- src/hu_stuff.c | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 4463f55ce..2ee798cda 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1827,7 +1827,9 @@ boolean G_Responder(event_t *ev) if (menuactive || pausedelay < 0 || leveltime < 2) return true; - if (++pausedelay > (NEWTICRATE/3)) + if (pausedelay < 1+(NEWTICRATE/2)) + pausedelay = 1+(NEWTICRATE/2); + else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3)) { pausedelay = INT32_MIN; G_SetRetryFlag(); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index f4730005e..7f66ade34 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1121,16 +1121,11 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } - if (modeattacking && pausedelay > 1) + if (modeattacking && pausedelay > 0) { - UINT8 strength = (pausedelay*10)/(NEWTICRATE/3); + INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3); INT32 y = hudinfo[HUD_LIVES].y - 13; - if (strength > 9) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); - else if (strength) - V_DrawFadeScreen(0, strength); - if (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE) y -= 16; else @@ -1141,7 +1136,14 @@ void HU_Drawer(void) y -= 8; } - V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, hudinfo[HUD_LIVES].f|((leveltime & 2) ? V_SKYMAP : V_BLUEMAP), "RETRYING..."); + V_DrawThinString(hudinfo[HUD_LIVES].x-2, y, + hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_SKYMAP : V_BLUEMAP), + "HOLD TO RETRY..."); + + if (strength > 9) + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + else if (strength > 0) + V_DrawFadeScreen(0, strength); } } From 255d5c6c9422d5934d9acfd2bc2767112ded8a9b Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 Jun 2018 20:17:31 +0100 Subject: [PATCH 04/20] * Level title movement begins before the fade in! * https://cdn.discordapp.com/attachments/400761370800422922/456833651645349888/srb20051.gif * Fix some wipe bugs. * Solved that thing where there was no fade between two back-to-back cutscenes. * Fixed there being no effective wipe between the end of the vanilla intro cutscene and the title screen. * Smoothed out the behaviour of titlemap fades to prevent conflicts. * [COMPLETELY UNRELATED] Kill the pause graphic and replace with a blue box with text in it, like what happens when the window loses focus. Much harder to miss. --- src/d_main.c | 124 +++++++++++++++++++++++++++---------------------- src/f_finale.c | 21 +++++++-- src/p_setup.c | 111 ++++++++++++++++++++++++++++++------------- src/p_user.c | 4 +- src/st_stuff.c | 20 ++++---- src/st_stuff.h | 3 ++ 6 files changed, 178 insertions(+), 105 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index a5e1a0254..ee946be48 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -283,7 +283,7 @@ static void D_Display(void) if (rendermode != render_none) { // Fade to black first - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) // fades to black on its own timing, always + if ((wipegamestate != -2) // fades to black on its own timing, always && wipedefs[wipedefindex] != UINT8_MAX) { F_WipeStartScreen(); @@ -361,88 +361,95 @@ static void D_Display(void) break; } - // clean up border stuff - // see if the border needs to be initially drawn - if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) + // STUPID race condition... + if (wipegamestate == GS_INTRO && gamestate == GS_TITLESCREEN) + wipegamestate = -2; + else { - // draw the view directly + wipegamestate = gamestate; - if (!automapactive && !dedicated && cv_renderview.value) + // clean up border stuff + // see if the border needs to be initially drawn + if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) { - if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) - { - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; - objectsdrawn = 0; -#ifdef HWRENDER - if (rendermode != render_soft) - HWR_RenderPlayerView(0, &players[displayplayer]); - else -#endif - if (rendermode != render_none) - R_RenderPlayerView(&players[displayplayer]); - } + // draw the view directly - // render the second screen - if (splitscreen && players[secondarydisplayplayer].mo) + if (!automapactive && !dedicated && cv_renderview.value) { -#ifdef HWRENDER - if (rendermode != render_soft) - HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); - else -#endif - if (rendermode != render_none) + if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { - viewwindowy = vid.height / 2; - M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); - topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + objectsdrawn = 0; + #ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(0, &players[displayplayer]); + else + #endif + if (rendermode != render_none) + R_RenderPlayerView(&players[displayplayer]); + } - R_RenderPlayerView(&players[secondarydisplayplayer]); + // render the second screen + if (splitscreen && players[secondarydisplayplayer].mo) + { + #ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(1, &players[secondarydisplayplayer]); + else + #endif + if (rendermode != render_none) + { + viewwindowy = vid.height / 2; + M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); - viewwindowy = 0; - M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + + R_RenderPlayerView(&players[secondarydisplayplayer]); + + viewwindowy = 0; + M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + } + } + + // Image postprocessing effect + if (rendermode == render_soft) + { + if (postimgtype) + V_DoPostProcessor(0, postimgtype, postimgparam); + if (postimgtype2) + V_DoPostProcessor(1, postimgtype2, postimgparam2); } } - // Image postprocessing effect - if (rendermode == render_soft) + if (lastdraw) { - if (postimgtype) - V_DoPostProcessor(0, postimgtype, postimgparam); - if (postimgtype2) - V_DoPostProcessor(1, postimgtype2, postimgparam2); + if (rendermode == render_soft) + { + VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); + usebuffer = true; + } + lastdraw = false; } - } - if (lastdraw) - { - if (rendermode == render_soft) + if (gamestate == GS_LEVEL) { - VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); - usebuffer = true; + ST_Drawer(); + HU_Drawer(); } - lastdraw = false; + else + F_TitleScreenDrawer(); } - - if (gamestate == GS_LEVEL) - { - ST_Drawer(); - HU_Drawer(); - } - else - F_TitleScreenDrawer(); } // change gamma if needed // (GS_LEVEL handles this already due to level-specific palettes) - if (forcerefresh && gamestate != GS_LEVEL) + if (forcerefresh && !(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) V_SetPalette(0); - wipegamestate = gamestate; - // draw pause pic if (paused && cv_showhud.value && (!menuactive || netgame)) { +#if 0 INT32 py; patch_t *patch; if (automapactive) @@ -451,6 +458,11 @@ static void D_Display(void) py = viewwindowy + 4; patch = W_CachePatchName("M_PAUSE", PU_CACHE); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch); +#else + INT32 y = ((automapactive) ? (32) : (BASEVIDHEIGHT/2)); + M_DrawTextBox((BASEVIDWIDTH/2) - (60), y - (16), 13, 2); + V_DrawCenteredString(BASEVIDWIDTH/2, y - (4), V_YELLOWMAP, "Game Paused"); +#endif } // vid size change is now finished if it was on... diff --git a/src/f_finale.c b/src/f_finale.c index db62ddf09..2b0c38542 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -29,6 +29,7 @@ #include "g_input.h" #include "console.h" #include "m_random.h" +#include "m_misc.h" // moviemode functionality #include "y_inter.h" #include "m_cond.h" #include "p_local.h" @@ -816,18 +817,27 @@ void F_IntroDrawer(void) // Stay on black for a bit. =) { - tic_t quittime; - quittime = I_GetTime() + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds - while (quittime > I_GetTime()) + tic_t nowtime, quittime, lasttime; + nowtime = lasttime = I_GetTime(); + quittime = nowtime + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds + while (quittime > nowtime) { + while (!((nowtime = I_GetTime()) - lasttime)) + I_Sleep(); + lasttime = nowtime; + I_OsPolling(); I_UpdateNoBlit(); M_Drawer(); // menu is drawn even on top of wipes I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 + + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); } } D_StartTitle(); + wipegamestate = GS_INTRO; return; } F_NewCutscene(introtext[++intro_scenenum]); @@ -1532,7 +1542,7 @@ void F_TitleScreenDrawer(void) if (!titlemapinaction) F_SkyScroll(titlescrollspeed); - // Don't draw outside of the title screewn, or if the patch isn't there. + // Don't draw outside of the title screen, or if the patch isn't there. if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)) return; @@ -1877,6 +1887,9 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset G_SetGamestate(GS_CUTSCENE); + if (wipegamestate == GS_CUTSCENE) + wipegamestate = -1; + gameaction = ga_nothing; paused = false; CON_ToggleOff(); diff --git a/src/p_setup.c b/src/p_setup.c index 11e6b4ef7..a1ef08c5d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -56,8 +56,11 @@ #include "filesrch.h" // refreshdirmenu -// wipes -#include "f_finale.h" +#ifdef HAVE_BLUA +#include "lua_hud.h" // level title +#endif + +#include "f_finale.h" // wipes #include "md5.h" // map MD5 @@ -2673,7 +2676,6 @@ boolean P_SetupLevel(boolean skipprecip) CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer - // Reset the palette if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); @@ -2726,6 +2728,9 @@ boolean P_SetupLevel(boolean skipprecip) // will be set by player think. players[consoleplayer].viewz = 1; + // Cancel all d_main.c fadeouts (keep fade in though). + wipegamestate = -2; + // Special stage fade to white // This is handled BEFORE sounds are stopped. if (modeattacking && pausedelay == INT32_MIN) @@ -2763,41 +2768,42 @@ boolean P_SetupLevel(boolean skipprecip) S_StopSounds(); S_ClearSfx(); - // As oddly named as this is, this handles music only. - // We should be fine starting it here. - /// ... as long as this isn't a titlemap transition, that is if (!titlemapinaction) + { + // As oddly named as this is, this handles music only. + // We should be fine starting it here. S_Start(); - // Let's fade to black here - // But only if we didn't do the special stage wipe - if (rendermode != render_none && !ranspecialwipe) - { - F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + // Let's fade to black here + // But only if we didn't do the special stage wipe + if (rendermode != render_none && !ranspecialwipe) + { + F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_toblack], false); - } + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipe_level_toblack], false); + } - if (ranspecialwipe == 2) - { - pausedelay = -NEWTICRATE; - S_StartSound(NULL, sfx_s3k73); - } + if (ranspecialwipe == 2) + { + pausedelay = -NEWTICRATE; + S_StartSound(NULL, sfx_s3k73); + } - // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." - if (!titlemapinaction && rendermode != render_none) - { - // Don't include these in the fade! - char tx[64]; - V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); - snprintf(tx, 63, "%s%s%s", - mapheaderinfo[gamemap-1]->lvlttl, - (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", - (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); - V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); - I_UpdateNoVsync(); + // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." + if (rendermode != render_none) + { + // Don't include these in the fade! + char tx[64]; + V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); + snprintf(tx, 63, "%s%s%s", + mapheaderinfo[gamemap-1]->lvlttl, + (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", + (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); + V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); + I_UpdateNoVsync(); + } } #ifdef HAVE_BLUA @@ -3176,7 +3182,7 @@ boolean P_SetupLevel(boolean skipprecip) P_MapEnd(); // Remove the loading shit from the screen - if (rendermode != render_none) + if (rendermode != render_none && !titlemapinaction) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); if (precache || dedicated) @@ -3227,6 +3233,45 @@ boolean P_SetupLevel(boolean skipprecip) #endif } + // Stage title! + if (rendermode != render_none + && (!titlemapinaction) + && ranspecialwipe != 2 + && *mapheaderinfo[gamemap-1]->lvlttl != '\0' +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_stagetitle) +#endif + ) + { + tic_t starttime = I_GetTime(); + tic_t endtime = starttime + (10*NEWTICRATERATIO); + tic_t nowtime = starttime; + tic_t lasttime = starttime; + while (nowtime < endtime) + { + // draw loop + while (!((nowtime = I_GetTime()) - lasttime)) + I_Sleep(); + lasttime = nowtime; + + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); + stplyr = &players[consoleplayer]; + ST_drawLevelTitle(nowtime - starttime); + if (splitscreen) + { + stplyr = &players[secondarydisplayplayer]; + ST_drawLevelTitle(nowtime - starttime); + } + + I_OsPolling(); + I_UpdateNoBlit(); + I_FinishUpdate(); // page flip or blit buffer + + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); + } + } + return true; } diff --git a/src/p_user.c b/src/p_user.c index 2bcb3bc6c..40e5f7a87 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -766,8 +766,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) // Don't show before title card // Not consistency safe, but this only affects drawing - if (timeinmap + 40 < 110) - player->texttimer = (UINT8)(110 - timeinmap); + if (timeinmap + 40 < (110 - 70)) + player->texttimer = (UINT8)((110 - 70) - timeinmap); } player->powers[pw_carry] = CR_NIGHTSMODE; diff --git a/src/st_stuff.c b/src/st_stuff.c index 698411533..6f9b0c182 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1113,7 +1113,7 @@ static void ST_drawInput(void) V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); } -static void ST_drawLevelTitle(void) +void ST_drawLevelTitle(tic_t titletime) { char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; @@ -1121,7 +1121,7 @@ static void ST_drawLevelTitle(void) INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos; INT32 subttlxpos = BASEVIDWIDTH/2; - if (!(timeinmap > 2 && timeinmap-3 < 110)) + if (!(titletime > 2 && titletime-3 < 110)) return; if (actnum > 0) @@ -1144,22 +1144,22 @@ static void ST_drawLevelTitle(void) #define MIDZONEY 105 #define MIDDIFF 4 - if (timeinmap < 10) + if (titletime < 10) { - fixed_t z = ((timeinmap - 3)< Date: Thu, 14 Jun 2018 22:23:20 +0100 Subject: [PATCH 05/20] * Make the OpenGL loading screen work with the fades better. * Make the closed captions not mess with fades, and improve their movement calculation. --- src/hardware/hw_bsp.c | 3 ++- src/p_setup.c | 7 +++++-- src/p_setup.h | 1 + src/screen.c | 8 +++++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index fa5bce308..04afb9be9 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -29,6 +29,7 @@ #include "../m_argv.h" #include "../i_video.h" #include "../w_wad.h" +#include "../p_setup.h" // levelfadecol // -------------------------------------------------------------------------- // This is global data for planes rendering @@ -644,7 +645,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b sprintf(s, "%d%%", (++ls_percent)<<1); x = BASEVIDWIDTH/2; y = BASEVIDHEIGHT/2; - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Black background to match fade in effect + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); // Background to match fade in effect //V_DrawPatchFill(W_CachePatchName("SRB2BACK",PU_CACHE)); // SRB2 background, ehhh too bright. M_DrawTextBox(x-58, y-8, 13, 1); V_DrawString(x-50, y, V_YELLOWMAP, "Loading..."); diff --git a/src/p_setup.c b/src/p_setup.c index a1ef08c5d..43da5275b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -103,6 +103,7 @@ side_t *sides; mapthing_t *mapthings; INT32 numstarposts; boolean levelloading; +UINT8 levelfadecol; // BLOCKMAP // Created from axis aligned bounding box @@ -2806,6 +2807,8 @@ boolean P_SetupLevel(boolean skipprecip) } } + levelfadecol = (ranspecialwipe) ? 0 : 31; + #ifdef HAVE_BLUA LUA_InvalidateLevel(); #endif @@ -3183,7 +3186,7 @@ boolean P_SetupLevel(boolean skipprecip) // Remove the loading shit from the screen if (rendermode != render_none && !titlemapinaction) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); if (precache || dedicated) R_PrecacheLevel(); @@ -3254,7 +3257,7 @@ boolean P_SetupLevel(boolean skipprecip) I_Sleep(); lasttime = nowtime; - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); stplyr = &players[consoleplayer]; ST_drawLevelTitle(nowtime - starttime); if (splitscreen) diff --git a/src/p_setup.h b/src/p_setup.h index a42ac5b76..f3897d1e0 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -27,6 +27,7 @@ extern mapthing_t *deathmatchstarts[MAX_DM_STARTS]; extern INT32 numdmstarts, numcoopstarts, numredctfstarts, numbluectfstarts; extern boolean levelloading; +extern UINT8 levelfadecol; extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame // diff --git a/src/screen.c b/src/screen.c index cd97b62fa..13c211724 100644 --- a/src/screen.c +++ b/src/screen.c @@ -442,14 +442,16 @@ void SCR_ClosedCaptions(void) boolean gamestopped = (paused || P_AutoPause()); INT32 basey = BASEVIDHEIGHT; + if (gamestate != wipegamestate) + return; + if (gamestate == GS_LEVEL) { if (splitscreen) basey -= 8; - else if (((maptol & TOL_NIGHTS) && (modeattacking == ATTACKING_NIGHTS)) + else if ((modeattacking == ATTACKING_NIGHTS) || (cv_powerupdisplay.value == 2) - || (cv_powerupdisplay.value == 1 && ((stplyr == &players[displayplayer] && !camera.chase) - || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)))) + || (cv_powerupdisplay.value == 1 && !splitscreen && !camera.chase)) basey -= 16; } From 59d617d31fd09ceb50f645a0811c0ead5534aa6b Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 14 Jun 2018 22:23:55 +0100 Subject: [PATCH 06/20] Minor modifications to the intro text. --- src/f_finale.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 2b0c38542..30a14c080 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -317,7 +317,7 @@ void F_StartIntro(void) introtext[2] = M_GetText( "As it was about to drain the rings\n" "away from the planet, Sonic burst into\n" - "the Satellite and for what he thought\n" + "the control room and for what he thought\n" "would be the last time,\xB4 defeated\n" "Dr. Eggman.\n#"); @@ -327,11 +327,11 @@ void F_StartIntro(void) "return,\xB8 bringing an all new threat.\n#"); introtext[4] = M_GetText( - "\xA8""About once every year, a strange asteroid\n" + "\xA8""About every five years, a strange asteroid\n" "hovers around the planet.\xBF It suddenly\n" "appears from nowhere, circles around, and\n" "\xB6- just as mysteriously as it arrives -\xB6\n" - "vanishes after about one week.\xBF\n" + "vanishes after only one week.\xBF\n" "No one knows why it appears, or how.\n#"); introtext[5] = M_GetText( @@ -384,7 +384,7 @@ void F_StartIntro(void) "\xA5\"6...\xD2""5...\xD2""4...\"\xA8\xD2\n" "Sonic knew he was getting closer to the\n" "zone, and pushed himself harder.\xB4 Finally,\n" - "the mountain appeared in the horizon.\xD2\xD2\n" + "the mountain appeared on the horizon.\xD2\xD2\n" "\xA5\"3...\xD2""2...\xD2""1...\xD2""Zero.\"\n#"); introtext[11] = M_GetText( From f0618d5780240ab2b26743c0143aa9e888c0ee82 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 15 Jun 2018 21:42:36 +0100 Subject: [PATCH 07/20] Correct some minor deficiencies in the hold-for-retry system in record attack. --- src/g_game.c | 4 +++- src/p_setup.c | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2ee798cda..4e3e5f0c7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1831,7 +1831,6 @@ boolean G_Responder(event_t *ev) pausedelay = 1+(NEWTICRATE/2); else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3)) { - pausedelay = INT32_MIN; G_SetRetryFlag(); return true; } @@ -1908,7 +1907,10 @@ void G_Ticker(boolean run) G_ClearRetryFlag(); if (modeattacking) + { + pausedelay = INT32_MIN; M_ModeAttackRetry(0); + } else { // Costs a life to retry ... unless the player in question is dead already. diff --git a/src/p_setup.c b/src/p_setup.c index 43da5275b..673541c84 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2734,7 +2734,7 @@ boolean P_SetupLevel(boolean skipprecip) // Special stage fade to white // This is handled BEFORE sounds are stopped. - if (modeattacking && pausedelay == INT32_MIN) + if (modeattacking && !demoplayback && (pausedelay == INT32_MIN)) ranspecialwipe = 2; else if (rendermode != render_none && G_IsSpecialStage(gamemap)) { @@ -2788,7 +2788,7 @@ boolean P_SetupLevel(boolean skipprecip) if (ranspecialwipe == 2) { - pausedelay = -NEWTICRATE; + pausedelay = -3; // preticker plus one S_StartSound(NULL, sfx_s3k73); } From f3baf608a243a8e83aa86216cee50a0cd944eed5 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 17 Jun 2018 18:45:03 +0100 Subject: [PATCH 08/20] Revamp of addons menu search! * Instead of iterating through the folder every time you change the search query by one letter, iterate through the "coredirmenu" (the game's interpretation of the folder) instead. MUCH, much less likely to lag to fuck and back. * Hide a bit of complexity in filesrch.c instead of having the entire thing exposed to mess with. For example, closefilemenu() instead of manually freeing the struct each time. * Refactor some stuff. --- src/filesrch.c | 210 ++++++++++++++++++++++++++++++++++--------------- src/filesrch.h | 2 + src/m_menu.c | 21 ++--- 3 files changed, 155 insertions(+), 78 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 2b5493642..3e1e5891a 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -326,8 +326,8 @@ size_t menudepthleft = menudepth; char menusearch[MAXSTRINGLENGTH+1]; -char **dirmenu; -size_t sizedirmenu; +char **dirmenu, **coredirmenu; // core only local for this file +size_t sizedirmenu, sizecoredirmenu; // ditto size_t dir_on[menudepth]; UINT8 refreshdirmenu = 0; @@ -446,7 +446,7 @@ char exttable[NUM_EXT_TABLE][5] = { char filenamebuf[MAX_WADFILES][MAX_WADPATH]; -static boolean filemenusearch(char *haystack, char *needle) +static boolean filemenucmp(char *haystack, char *needle) { static char localhaystack[128]; strlcpy(localhaystack, haystack, 128); @@ -457,21 +457,126 @@ static boolean filemenusearch(char *haystack, char *needle) : (!strncmp(localhaystack, needle, menusearch[0]))); } -#define searchdir if (menusearch[0] && !filemenusearch(dent->d_name, localmenusearch))\ - {\ - rejected++;\ - continue;\ - }\ +void closefilemenu(boolean validsize) +{ + // search + if (dirmenu) + { + if (dirmenu != coredirmenu) + { + if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS)) + { + Z_Free(dirmenu[0]); + dirmenu[0] = NULL; + } + Z_Free(dirmenu); + } + dirmenu = NULL; + sizedirmenu = 0; + } + + if (coredirmenu) + { + // core + if (validsize) + { + for (; sizecoredirmenu > 0; sizecoredirmenu--) + { + Z_Free(coredirmenu[sizecoredirmenu-1]); + coredirmenu[sizecoredirmenu-1] = NULL; + } + } + else + sizecoredirmenu = 0; + + Z_Free(coredirmenu); + coredirmenu = NULL; + } +} + +void searchfilemenu(char *tempname) +{ + size_t i, first; + char localmenusearch[MAXSTRINGLENGTH] = ""; + + if (dirmenu) + { + if (dirmenu != coredirmenu) + { + if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS)) + { + Z_Free(dirmenu[0]); + dirmenu[0] = NULL; + } + //Z_Free(dirmenu); -- Z_Realloc later tho... + } + else + dirmenu = NULL; + } + + if (!menusearch[0]) + { + if (dirmenu) + Z_Free(dirmenu); + dirmenu = coredirmenu; + sizedirmenu = sizecoredirmenu; + if (tempname) + Z_Free(tempname); + return; + } + + strcpy(localmenusearch, menusearch+1); + if (!cv_addons_search_case.value) + strupr(localmenusearch); + + first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP... + + sizedirmenu = 0; + for (i = first; i < sizecoredirmenu; i++) + { + if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch)) + sizedirmenu++; + } + + if (!sizedirmenu) // no results... + { + if ((!(dirmenu = Z_Realloc(dirmenu, sizeof(char *), PU_STATIC, NULL))) + || !(dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)))) + I_Error("Ran out of memory whilst preparing add-ons menu"); + sizedirmenu = 1; + if (tempname) + Z_Free(tempname); + return; + } + + if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL))) + I_Error("Ran out of memory whilst preparing add-ons menu"); + + sizedirmenu = 0; + for (i = first; i < sizecoredirmenu; i++) + { + if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch)) + { + dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse + if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname)) + dir_on[menudepthleft] = i; + } + } + + if (dir_on[menudepthleft] >= sizedirmenu) + dir_on[menudepthleft] = sizedirmenu-1; + + if (tempname) + Z_Free(tempname); +} boolean preparefilemenu(boolean samedepth) { DIR *dirhandle; struct dirent *dent; struct stat fsstat; - size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0; + size_t pos = 0, folderpos = 0, numfolders = 0; char *tempname = NULL; - boolean noresults = false; - char localmenusearch[MAXSTRINGLENGTH] = ""; if (samedepth) { @@ -481,20 +586,16 @@ boolean preparefilemenu(boolean samedepth) else menusearch[0] = menusearch[1] = 0; // clear search - for (; sizedirmenu > 0; sizedirmenu--) // clear out existing items + if (!(dirhandle = opendir(menupath))) // get directory { - Z_Free(dirmenu[sizedirmenu-1]); - dirmenu[sizedirmenu-1] = NULL; + closefilemenu(true); + return false; } - if (!(dirhandle = opendir(menupath))) // get directory - return false; - - if (menusearch[0]) + for (; sizecoredirmenu > 0; sizecoredirmenu--) // clear out existing items { - strcpy(localmenusearch, menusearch+1); - if (!cv_addons_search_case.value) - strupr(localmenusearch); + Z_Free(coredirmenu[sizecoredirmenu-1]); + coredirmenu[sizecoredirmenu-1] = NULL; } while (true) @@ -526,43 +627,42 @@ boolean preparefilemenu(boolean samedepth) if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file } - searchdir; } else // directory - { - searchdir; numfolders++; - } - sizedirmenu++; + + sizecoredirmenu++; } } - if (!rejected && !sizedirmenu) + if (!sizecoredirmenu) { + closedir(dirhandle); + closefilemenu(false); if (tempname) Z_Free(tempname); - closedir(dirhandle); return false; } - if (((noresults = (menusearch[0] && !sizedirmenu))) - || (!menusearch[0] && menudepthleft != menudepth-1)) // Make room for UP... or search entry + if (menudepthleft != menudepth-1) // Make room for UP... { - sizedirmenu++; + sizecoredirmenu++; numfolders++; folderpos++; } - if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL))) + if (dirmenu && dirmenu == coredirmenu) + dirmenu = NULL; + + if (!(coredirmenu = Z_Realloc(coredirmenu, sizecoredirmenu*sizeof(char *), PU_STATIC, NULL))) { closedir(dirhandle); // just in case I_Error("Ran out of memory whilst preparing add-ons menu"); } - rejected = 0; rewinddir(dirhandle); - while ((pos+folderpos) < sizedirmenu) + while ((pos+folderpos) < sizecoredirmenu) { menupath[menupathindex[menudepthleft]] = 0; dent = readdir(dirhandle); @@ -588,14 +688,12 @@ boolean preparefilemenu(boolean samedepth) if (!S_ISDIR(fsstat.st_mode)) // file { - if (!((numfolders+pos) < sizedirmenu)) continue; // crash prevention + if (!((numfolders+pos) < sizecoredirmenu)) continue; // crash prevention for (; ext < NUM_EXT_TABLE; ext++) if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file ext += EXT_START; // moving to be appropriate position - searchdir; - if (ext >= EXT_LOADSTART) { size_t i; @@ -628,10 +726,7 @@ boolean preparefilemenu(boolean samedepth) folder = 0; } else // directory - { - searchdir; len += (folder = 1); - } if (len > 255) len = 255; @@ -644,45 +739,30 @@ boolean preparefilemenu(boolean samedepth) if (folder) { strcpy(temp+len, "/"); - dirmenu[folderpos++] = temp; + coredirmenu[folderpos++] = temp; } else - dirmenu[numfolders + pos++] = temp; + coredirmenu[numfolders + pos++] = temp; } } closedir(dirhandle); - if (noresults) // no results - dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)); - else if (!menusearch[0] &&menudepthleft != menudepth-1) // now for UP... entry - dirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP)); + if ((menudepthleft != menudepth-1) // now for UP... entry + && !(coredirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP)))) + I_Error("Ran out of memory whilst preparing add-ons menu"); menupath[menupathindex[menudepthleft]] = 0; - sizedirmenu = (numfolders+pos); // just in case things shrink between opening and rewind + sizecoredirmenu = (numfolders+pos); // just in case things shrink between opening and rewind - if (tempname) - { - size_t i; - for (i = 0; i < sizedirmenu; i++) - { - if (!strcmp(dirmenu[i]+DIR_STRING, tempname)) - { - dir_on[menudepthleft] = i; - break; - } - } - Z_Free(tempname); - } - - if (!sizedirmenu) + if (!sizecoredirmenu) { dir_on[menudepthleft] = 0; - Z_Free(dirmenu); + closefilemenu(false); return false; } - else if (dir_on[menudepthleft] >= sizedirmenu) - dir_on[menudepthleft] = sizedirmenu-1; + + searchfilemenu(tempname); return true; } diff --git a/src/filesrch.h b/src/filesrch.h index e88242698..4cfa40e6c 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -87,6 +87,8 @@ typedef enum REFRESHDIR_MAX = 32 } refreshdir_enum; +void closefilemenu(boolean validsize); +void searchfilemenu(char *tempname); boolean preparefilemenu(boolean samedepth); #endif // __FILESRCH_H__ diff --git a/src/m_menu.c b/src/m_menu.c index 5258f4b44..d23d5640f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5048,13 +5048,11 @@ static void M_DrawAddons(void) x -= (21 + 5 + 16); V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]); -#define CANSAVE (!modifiedgame || savemoddata) x = BASEVIDWIDTH - x - 16; - V_DrawSmallScaledPatch(x, y + 4, (CANSAVE ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]); + V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]); if (modifiedgame) V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]); -#undef CANSAVE } #ifdef FIXUPO0 @@ -5119,11 +5117,15 @@ static void M_HandleAddons(INT32 choice) if (M_ChangeStringAddons(choice)) { - if (!preparefilemenu(true)) + char *tempname = NULL; + if (dirmenu && dirmenu[dir_on[menudepthleft]]) + tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL + searchfilemenu(tempname); + /*if (!preparefilemenu(true)) { UNEXIST; return; - } + }*/ } switch (choice) @@ -5242,14 +5244,7 @@ static void M_HandleAddons(INT32 choice) } if (exitmenu) { - for (; sizedirmenu > 0; sizedirmenu--) - { - Z_Free(dirmenu[sizedirmenu-1]); - dirmenu[sizedirmenu-1] = NULL; - } - - Z_Free(dirmenu); - dirmenu = NULL; + closefilemenu(true); // secrets disabled by addfile... MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); From 247f3e9b03e6e55bc02eae5df76fa75ea636ca3c Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 18 Jun 2018 11:22:57 +0100 Subject: [PATCH 09/20] Improve the tempname position-keeping behaviour significantly, hammering out a potential crash bug too. --- src/filesrch.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index 3e1e5891a..b80681306 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -514,14 +514,32 @@ void searchfilemenu(char *tempname) dirmenu = NULL; } + first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP... + if (!menusearch[0]) { if (dirmenu) Z_Free(dirmenu); dirmenu = coredirmenu; sizedirmenu = sizecoredirmenu; + if (tempname) + { + for (i = first; i < sizedirmenu; i++) + { + if (!strcmp(dirmenu[i]+DIR_STRING, tempname)) + { + dir_on[menudepthleft] = i; + break; + } + } + + if (i == sizedirmenu) + dir_on[menudepthleft] = first; + Z_Free(tempname); + } + return; } @@ -529,8 +547,6 @@ void searchfilemenu(char *tempname) if (!cv_addons_search_case.value) strupr(localmenusearch); - first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP... - sizedirmenu = 0; for (i = first; i < sizecoredirmenu; i++) { @@ -544,6 +560,7 @@ void searchfilemenu(char *tempname) || !(dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS)))) I_Error("Ran out of memory whilst preparing add-ons menu"); sizedirmenu = 1; + dir_on[menudepthleft] = 0; if (tempname) Z_Free(tempname); return; @@ -557,17 +574,21 @@ void searchfilemenu(char *tempname) { if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch)) { - dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname)) - dir_on[menudepthleft] = i; + { + dir_on[menudepthleft] = sizedirmenu; + Z_Free(tempname); + tempname = NULL; + } + dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse } } - if (dir_on[menudepthleft] >= sizedirmenu) - dir_on[menudepthleft] = sizedirmenu-1; - if (tempname) + { + dir_on[menudepthleft] = first; Z_Free(tempname); + } } boolean preparefilemenu(boolean samedepth) From 00d75840b662931efcca5f464dd98a4bdfbb7382 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 18 Jun 2018 12:49:06 +0100 Subject: [PATCH 10/20] Not necessary on-topic devwork, but using global variables I developed in internal to make there less code repetition/iteration in the WAD limit checks. --- src/d_netcmd.c | 36 +++++++----------------------------- src/d_netfil.c | 9 ++------- src/w_wad.c | 4 +--- 3 files changed, 10 insertions(+), 39 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e01178155..89f01c161 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3081,26 +3081,14 @@ static void Command_Addfile(void) if (*p == '\\' || *p == '/' || *p == ':') break; ++p; + // check total packet size and no of files currently loaded + // See W_LoadWadFile in w_wad.c + if ((numwadfiles >= MAX_WADFILES) + || ((packetsizetally + nameonlylength(fn) + 22) > MAXFILENEEDED*sizeof(UINT8))) { - size_t packetsize = 0; - serverinfo_pak *dummycheck = NULL; - - // Shut the compiler up. - (void)dummycheck; - - // See W_LoadWadFile in w_wad.c - for (i = 0; i < numwadfiles; i++) - packetsize += nameonlylength(wadfiles[i]->filename) + 22; - - packetsize += nameonlylength(fn) + 22; - - if ((numwadfiles >= MAX_WADFILES) - || (packetsize > sizeof(dummycheck->fileneeded))) - { - CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); - return; - } + CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); + return; } WRITESTRINGN(buf_p,p,240); @@ -3150,11 +3138,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) boolean kick = false; boolean toomany = false; INT32 i; - size_t packetsize = 0; - serverinfo_pak *dummycheck = NULL; - - // Shut the compiler up. - (void)dummycheck; READSTRINGN(*cp, filename, 240); READMEM(*cp, md5sum, 16); @@ -3181,13 +3164,8 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) } // See W_LoadWadFile in w_wad.c - for (i = 0; i < numwadfiles; i++) - packetsize += nameonlylength(wadfiles[i]->filename) + 22; - - packetsize += nameonlylength(filename) + 22; - if ((numwadfiles >= MAX_WADFILES) - || (packetsize > sizeof(dummycheck->fileneeded))) + || ((packetsizetally + nameonlylength(filename) + 22) > MAXFILENEEDED*sizeof(UINT8))) toomany = true; else ncs = findfile(filename,md5sum,true); diff --git a/src/d_netfil.c b/src/d_netfil.c index 889de9466..ea95153b9 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -324,10 +324,6 @@ INT32 CL_CheckFiles(void) INT32 ret = 1; size_t packetsize = 0; size_t filestoget = 0; - serverinfo_pak *dummycheck = NULL; - - // Shut the compiler up. - (void)dummycheck; // if (M_CheckParm("-nofiles")) // return 1; @@ -371,8 +367,7 @@ INT32 CL_CheckFiles(void) } // See W_LoadWadFile in w_wad.c - for (i = 0; i < numwadfiles; i++) - packetsize += nameonlylength(wadfiles[i]->filename) + 22; + packetsize = packetsizetally; for (i = 1; i < fileneedednum; i++) { @@ -396,7 +391,7 @@ INT32 CL_CheckFiles(void) packetsize += nameonlylength(fileneeded[i].filename) + 22; if ((numwadfiles+filestoget >= MAX_WADFILES) - || (packetsize > sizeof(dummycheck->fileneeded))) + || (packetsize > MAXFILENEEDED*sizeof(UINT8))) return 3; filestoget++; diff --git a/src/w_wad.c b/src/w_wad.c index 1b0e501a6..46caef847 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -360,9 +360,7 @@ UINT16 W_InitFile(const char *filename) // see PutFileNeeded in d_netfil.c if ((important = !W_VerifyNMUSlumps(filename))) { - packetsize = packetsizetally; - - packetsize += nameonlylength(filename) + 22; + packetsize = packetsizetally + nameonlylength(filename) + 22; if (packetsize > MAXFILENEEDED*sizeof(UINT8)) { From bd3e9cc067d3cba347ccd2bbdb84968b161087f3 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 18 Jun 2018 16:55:34 +0100 Subject: [PATCH 11/20] Major refinement of Add-ons menu! * Kill addonsresponselimit, which was a hacky solution to a stupid problem. Instead... * Allocate and consistently handle memory to store the name of an added file so we can reference it directly. * Replace the choice between ./ and a custom folder with the full, standard assortment of Default (usehome ? SRB2HOME : SRB2PATH), HOME (SRB2HOME), SRB2 (SRB2PATH) or Custom (cv_addons_folder.string). * Make these render as the name plus folder, since you can't go UP... from the top level. * Make the path seperators consistently system-based re PATHSEP. (Quite frankly, I'm surprised it even worked in the first place...) --- src/d_netcmd.c | 6 ++++ src/d_netfil.c | 9 +++--- src/filesrch.c | 24 ++++++++++----- src/filesrch.h | 1 + src/m_menu.c | 79 +++++++++++++++++++++++++------------------------- src/w_wad.c | 10 +++++++ 6 files changed, 79 insertions(+), 50 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 89f01c161..2ab0548a0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3318,6 +3318,9 @@ static void Command_Playintro_f(void) if (netgame) return; + if (dirmenu) + closefilemenu(true); + F_StartIntro(); } @@ -4076,6 +4079,9 @@ void Command_ExitGame_f(void) cv_debug = 0; emeralds = 0; + if (dirmenu) + closefilemenu(true); + if (!modeattacking) D_StartTitle(); } diff --git a/src/d_netfil.c b/src/d_netfil.c index ea95153b9..e43ad77e2 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -894,10 +894,11 @@ void nameonly(char *s) { ns = &(s[j+1]); len = strlen(ns); - if (false) - M_Memcpy(s, ns, len+1); - else - memmove(s, ns, len+1); +#if 0 + M_Memcpy(s, ns, len+1); +#else + memmove(s, ns, len+1); +#endif return; } } diff --git a/src/filesrch.c b/src/filesrch.c index b80681306..fe3fe240c 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -306,9 +306,14 @@ closedir (DIR * dirp) } #endif -static CV_PossibleValue_t addons_cons_t[] = {{0, "SRB2 Folder"}, /*{1, "HOME"}, {2, "SRB2 Folder"},*/ {3, "CUSTOM"}, {0, NULL}}; -consvar_t cv_addons_option = {"addons_option", "SRB2 Folder", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_addons_folder = {"addons_folder", "./", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"}, +#if 1 + {1, "HOME"}, {2, "SRB2"}, +#endif + {3, "CUSTOM"}, {0, NULL}}; + +consvar_t cv_addons_option = {"addons_option", "Default", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_addons_folder = {"addons_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Contents"}, {0, NULL}}; consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -330,6 +335,7 @@ char **dirmenu, **coredirmenu; // core only local for this file size_t sizedirmenu, sizecoredirmenu; // ditto size_t dir_on[menudepth]; UINT8 refreshdirmenu = 0; +char *refreshdirname = NULL; size_t packetsizetally = 0; size_t mainwadstally = 0; @@ -362,9 +368,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want return FS_NOTFOUND; } - if (searchpath[searchpathindex[depthleft]-2] != '/') + if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0]) { - searchpath[searchpathindex[depthleft]-1] = '/'; + searchpath[searchpathindex[depthleft]-1] = PATHSEP[0]; searchpath[searchpathindex[depthleft]] = 0; } else @@ -406,7 +412,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want depthleft++; } - searchpath[searchpathindex[depthleft]-1]='/'; + searchpath[searchpathindex[depthleft]-1]=PATHSEP[0]; searchpath[searchpathindex[depthleft]]=0; } else if (!strcasecmp(searchname, dent->d_name)) @@ -492,6 +498,10 @@ void closefilemenu(boolean validsize) Z_Free(coredirmenu); coredirmenu = NULL; } + + if (refreshdirname) + Z_Free(refreshdirname); + refreshdirname = NULL; } void searchfilemenu(char *tempname) @@ -759,7 +769,7 @@ boolean preparefilemenu(boolean samedepth) strlcpy(temp+DIR_STRING, dent->d_name, len); if (folder) { - strcpy(temp+len, "/"); + strcpy(temp+len, PATHSEP); coredirmenu[folderpos++] = temp; } else diff --git a/src/filesrch.h b/src/filesrch.h index 4cfa40e6c..41dc80d13 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -40,6 +40,7 @@ extern char **dirmenu; extern size_t sizedirmenu; extern size_t dir_on[menudepth]; extern UINT8 refreshdirmenu; +extern char *refreshdirname; extern size_t packetsizetally; extern size_t mainwadstally; diff --git a/src/m_menu.c b/src/m_menu.c index d23d5640f..bdeee16ed 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -341,7 +341,6 @@ static void M_EraseData(INT32 choice); static void M_Addons(INT32 choice); static void M_AddonsOptions(INT32 choice); static patch_t *addonsp[NUM_EXT+6]; -static UINT8 addonsresponselimit = 0; #define numaddonsshown 4 @@ -2110,15 +2109,19 @@ static void M_GoBack(INT32 choice) if (!Playing() && netgame && multiplayer) { MSCloseUDPSocket(); // Clean up so we can re-open the connection later. - netgame = false; - multiplayer = false; + netgame = multiplayer = false; } if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef)) { // D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate. - Z_Free(levelselect.rows); - levelselect.rows = NULL; + + if (levelselect.rows) + { + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } + menuactive = false; D_StartTitle(); } @@ -4759,22 +4762,24 @@ static void M_Addons(INT32 choice) (void)choice; - /*if (cv_addons_option.value == 0) - pathname = srb2home; usehome ? srb2home : srb2path; +#if 1 + if (cv_addons_option.value == 0) + pathname = usehome ? srb2home : srb2path; else if (cv_addons_option.value == 1) pathname = srb2home; else if (cv_addons_option.value == 2) pathname = srb2path; - else*/ + else +#endif if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0') pathname = cv_addons_folder.string; strlcpy(menupath, pathname, 1024); menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1; - if (menupath[menupathindex[menudepthleft]-2] != '/') + if (menupath[menupathindex[menudepthleft]-2] != PATHSEP[0]) { - menupath[menupathindex[menudepthleft]-1] = '/'; + menupath[menupathindex[menudepthleft]-1] = PATHSEP[0]; menupath[menupathindex[menudepthleft]] = 0; } else @@ -4868,11 +4873,7 @@ static char *M_AddonsHeaderPath(void) UINT32 len; static char header[1024]; - if (menupath[0] == '.') - strlcpy(header, va("SRB2 folder%s", menupath+1), 1024); - else - strcpy(header, menupath); - + strlcpy(header, va("%s folder%s", cv_addons_option.string, menupath+menupathindex[menudepth-1]-1), 1024); len = strlen(header); if (len > 34) { @@ -4889,6 +4890,15 @@ static char *M_AddonsHeaderPath(void) M_SetupNextMenu(MISC_AddonsDef.prevMenu);\ M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING) +#define CLEARNAME Z_Free(refreshdirname);\ + refreshdirname = NULL + +static void M_AddonsClearName(INT32 choice) +{ + CLEARNAME; + M_StopMessage(choice); +} + // returns whether to do message draw static boolean M_AddonsRefresh(void) { @@ -4900,35 +4910,35 @@ static boolean M_AddonsRefresh(void) if (refreshdirmenu & REFRESHDIR_ADDFILE) { - addonsresponselimit = 0; + char *message = NULL; if (refreshdirmenu & REFRESHDIR_NOTLOADED) { - char *message = NULL; S_StartSound(NULL, sfx_lose); if (refreshdirmenu & REFRESHDIR_MAX) - message = va("\x82%s\x80\nMaximum number of add-ons reached.\nThis file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); + message = va("\x82%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", refreshdirname); else - message = va("\x82%s\x80\nThe file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); - M_StartMessage(message,NULL,MM_NOTHING); - return true; + message = va("\x82%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", refreshdirname); } - - if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR)) + else if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR)) { S_StartSound(NULL, sfx_skid); - M_StartMessage(va("\x82%s\x80\nThe file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")),NULL,MM_NOTHING); + message = va("\x82%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")); + } + + if (message) + { + M_StartMessage(message,M_AddonsClearName,MM_EVENTHANDLER); return true; } S_StartSound(NULL, sfx_strpst); + CLEARNAME; } return false; } -#define offs 1 - #ifdef FIXUPO0 #pragma GCC optimize ("0") #endif @@ -4945,10 +4955,7 @@ static void M_DrawAddons(void) return; } - if (addonsresponselimit) - addonsresponselimit--; - - V_DrawCenteredString(BASEVIDWIDTH/2, 4+offs, 0, (Playing() + V_DrawCenteredString(BASEVIDWIDTH/2, 5, 0, (Playing() ? "\x85""Adding files mid-game may cause problems." : LOCATIONSTRING)); @@ -4970,7 +4977,7 @@ static void M_DrawAddons(void) // DRAW MENU x = currentMenu->x; - y = currentMenu->y + offs; + y = currentMenu->y + 1; //M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true, true); -- wanted different width V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), V_YELLOWMAP|V_ALLOWLOWERCASE, M_AddonsHeaderPath()); @@ -4978,7 +4985,7 @@ static void M_DrawAddons(void) V_DrawFill(x-21 + (MAXSTRINGLENGTH*8+6 - 1), (y - 16) + (lsheadingheight - 3), 1, 1, 26); V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 26); - V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 1 + offs) - (y - 1), 159); + V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 2) - (y - 1), 159); // get bottom... max = dir_on[menudepthleft] + numaddonsshown + 1; @@ -5034,7 +5041,7 @@ static void M_DrawAddons(void) if (max != (ssize_t)sizedirmenu) V_DrawString(19, y-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B"); - y = BASEVIDHEIGHT - currentMenu->y + offs; + y = BASEVIDHEIGHT - currentMenu->y + 1; M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1); if (menusearch[0]) @@ -5059,8 +5066,6 @@ static void M_DrawAddons(void) #pragma GCC reset_options #endif -#undef offs - static void M_AddonExec(INT32 ch) { if (ch != 'y' && ch != KEY_ENTER) @@ -5112,9 +5117,6 @@ static void M_HandleAddons(INT32 choice) { boolean exitmenu = false; // exit to previous menu - if (addonsresponselimit) - return; - if (M_ChangeStringAddons(choice)) { char *tempname = NULL; @@ -5224,7 +5226,6 @@ static void M_HandleAddons(INT32 choice) case EXT_WAD: case EXT_PK3: COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING)); - addonsresponselimit = 5; break; default: S_StartSound(NULL, sfx_lose); diff --git a/src/w_wad.c b/src/w_wad.c index 46caef847..320b65a3c 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -340,6 +340,16 @@ UINT16 W_InitFile(const char *filename) if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier + if (refreshdirname) + Z_Free(refreshdirname); + if (dirmenu) + { + refreshdirname = Z_StrDup(filename); + nameonly(refreshdirname); + } + else + refreshdirname = NULL; + //CONS_Debug(DBG_SETUP, "Loading %s\n", filename); // // check if limit of active wadfiles From f18cfb11f3116a487e0ea25e9e482834dbe0f16f Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 18 Jun 2018 17:39:34 +0100 Subject: [PATCH 12/20] Some cvar fudging. * Turn off mlook and mousemove by default, as requested by Prime/Mystic. * Change all the analog cvar names (and hide them from the help function so they aren't so easily rediscovered) to invalidate 2.1-era copies of config.cfg, given I've seen a common sentiment is that they won't try the new controls at all and will just copy their old ones across, and I'd like to sabotage the deprecated feature. --- src/g_game.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 4e3e5f0c7..da3b38b56 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -320,19 +320,21 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_alwaysfreelook = {"alwaysmlook", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_alwaysfreelook = {"alwaysmlook", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_invertmouse2 = {"invertmouse2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_alwaysfreelook2 = {"alwaysmlook2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_mousemove = {"mousemove", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_mousemove2 = {"mousemove2", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_analog = {"analog", "Off", CV_CALL, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mousemove = {"mousemove", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mousemove2 = {"mousemove2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}}; +// previously "analog", "analog2", "useranalog", and "useranalog2", invalidating 2.1-era copies of config.cfg +// changed because it'd be nice to see people try out our actually good controls with gamepads now autobrake exists +consvar_t cv_analog = {"sessionanalog", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_analog2 = {"sessionanalog2", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_useranalog = {"configanalog", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_useranalog2 = {"configanalog2", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; // deez New User eXperiences +static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}}; consvar_t cv_directionchar = {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL}; From 73a66d22dfceb789acd589cb1177a83dd5c5deab Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 28 Aug 2018 20:57:43 +0100 Subject: [PATCH 13/20] At toaster's suggestion, have 2p control whether closed captioning is moved up if the powerup display is 1st person only --- src/screen.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/screen.c b/src/screen.c index afeffbdaa..8fc554cc8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -451,8 +451,11 @@ void SCR_ClosedCaptions(void) basey -= 8; else if ((modeattacking == ATTACKING_NIGHTS) || (!(maptol & TOL_NIGHTS) - && ((cv_powerupdisplay.value == 2) - || (cv_powerupdisplay.value == 1 && !splitscreen && !camera.chase)))) + && ((cv_powerupdisplay.value == 2) // "Always" + || (cv_powerupdisplay.value == 1 // "First-person only" + && ((!splitscreen && !camera.chase) + || (splitscreen && !camera2.chase)) // in 2p mode, move up only if 2p's powerup display is on + )))) basey -= 16; } From 7db7a739d470291d29e870a68d8fbbc1dcc5109f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 29 Aug 2018 21:31:15 +0100 Subject: [PATCH 14/20] Use INFLIVES macro in place of 0x7f for infinite lives check --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 74acb7594..d3d8eeb25 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1914,7 +1914,7 @@ void G_Ticker(boolean run) else { // Costs a life to retry ... unless the player in question is dead already. - if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != 0x7f) + if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) players[consoleplayer].lives -= 1; G_DoReborn(consoleplayer); From ceb0abb0814eb3d189e90fa36792eb4e4b148ea0 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 29 Aug 2018 22:07:38 +0100 Subject: [PATCH 15/20] Fix compiler complaints, remove a slipup of mine from when I was dealing with merge conflicts --- src/d_main.c | 2 +- src/m_menu.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c71446398..a2a51d3ff 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -283,7 +283,7 @@ static void D_Display(void) if (rendermode != render_none) { // Fade to black first - if ((wipegamestate != -2) // fades to black on its own timing, always + if ((wipegamestate != (gamestate_t)-2) // fades to black on its own timing, always && wipedefs[wipedefindex] != UINT8_MAX) { F_WipeStartScreen(); diff --git a/src/m_menu.c b/src/m_menu.c index 956748f1c..ce82cb69b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4956,9 +4956,6 @@ static void M_DrawAddons(void) return; } - if (addonsresponselimit) - addonsresponselimit--; - if (Playing()) topstr = "\x85""Adding files mid-game may cause problems."; else if (savemoddata) From 4083ee9df748fe4268882ab9a54be85ca89f4cae Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 30 Aug 2018 20:08:17 +0100 Subject: [PATCH 16/20] Apparently I am blind and missed that splitscreen only CC offset that overrides the code for the other offset below --- src/screen.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/screen.c b/src/screen.c index 8fc554cc8..20b7134a1 100644 --- a/src/screen.c +++ b/src/screen.c @@ -452,10 +452,7 @@ void SCR_ClosedCaptions(void) else if ((modeattacking == ATTACKING_NIGHTS) || (!(maptol & TOL_NIGHTS) && ((cv_powerupdisplay.value == 2) // "Always" - || (cv_powerupdisplay.value == 1 // "First-person only" - && ((!splitscreen && !camera.chase) - || (splitscreen && !camera2.chase)) // in 2p mode, move up only if 2p's powerup display is on - )))) + || (cv_powerupdisplay.value == 1 && !camera.chase)))) // "First-person only" basey -= 16; } From 6a6d32e7c2205e31fece4f202c75b3ed7cbd5a43 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 23 Sep 2018 14:17:29 +0100 Subject: [PATCH 17/20] searchfilemenu: Replace first with 0 here as toaster suggested --- src/filesrch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filesrch.c b/src/filesrch.c index fe3fe240c..c1abccde3 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -596,7 +596,7 @@ void searchfilemenu(char *tempname) if (tempname) { - dir_on[menudepthleft] = first; + dir_on[menudepthleft] = 0; Z_Free(tempname); } } From 8a9c10e633bae292c14e0f44d6a2e60787596c4a Mon Sep 17 00:00:00 2001 From: mazmazz Date: Tue, 20 Nov 2018 23:43:05 -0500 Subject: [PATCH 18/20] Hardcode Pause/Break key and change Pause default; show prompt in menu about Pause key --- src/g_game.c | 3 ++- src/g_input.c | 2 +- src/m_menu.c | 24 ++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 95a76b95d..f7e7ae75a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1800,7 +1800,8 @@ boolean G_Responder(event_t *ev) { case ev_keydown: if (ev->data1 == gamecontrol[gc_pause][0] - || ev->data1 == gamecontrol[gc_pause][1]) + || ev->data1 == gamecontrol[gc_pause][1] + || ev->data1 == KEY_PAUSE) { if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { diff --git a/src/g_input.c b/src/g_input.c index 4f7296cd5..e17e359a7 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -709,7 +709,7 @@ void G_DefineDefaultControls(void) gamecontroldefault[i][gc_teamkey ][0] = 'y'; gamecontroldefault[i][gc_scores ][0] = KEY_TAB; gamecontroldefault[i][gc_console ][0] = KEY_CONSOLE; - gamecontroldefault[i][gc_pause ][0] = KEY_PAUSE; + gamecontroldefault[i][gc_pause ][0] = 'p'; } } diff --git a/src/m_menu.c b/src/m_menu.c index 46a7d94fc..ae868762a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9380,6 +9380,7 @@ static void M_DrawControl(void) #undef controlbuffer static INT32 controltochange; +static char controltochangetext[55]; static void M_ChangecontrolResponse(event_t *ev) { @@ -9387,8 +9388,8 @@ static void M_ChangecontrolResponse(event_t *ev) INT32 found; INT32 ch = ev->data1; - // ESCAPE cancels - if (ch != KEY_ESCAPE) + // ESCAPE cancels; dummy out PAUSE + if (ch != KEY_ESCAPE && ch != KEY_PAUSE) { switch (ev->type) @@ -9449,6 +9450,24 @@ static void M_ChangecontrolResponse(event_t *ev) } S_StartSound(NULL, sfx_strpst); } + else if (ch == KEY_PAUSE) + { + static char tmp[155]; + menu_t *prev = currentMenu->prevMenu; + + if (controltochange == gc_pause) + sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit cannot be used to retry runs \nduring Record Attack. \n\nHit another key for\n%s\nESC for Cancel"), + controltochangetext); + else + sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"), + controltochangetext); + + M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); + currentMenu->prevMenu = prev; + + S_StartSound(NULL, sfx_s3k42); + return; + } else S_StartSound(NULL, sfx_skid); @@ -9465,6 +9484,7 @@ static void M_ChangeControl(INT32 choice) controltochange = currentMenu->menuitems[choice].alphaKey; sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"), currentMenu->menuitems[choice].text); + strncpy(controltochangetext, currentMenu->menuitems[choice].text, 55); M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); } From 2acad7ad86a60d57fa9458e34e8824910e9fcc93 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 21 Nov 2018 11:10:18 -0500 Subject: [PATCH 19/20] Dont show Hold to Retry HUD when using Pause/Break key --- src/g_game.c | 2 ++ src/g_game.h | 1 + src/hu_stuff.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index f7e7ae75a..79c09f6b1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1653,6 +1653,7 @@ void G_DoLoadLevel(boolean resetplayer) } INT32 pausedelay = 0; +boolean pausebreakkey = false; static INT32 camtoggledelay, camtoggledelay2 = 0; // @@ -1805,6 +1806,7 @@ boolean G_Responder(event_t *ev) { if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { + pausebreakkey = (ev->data1 == KEY_PAUSE); if (menuactive || pausedelay < 0 || leveltime < 2) return true; diff --git a/src/g_game.h b/src/g_game.h index dc0c3619d..1e30831d8 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -54,6 +54,7 @@ extern INT32 gameovertics; extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) extern INT16 rw_maximums[NUM_WEAPONS]; extern INT32 pausedelay; +extern boolean pausebreakkey; // used in game menu extern consvar_t cv_tutorialprompt; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 26e50885a..6e17b939d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1132,7 +1132,7 @@ void HU_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text); } - if (modeattacking && pausedelay > 0) + if (modeattacking && pausedelay > 0 && !pausebreakkey) { INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3); INT32 y = hudinfo[HUD_LIVES].y - 13; From 9bdab67de6b46276f5449eb7866c90fc70177a9e Mon Sep 17 00:00:00 2001 From: mazmazz Date: Wed, 21 Nov 2018 11:21:17 -0500 Subject: [PATCH 20/20] Don't accept KEY_PAUSE for control console command --- src/g_input.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/g_input.c b/src/g_input.c index e17e359a7..2988d7c37 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -814,6 +814,8 @@ static void setcontrol(INT32 (*gc)[2], INT32 na) return; } keynum = G_KeyStringtoNum(COM_Argv(2)); + if (keynum == KEY_PAUSE) // fail silently; pause is hardcoded + return; G_CheckDoubleUsage(keynum); gc[numctrl][0] = keynum;