diff --git a/src/console.c b/src/console.c index 3a6e4729d..a504af06d 100644 --- a/src/console.c +++ b/src/console.c @@ -1619,6 +1619,8 @@ void CON_Drawer(void) if (con_curlines > 0) CON_DrawConsole(); - else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE || gamestate == GS_CREDITS) + else if (gamestate == GS_LEVEL + || gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE + || gamestate == GS_CREDITS || gamestate == GS_EVALUATION) CON_DrawHudlines(); } diff --git a/src/d_main.c b/src/d_main.c index 21f6055a2..45f9d6763 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -340,6 +340,7 @@ static void D_Display(void) case GS_EVALUATION: F_GameEvaluationDrawer(); + HU_Erase(); HU_Drawer(); break; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b9c53a1b7..545f2da11 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -195,8 +195,6 @@ static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Mystery"}, static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}}; -static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Tics"}, {2, "Centiseconds"}, {0, NULL}}; - #ifdef NETGAME_DEVMODE static consvar_t cv_fishcake = {"fishcake", "Off", CV_CALL|CV_NOSHOWHELP|CV_RESTRICT, CV_OnOff, Fishcake_OnChange, 0, NULL, NULL, 0, 0, NULL}; #endif @@ -307,6 +305,7 @@ consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Tics"}, {2, "Centiseconds"}, {3, "Mania"}, {0, NULL}}; consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3885,7 +3884,28 @@ static void Command_ExitLevel_f(void) else if (gamestate != GS_LEVEL || demoplayback) CONS_Printf(M_GetText("You must be in a level to use this.\n")); else + { + if ((netgame || multiplayer) + && ((mapheaderinfo[gamemap-1]->nextlevel <= 0) + || (mapheaderinfo[gamemap-1]->nextlevel > NUMMAPS) + || !(mapvisited[mapheaderinfo[gamemap-1]->nextlevel-1]))) + { + UINT8 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].exiting) + break; + } + + if (i == MAXPLAYERS) + { + CONS_Printf(M_GetText("Someone must finish the level for you to use this.\n")); + return; + } + } + SendNetXCmd(XD_EXITLEVEL, NULL, 0); + } } static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) diff --git a/src/dehacked.c b/src/dehacked.c index 0e2b8b4f4..764b37885 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7337,7 +7337,6 @@ struct { {"V_70TRANS",V_70TRANS}, {"V_80TRANS",V_80TRANS}, {"V_90TRANS",V_90TRANS}, - {"V_STATIC",V_STATIC}, {"V_HUDTRANSHALF",V_HUDTRANSHALF}, {"V_HUDTRANS",V_HUDTRANS}, {"V_HUDTRANSDOUBLE",V_HUDTRANSDOUBLE}, diff --git a/src/doomstat.h b/src/doomstat.h index 51d385203..18fe92086 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -385,6 +385,7 @@ extern recorddata_t *mainrecords[NUMMAPS]; #define MV_ULTIMATE 8 #define MV_PERFECT 16 #define MV_MAX 31 // used in gamedata check +#define MV_MP 128 extern UINT8 mapvisited[NUMMAPS]; // Temporary holding place for nights data for the current map diff --git a/src/g_game.c b/src/g_game.c index df2ba5baa..86062ef58 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1751,7 +1751,6 @@ boolean G_Responder(event_t *ev) return true; } } - else if (gamestate == GS_CREDITS) { if (HU_Responder(ev)) @@ -1763,17 +1762,15 @@ boolean G_Responder(event_t *ev) return true; } } - else if (gamestate == GS_CONTINUING) { if (F_ContinueResponder(ev)) return true; } // Demo End - else if (gamestate == GS_GAMEEND || gamestate == GS_EVALUATION || gamestate == GS_CREDITS) + else if (gamestate == GS_GAMEEND) return true; - - else if (gamestate == GS_INTERMISSION) + else if (gamestate == GS_INTERMISSION || gamestate == GS_EVALUATION) if (HU_Responder(ev)) return true; // chat ate the event @@ -1930,6 +1927,7 @@ void G_Ticker(boolean run) case GS_EVALUATION: if (run) F_GameEvaluationTicker(); + HU_Ticker(); break; case GS_CONTINUING: @@ -3377,7 +3375,7 @@ void G_SaveGameData(void) // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) - WRITEUINT8(save_p, mapvisited[i]); + WRITEUINT8(save_p, (mapvisited[i] & MV_MAX)); // To save space, use one bit per collected/achieved/unlocked flag for (i = 0; i < MAXEMBLEMS;) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 9c912495a..dc97f7014 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -281,16 +281,16 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal sdupx = sdupy = 2.0f; v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; - v[2].x = v[1].x = (cx*sdupx + ((w-sx) - gpatch->leftoffset) * pdupx) / vid.width - 1; + v[2].x = v[1].x = (cx*sdupx + ((w) - gpatch->leftoffset) * pdupx) / vid.width - 1; v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height; - v[2].y = v[3].y = 1 - (cy*sdupy + ((h-sy) - gpatch->topoffset) * pdupy) / vid.height; + v[2].y = v[3].y = 1 - (cy*sdupy + ((h) - gpatch->topoffset) * pdupy) / vid.height; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = ((sx)/(float)gpatch->width )*gpatch->max_s; - v[2].sow = v[1].sow = ((w )/(float)gpatch->width )*gpatch->max_s; - v[0].tow = v[1].tow = ((sy)/(float)gpatch->height)*gpatch->max_t; - v[2].tow = v[3].tow = ((h )/(float)gpatch->height)*gpatch->max_t; + v[0].sow = v[3].sow = ((sx )/(float)gpatch->width )*gpatch->max_s; + v[2].sow = v[1].sow = ((sx+w)/(float)gpatch->width )*gpatch->max_s; + v[0].tow = v[1].tow = ((sy )/(float)gpatch->height)*gpatch->max_t; + v[2].tow = v[3].tow = ((sy+h)/(float)gpatch->height)*gpatch->max_t; flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; diff --git a/src/m_cheat.c b/src/m_cheat.c index 76733a82f..69ae77114 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -70,6 +70,7 @@ static UINT8 cheatf_ultimate(void) return 1; } +#ifdef REDXVI static UINT8 cheatf_warp(void) { if (modifiedgame) @@ -91,6 +92,7 @@ static UINT8 cheatf_warp(void) M_StartControlPanel(); return 1; } +#endif #ifdef DEVELOP static UINT8 cheatf_devmode(void) @@ -131,6 +133,7 @@ static cheatseq_t cheat_ultimate_joy = { SCRAMBLE(KEY_ENTER), 0xff } }; +#ifdef REDXVI static cheatseq_t cheat_warp = { 0, cheatf_warp, { SCRAMBLE('r'), SCRAMBLE('e'), SCRAMBLE('d'), SCRAMBLE('x'), SCRAMBLE('v'), SCRAMBLE('i'), 0xff } @@ -143,6 +146,7 @@ static cheatseq_t cheat_warp_joy = { SCRAMBLE(KEY_LEFTARROW), SCRAMBLE(KEY_UPARROW), SCRAMBLE(KEY_ENTER), 0xff } }; +#endif #ifdef DEVELOP static cheatseq_t cheat_devmode = { @@ -235,8 +239,10 @@ boolean cht_Responder(event_t *ev) ret += cht_CheckCheat(&cheat_ultimate, (char)ch); ret += cht_CheckCheat(&cheat_ultimate_joy, (char)ch); +#ifdef REDXVI ret += cht_CheckCheat(&cheat_warp, (char)ch); ret += cht_CheckCheat(&cheat_warp_joy, (char)ch); +#endif #ifdef DEVELOP ret += cht_CheckCheat(&cheat_devmode, (char)ch); #endif diff --git a/src/m_menu.c b/src/m_menu.c index 34f623718..879cc879d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -238,6 +238,7 @@ static void M_CustomLevelSelect(INT32 choice); static void M_CustomWarp(INT32 choice); FUNCNORETURN static ATTRNORETURN void M_UltimateCheat(INT32 choice); static void M_LoadGameLevelSelect(INT32 choice); +static void M_AllowSuper(INT32 choice); static void M_GetAllEmeralds(INT32 choice); static void M_DestroyRobots(INT32 choice); static void M_LevelSelectWarp(INT32 choice); @@ -255,7 +256,6 @@ static void M_Options(INT32 choice); static void M_SelectableClearMenus(INT32 choice); static void M_Retry(INT32 choice); static void M_EndGame(INT32 choice); -static void M_GameTypeChange(INT32 choice); static void M_MapChange(INT32 choice); static void M_ChangeLevel(INT32 choice); static void M_ConfirmSpectate(INT32 choice); @@ -353,7 +353,6 @@ static void M_DrawSkyRoom(void); static void M_DrawChecklist(void); static void M_DrawEmblemHints(void); static void M_DrawPauseMenu(void); -static void M_DrawGameTypeMenu(void); static void M_DrawServerMenu(void); static void M_DrawLevelPlatterMenu(void); static void M_DrawImageDef(void); @@ -532,7 +531,7 @@ static menuitem_t MPauseMenu[] = { {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8}, {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, - {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 24}, + {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_MapChange, 24}, {IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,40}, {IT_STRING | IT_CALL, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen @@ -615,32 +614,16 @@ static menuitem_t MISC_ChangeTeamMenu[] = {IT_WHITESTRING|IT_CALL, NULL, "Confirm", M_ConfirmTeamChange, 90}, }; -static menuitem_t MISC_ChangeGameTypeMenu[] = -{ - {IT_STRING|IT_CALL, NULL, "Co-op", M_MapChange, 0}, - - {IT_STRING|IT_CALL, NULL, "Competition", M_MapChange, 12}, - {IT_STRING|IT_CALL, NULL, "Race", M_MapChange, 20}, - - {IT_STRING|IT_CALL, NULL, "Match", M_MapChange, 32}, - {IT_STRING|IT_CALL, NULL, "Team Match", M_MapChange, 40}, - - {IT_STRING|IT_CALL, NULL, "Tag", M_MapChange, 52}, - {IT_STRING|IT_CALL, NULL, "Hide & Seek", M_MapChange, 60}, - - {IT_STRING|IT_CALL, NULL, "Capture the Flag", M_MapChange, 72}, -}; - static const gtdesc_t gametypedesc[] = { - {"Play through the single-player campaign with your friends, teaming up to beat Dr Eggman's nefarious challenges!"}, - {"Speed your way through the main acts, competing in several different categories to see who's the best."}, - {"There's not much to it - zoom through the level faster than everyone else."}, - {"Sling rings at your foes in a free-for-all battle. Use the special weapon rings to your advantage!"}, - {"Sling rings at your foes in a color-coded battle. Use the special weapon rings to your advantage!"}, - {"Whoever's IT has to hunt down everyone else. If you get caught, you have to turn on your former friends!"}, - {"Try and find a good hiding place in these maps - we dare you."}, - {"Steal the flag from the enemy's base and bring it back to your own, but watch out - they could just as easily steal yours!"}, + {{ 54, 54}, "Play through the single-player campaign with your friends, teaming up to beat Dr Eggman's nefarious challenges!"}, + {{103, 103}, "Speed your way through the main acts, competing in several different categories to see who's the best."}, + {{190, 190}, "There's not much to it - zoom through the level faster than everyone else."}, + {{ 66, 66}, "Sling rings at your foes in a free-for-all battle. Use the special weapon rings to your advantage!"}, + {{153, 37}, "Sling rings at your foes in a color-coded battle. Use the special weapon rings to your advantage!"}, + {{123, 123}, "Whoever's IT has to hunt down everyone else. If you get caught, you have to turn on your former friends!"}, + {{150, 150}, "Try and find a good hiding place in these maps - we dare you."}, + {{ 37, 153}, "Steal the flag from the enemy's base and bring it back to your own, but watch out - they could just as easily steal yours!"}, }; static menuitem_t MISC_ChangeLevelMenu[] = @@ -665,17 +648,20 @@ static menuitem_t MISC_HelpMenu[] = // Pause Menu Pandora's Box Options static menuitem_t SR_PandorasBox[] = { - {IT_STRING | IT_CVAR, NULL, "Rings", &cv_dummyrings, 20}, - {IT_STRING | IT_CVAR, NULL, "Lives", &cv_dummylives, 30}, - {IT_STRING | IT_CVAR, NULL, "Continues", &cv_dummycontinues, 40}, + {IT_STRING | IT_CALL, NULL, "Mid-game add-ons...", M_Addons, 0}, - {IT_STRING | IT_CVAR, NULL, "Gravity", &cv_gravity, 60}, - {IT_STRING | IT_CVAR, NULL, "Throw Rings", &cv_ringslinger, 70}, + {IT_STRING | IT_CVAR, NULL, "Rings", &cv_dummyrings, 20}, + {IT_STRING | IT_CVAR, NULL, "Lives", &cv_dummylives, 30}, + {IT_STRING | IT_CVAR, NULL, "Continues", &cv_dummycontinues, 40}, - {IT_STRING | IT_CALL, NULL, "Get All Emeralds", M_GetAllEmeralds, 90}, - {IT_STRING | IT_CALL, NULL, "Destroy All Robots", M_DestroyRobots, 100}, + {IT_STRING | IT_CVAR, NULL, "Gravity", &cv_gravity, 60}, + {IT_STRING | IT_CVAR, NULL, "Throw Rings", &cv_ringslinger, 70}, - {IT_STRING | IT_CALL, NULL, "Ultimate Cheat", M_UltimateCheat, 130}, + {IT_STRING | IT_CALL, NULL, "Enable Super form", M_AllowSuper, 90}, + {IT_STRING | IT_CALL, NULL, "Get All Emeralds", M_GetAllEmeralds, 100}, + {IT_STRING | IT_CALL, NULL, "Destroy All Robots", M_DestroyRobots, 110}, + + {IT_STRING | IT_CALL, NULL, "Ultimate Cheat", M_UltimateCheat, 130}, }; // Sky Room Custom Unlocks @@ -914,7 +900,7 @@ static menuitem_t SP_PlayerMenu[] = // Separated splitscreen and normal servers. static menuitem_t MP_SplitServerMenu[] = { - {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_GameTypeChange, 100}, + {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100}, #ifdef NONET // In order to keep player setup accessible. {IT_STRING|IT_CALL, NULL, "Player 1 setup...", M_SetupMultiPlayer, 110}, {IT_STRING|IT_CALL, NULL, "Player 2 setup...", M_SetupMultiPlayer2, 120}, @@ -944,7 +930,7 @@ static menuitem_t MP_ServerMenu[] = {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20}, {IT_STRING|IT_CVAR, NULL, "Max Players", &cv_maxplayers, 46}, {IT_STRING|IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 56}, - {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_GameTypeChange, 100}, + {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100}, {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140}, }; @@ -1077,8 +1063,8 @@ static menuitem_t OP_ChangeControlsMenu[] = {IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, gc_backward }, {IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, gc_strafeleft }, {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, gc_straferight }, - {IT_CALL | IT_STRING2, NULL, "Jump / Main Action", M_ChangeControl, gc_jump }, - {IT_CALL | IT_STRING2, NULL, "Spin / Shield Action", M_ChangeControl, gc_use }, + {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, gc_jump }, + {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, gc_use }, {IT_HEADER, NULL, "Camera", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Camera Up", M_ChangeControl, gc_lookup }, @@ -1495,22 +1481,11 @@ menu_t MISC_ScrambleTeamDef = DEFAULTMENUSTYLE(NULL, MISC_ScrambleTeamMenu, &MPa menu_t MISC_ChangeTeamDef = DEFAULTMENUSTYLE(NULL, MISC_ChangeTeamMenu, &MPauseDef, 27, 40); // MP Gametype and map change menu -menu_t MISC_ChangeGameTypeDef = -{ - NULL, - sizeof (MISC_ChangeGameTypeMenu)/sizeof (menuitem_t), - &MainDef, // Doesn't matter. - MISC_ChangeGameTypeMenu, - M_DrawGameTypeMenu, - 30, (200 - (72+8))/2, // vertically centering - 0, - NULL -}; menu_t MISC_ChangeLevelDef = { NULL, sizeof (MISC_ChangeLevelMenu)/sizeof (menuitem_t), - &MISC_ChangeGameTypeDef, + &MainDef, // Doesn't matter. MISC_ChangeLevelMenu, M_DrawLevelPlatterMenu, 0, 0, @@ -1528,7 +1503,7 @@ menu_t SR_PandoraDef = &SPauseDef, SR_PandorasBox, M_DrawGenericMenu, - 60, 40, + 60, 30, 0, M_ExitPandorasBox }; @@ -2162,6 +2137,8 @@ static void M_GoBack(INT32 choice) 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; menuactive = false; D_StartTitle(); } @@ -2524,21 +2501,11 @@ boolean M_Responder(event_t *ev) case KEY_DOWNARROW: M_NextOpt(); S_StartSound(NULL, sfx_menu1); - if (currentMenu == &MISC_ChangeGameTypeDef) - { - Z_Free(char_notes); - char_notes = NULL; - } return true; case KEY_UPARROW: M_PrevOpt(); S_StartSound(NULL, sfx_menu1); - if (currentMenu == &MISC_ChangeGameTypeDef) - { - Z_Free(char_notes); - char_notes = NULL; - } return true; case KEY_LEFTARROW: @@ -3104,6 +3071,34 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) */ } +static fixed_t staticalong = 0; + +static void M_DrawStaticBox(fixed_t x, fixed_t y, INT32 flags, fixed_t w, fixed_t h) +{ + patch_t *patch; + fixed_t sw, pw; + + patch = W_CachePatchName("LSSTATIC", PU_CACHE); + pw = SHORT(patch->width) - (sw = w*2); //FixedDiv(w, scale); -- for scale FRACUNIT/2 + + /*if (pw > 0) -- model code for modders providing weird LSSTATIC + { + if (staticalong > pw) + staticalong -= pw; + } + else + staticalong = 0;*/ + + if (staticalong > pw) // simplified for base LSSTATIC + staticalong -= pw; + + V_DrawCroppedPatch(x<typeoflevel & TOL_COOP)) + return true; + + if (mapvisited[mapnum]) // MV_MP + return true; + + // intentional fallthrough case LLM_RECORDATTACK: case LLM_NIGHTSATTACK: + if (mapvisited[mapnum] & MV_MAX) + return true; + if (mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED) return true; - if (!mapvisited[mapnum]) - return false; - - // intentional fallthrough - case LLM_CREATESERVER: + return false; case LLM_LEVELSELECT: default: return true; @@ -3964,6 +3966,9 @@ static INT32 M_CountRowsToShowOnPlatter(INT32 gt) mapnum++; } + if (levellistmode == LLM_CREATESERVER) + rows++; + return rows; } @@ -3973,10 +3978,10 @@ static INT32 M_CountRowsToShowOnPlatter(INT32 gt) // Prepares a tasty dish of zones and acts! // Call before any attempt to access a level platter. // -static boolean M_PrepareLevelPlatter(INT32 gt) +static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) { INT32 numrows = M_CountRowsToShowOnPlatter(gt); - INT32 mapnum = 0, prevmapnum = 0, col = 0, row = 0; + INT32 mapnum = 0, prevmapnum = 0, col = 0, row = 0, startrow = 0; if (!numrows) return false; @@ -3993,6 +3998,17 @@ static boolean M_PrepareLevelPlatter(INT32 gt) // done here so lsrow and lscol can be set if cv_nextmap is on the platter lsrow = lscol = lshli = lsoffs[0] = lsoffs[1] = 0; + if (levellistmode == LLM_CREATESERVER) + { + sprintf(levelselect.rows[0].header, "Gametype"); + lswide(0) = true; + levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1] = levelselect.rows[row].mapavailable[0] = false; + startrow = row = 1; + + Z_Free(char_notes); + char_notes = NULL; + } + while (mapnum < NUMMAPS) { if (M_CanShowLevelOnPlatter(mapnum, gt)) @@ -4002,7 +4018,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt) const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON); // preparing next position to drop mapnum into - if (levelselect.rows[0].maplist[0]) + if (levelselect.rows[startrow].maplist[0]) { if (col == 2 // no more space on the row? || wide @@ -4025,7 +4041,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt) levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1] = levelselect.rows[row].mapavailable[0]; } - if (cv_nextmap.value == mapnum+1) // A little quality of life improvement. + if (nextmappick && cv_nextmap.value == mapnum+1) // A little quality of life improvement. { lsrow = row; lscol = col; @@ -4067,7 +4083,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt) sprintf(levelselect.rows[row].mapnames[col], "???"); // creating header text - if (!col && (!row || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[levelselect.rows[row-1].maplist[0]-1]->selectheading)))) + if (!col && ((row == startrow) || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[levelselect.rows[row-1].maplist[0]-1]->selectheading)))) { if (!levelselect.rows[row].mapavailable[col]) sprintf(levelselect.rows[row].header, "???"); @@ -4127,12 +4143,11 @@ static boolean M_PrepareLevelPlatter(INT32 gt) return true; } -#define selectvalnextmapnobrace(column) selectval = levelselect.rows[lsrow].maplist[column];\ - if (selectval && levelselect.rows[lsrow].mapavailable[column])\ +#define ifselectvalnextmapnobrace(column) if ((selectval = levelselect.rows[lsrow].maplist[column]) && levelselect.rows[lsrow].mapavailable[column])\ {\ CV_SetValue(&cv_nextmap, selectval); -#define selectvalnextmap(column) selectvalnextmapnobrace(column)} +#define ifselectvalnextmap(column) ifselectvalnextmapnobrace(column)} // // M_HandleLevelPlatter @@ -4159,7 +4174,7 @@ static void M_HandleLevelPlatter(INT32 choice) S_StartSound(NULL,sfx_s3kb7); - selectvalnextmap(lscol) else selectvalnextmap(0) + ifselectvalnextmap(lscol) else ifselectvalnextmap(0) break; case KEY_UPARROW: @@ -4182,35 +4197,59 @@ static void M_HandleLevelPlatter(INT32 choice) S_StartSound(NULL,sfx_s3kb7); - selectvalnextmap(lscol) else selectvalnextmap(0) + ifselectvalnextmap(lscol) else ifselectvalnextmap(0) break; - case KEY_LEFTARROW: - if (lscol > 0) + case KEY_ENTER: + if (!(levellistmode == LLM_CREATESERVER && !lsrow)) { - lscol--; - - lsoffs[1] = (lswide(lsrow) ? -8 : lshseperation); - S_StartSound(NULL,sfx_s3kb7); - - selectvalnextmap(lscol) else selectvalnextmap(0) + ifselectvalnextmapnobrace(lscol) + lsoffs[0] = lsoffs[1] = 0; + S_StartSound(NULL,sfx_menu1); + if (gamestate == GS_TIMEATTACK) + M_SetupNextMenu(currentMenu->prevMenu); + else if (currentMenu == &MISC_ChangeLevelDef) + { + if (currentMenu->prevMenu && currentMenu->prevMenu != &MPauseDef) + M_SetupNextMenu(currentMenu->prevMenu); + else + M_ChangeLevel(0); + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } + else + M_LevelSelectWarp(0); + Nextmap_OnChange(); + } + else if (!lsoffs[0]) // prevent sound spam + { + lsoffs[0] = -8; + S_StartSound(NULL,sfx_s3kb2); + } + break; } - else if (!lsoffs[1]) // prevent sound spam - { - lsoffs[1] = -8; - S_StartSound(NULL,sfx_s3kb7); - } - break; - + // intentionall fallthrough case KEY_RIGHTARROW: - if (lscol < 2) + if (levellistmode == LLM_CREATESERVER && !lsrow) + { + CV_AddValue(&cv_newgametype, 1); + S_StartSound(NULL,sfx_menu1); + lscol = 0; + + Z_Free(char_notes); + char_notes = NULL; + + if (!M_PrepareLevelPlatter(cv_newgametype.value, false)) + I_Error("Unidentified level platter failure!"); + } + else if (lscol < 2) { lscol++; lsoffs[1] = (lswide(lsrow) ? 8 : -lshseperation); S_StartSound(NULL,sfx_s3kb7); - selectvalnextmap(lscol) else selectvalnextmap(0) + ifselectvalnextmap(lscol) else ifselectvalnextmap(0) } else if (!lsoffs[1]) // prevent sound spam { @@ -4219,30 +4258,32 @@ static void M_HandleLevelPlatter(INT32 choice) } break; - case KEY_ENTER: - selectvalnextmapnobrace(lscol) - - lsoffs[0] = lsoffs[1] = 0; - S_StartSound(NULL,sfx_menu1); - if (gamestate == GS_TIMEATTACK) - M_SetupNextMenu(currentMenu->prevMenu); - else if (currentMenu == &MISC_ChangeLevelDef) - { - if (currentMenu->prevMenu && currentMenu->prevMenu->prevMenu != &MPauseDef) - M_SetupNextMenu(currentMenu->prevMenu->prevMenu); - else - M_ChangeLevel(0); - Z_Free(levelselect.rows); - levelselect.rows = NULL; - } - else - M_LevelSelectWarp(0); - Nextmap_OnChange(); - } - else if (!lsoffs[0]) // prevent sound spam + case KEY_LEFTARROW: + if (levellistmode == LLM_CREATESERVER && !lsrow) { - lsoffs[0] = -8; - S_StartSound(NULL,sfx_lose); + CV_AddValue(&cv_newgametype, -1); + S_StartSound(NULL,sfx_menu1); + lscol = 0; + + Z_Free(char_notes); + char_notes = NULL; + + if (!M_PrepareLevelPlatter(cv_newgametype.value, false)) + I_Error("Unidentified level platter failure!"); + } + else if (lscol > 0) + { + lscol--; + + lsoffs[1] = (lswide(lsrow) ? -8 : lshseperation); + S_StartSound(NULL,sfx_s3kb7); + + ifselectvalnextmap(lscol) else ifselectvalnextmap(0) + } + else if (!lsoffs[1]) // prevent sound spam + { + lsoffs[1] = -8; + S_StartSound(NULL,sfx_s3kb7); } break; @@ -4256,6 +4297,12 @@ static void M_HandleLevelPlatter(INT32 choice) if (exitmenu) { + if (gamestate != GS_TIMEATTACK) + { + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } + if (currentMenu->prevMenu) { M_SetupNextMenu(currentMenu->prevMenu); @@ -4263,8 +4310,9 @@ static void M_HandleLevelPlatter(INT32 choice) } else M_ClearMenus(true); - Z_Free(levelselect.rows); - levelselect.rows = NULL; + + Z_Free(char_notes); + char_notes = NULL; } } @@ -4289,7 +4337,10 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo // A 564x100 image of the level as entry MAPxxW if (!(levelselect.rows[row].mapavailable[col])) - V_DrawSmallScaledPatch(x, y, V_STATIC, levselp[1][2]); // static - make secret maps look ENTICING + { + V_DrawSmallScaledPatch(x, y, 0, levselp[1][2]); + M_DrawStaticBox(x, y, V_80TRANS, 282, 50); + } else { if (W_CheckNumForName(va("%sW", G_BuildMapName(map))) != LUMPERROR) @@ -4317,7 +4368,10 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea // A 160x100 image of the level as entry MAPxxP if (!(levelselect.rows[row].mapavailable[col])) - V_DrawSmallScaledPatch(x, y, V_STATIC, levselp[0][2]); // static - make secret maps look ENTICING + { + V_DrawSmallScaledPatch(x, y, 0, levselp[0][2]); + M_DrawStaticBox(x, y, V_80TRANS, 80, 50); + } else { if (W_CheckNumForName(va("%sP", G_BuildMapName(map))) != LUMPERROR) @@ -4348,7 +4402,28 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) y += lsheadingheight; } - if (lswide(row)) + if (levellistmode == LLM_CREATESERVER && !row) + { + if (!char_notes) + char_notes = V_WordWrap(0, 282 - 8, V_ALLOWLOWERCASE, gametypedesc[cv_newgametype.value].notes); + + V_DrawFill(lsbasex, y, 282, 50, 27); + V_DrawString(lsbasex + 4, y + 4, V_RETURN8|V_ALLOWLOWERCASE, char_notes); + + V_DrawFill(lsbasex, y+50, 141, 8, gametypedesc[cv_newgametype.value].col[0]); + V_DrawFill(lsbasex+141, y+50, 141, 8, gametypedesc[cv_newgametype.value].col[1]); + + V_DrawString(lsbasex, y+50, 0, gametype_cons_t[cv_newgametype.value].strvalue); + + if (!lsrow) + { + V_DrawCharacter(lsbasex - 10 - (skullAnimCounter/5), y+25, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(lsbasex+282 + 2 + (skullAnimCounter/5), y+25, + '\x1D' | V_YELLOWMAP, false); + } + } + else if (lswide(row)) M_DrawLevelPlatterWideMap(row, 0, lsbasex, y, rowhighlight); else { @@ -4382,10 +4457,13 @@ static void M_DrawLevelPlatterMenu(void) } // draw cursor box - V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)])); + if (levellistmode != LLM_CREATESERVER || lsrow) + V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey+lsoffs[0], 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)])); +#if 0 if (levelselect.rows[lsrow].maplist[lscol] > 0) V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE)); +#endif // handle movement of cursor box if (lsoffs[0] > 1 || lsoffs[0] < -1) @@ -4988,7 +5066,7 @@ static void M_DrawAddons(void) x = BASEVIDWIDTH - x - 16; V_DrawSmallScaledPatch(x, y + 4, (CANSAVE ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]); - if CANSAVE + if (modifiedgame) V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]); #undef CANSAVE } @@ -5203,6 +5281,12 @@ static void M_PandorasBox(INT32 choice) CV_StealthSetValue(&cv_dummyrings, max(players[consoleplayer].rings, 0)); CV_StealthSetValue(&cv_dummylives, players[consoleplayer].lives); CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues); + SR_PandorasBox[6].status = ((players[consoleplayer].charflags & SF_SUPER) +#ifndef DEVELOP + || cv_skin.value == 1 +#endif + ) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); + SR_PandorasBox[7].status = (emeralds == ((EMERALD7)*2)-1) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); M_SetupNextMenu(&SR_PandoraDef); } @@ -5339,12 +5423,24 @@ static void M_UltimateCheat(INT32 choice) I_Quit(); } +static void M_AllowSuper(INT32 choice) +{ + (void)choice; + + players[consoleplayer].charflags |= SF_SUPER; + M_StartMessage(M_GetText("You are now capable of turning super.\nRemember to get all the emeralds!\n"),NULL,MM_NOTHING); + SR_PandorasBox[6].status = IT_GRAYEDOUT; + + G_SetGameModified(multiplayer); +} + static void M_GetAllEmeralds(INT32 choice) { (void)choice; emeralds = ((EMERALD7)*2)-1; M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING); + SR_PandorasBox[7].status = IT_GRAYEDOUT; G_SetGameModified(multiplayer); } @@ -5559,7 +5655,7 @@ static void M_DrawChecklist(void) if (title) { - const char *level = ((M_MapLocked(cond[condnum].requirement) || !((mapheaderinfo[cond[condnum].requirement-1]->menuflags & LF2_NOVISITNEEDED) || mapvisited[cond[condnum].requirement-1])) ? M_CreateSecretMenuOption(title) : title); + const char *level = ((M_MapLocked(cond[condnum].requirement) || !((mapheaderinfo[cond[condnum].requirement-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].requirement-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); switch (cond[condnum].type) { @@ -5592,7 +5688,7 @@ static void M_DrawChecklist(void) if (title) { - const char *level = ((M_MapLocked(cond[condnum].extrainfo1) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || mapvisited[cond[condnum].extrainfo1-1])) ? M_CreateSecretMenuOption(title) : title); + const char *level = ((M_MapLocked(cond[condnum].extrainfo1) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].extrainfo1-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); switch (cond[condnum].type) { @@ -5661,7 +5757,7 @@ static void M_DrawChecklist(void) if (title) { - const char *level = ((M_MapLocked(cond[condnum].extrainfo1) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || mapvisited[cond[condnum].extrainfo1-1])) ? M_CreateSecretMenuOption(title) : title); + const char *level = ((M_MapLocked(cond[condnum].extrainfo1) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].extrainfo1-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); switch (cond[condnum].type) { @@ -5975,7 +6071,7 @@ static void M_CustomLevelSelect(INT32 choice) levellistmode = LLM_LEVELSELECT; maplistoption = (UINT8)(unlockables[ul].variable); - if (!M_PrepareLevelPlatter(-1)) + if (!M_PrepareLevelPlatter(-1, true)) { M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); return; @@ -6007,7 +6103,7 @@ static void M_LoadGameLevelSelect(INT32 choice) levellistmode = LLM_LEVELSELECT; maplistoption = 1; - if (!M_PrepareLevelPlatter(-1)) + if (!M_PrepareLevelPlatter(-1, true)) { M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); return; @@ -6060,12 +6156,14 @@ static void M_DrawLoadGameData(void) if (savetodraw == saveSlotSelected) V_DrawFill(x, y+9, 80, 1, yellowmap[3]); y += 11; - V_DrawSmallScaledPatch(x, y, V_STATIC, savselp[4]); + V_DrawSmallScaledPatch(x, y, 0, savselp[4]); + M_DrawStaticBox(x, y, V_80TRANS, 80, 50); y += 41; if (ultimate_selectable) V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "ULTIMATE."); else V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "DON'T SAVE!"); + continue; } @@ -6123,28 +6221,28 @@ static void M_DrawLoadGameData(void) // level image area { - patch_t *patch; - INT32 flags = 0; - if ((savegameinfo[savetodraw].lives == -42) || (savegameinfo[savetodraw].lives == -666)) { - patch = savselp[3]; - flags = V_STATIC; + V_DrawFill(x, y, 80, 50, 31); + M_DrawStaticBox(x, y, V_80TRANS, 80, 50); } - else if (savegameinfo[savetodraw].gamemap & 8192) - patch = savselp[6]; else { - lumpnum_t lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName((savegameinfo[savetodraw].gamemap) & 8191))); - if (lumpnum != LUMPERROR) - patch = W_CachePatchNum(lumpnum, PU_CACHE); + patch_t *patch; + if (savegameinfo[savetodraw].gamemap & 8192) + patch = savselp[3]; else - patch = savselp[5]; + { + lumpnum_t lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName((savegameinfo[savetodraw].gamemap) & 8191))); + if (lumpnum != LUMPERROR) + patch = W_CachePatchNum(lumpnum, PU_CACHE); + else + patch = savselp[5]; + } + V_DrawSmallScaledPatch(x, y, 0, patch); } - V_DrawSmallScaledPatch(x, y, flags, patch); - y += 41; if (savegameinfo[savetodraw].lives == -42) @@ -6495,17 +6593,15 @@ static void M_ReadSaveStrings(void) W_UnlockCachedPatch(savselp[3]); W_UnlockCachedPatch(savselp[4]); W_UnlockCachedPatch(savselp[5]); - W_UnlockCachedPatch(savselp[6]); } savselp[0] = W_CachePatchName("SAVEBACK", PU_STATIC); savselp[1] = W_CachePatchName("SAVENONE", PU_STATIC); savselp[2] = W_CachePatchName("ULTIMATE", PU_STATIC); - savselp[3] = W_CachePatchName("BLACKLVL", PU_STATIC); + savselp[3] = W_CachePatchName("GAMEDONE", PU_STATIC); savselp[4] = W_CachePatchName("BLACXLVL", PU_STATIC); savselp[5] = W_CachePatchName("BLANKLVL", PU_STATIC); - savselp[6] = W_CachePatchName("GAMEDONE", PU_STATIC); } // @@ -6846,9 +6942,9 @@ static void M_DrawSetupChoosePlayerMenu(void) { patch = W_CachePatchName(description[prev].picname, PU_CACHE); if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height)); + V_DrawCroppedPatch(8<height) + 2*(o-32), SHORT(patch->width), 64 - 2*o); else - V_DrawCroppedPatch(8<height) - 32 + o, SHORT(patch->width), SHORT(patch->height)); + V_DrawCroppedPatch(8<height) + o - 32, SHORT(patch->width), 32 - o); W_UnlockCachedPatch(patch); } @@ -6857,7 +6953,7 @@ static void M_DrawSetupChoosePlayerMenu(void) { patch = W_CachePatchName(description[next].picname, PU_CACHE); if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<width), o*2); + V_DrawCroppedPatch(8<width), 2*o); else V_DrawCroppedPatch(8<width), o); W_UnlockCachedPatch(patch); @@ -6875,9 +6971,9 @@ static void M_DrawSetupChoosePlayerMenu(void) else { if (SHORT(patch->width) >= 256) - V_DrawCroppedPatch(8<width), SHORT(patch->height)); + V_DrawCroppedPatch(8<width), SHORT(patch->height) - 2*(o-32)); else - V_DrawCroppedPatch(8<width), SHORT(patch->height)); + V_DrawCroppedPatch(8<width), SHORT(patch->height) - (o-32)); } W_UnlockCachedPatch(patch); @@ -6967,7 +7063,7 @@ static void M_Statistics(INT32 choice) if (!(mapheaderinfo[i]->typeoflevel & TOL_SP) || (mapheaderinfo[i]->menuflags & LF2_HIDEINSTATS)) continue; - if (!mapvisited[i]) + if (!(mapvisited[i] & MV_MAX)) continue; statsMapList[j++] = i; @@ -7364,7 +7460,7 @@ static void M_TimeAttack(INT32 choice) SP_TimeAttackDef.prevMenu = &MainDef; levellistmode = LLM_RECORDATTACK; // Don't be dependent on cv_newgametype - if (!M_PrepareLevelPlatter(-1)) + if (!M_PrepareLevelPlatter(-1, true)) { M_StartMessage(M_GetText("No record-attackable levels found.\n"),NULL,MM_NOTHING); return; @@ -7541,7 +7637,7 @@ static void M_NightsAttack(INT32 choice) SP_NightsAttackDef.prevMenu = &MainDef; levellistmode = LLM_NIGHTSATTACK; // Don't be dependent on cv_newgametype - if (!M_PrepareLevelPlatter(-1)) + if (!M_PrepareLevelPlatter(-1, true)) { M_StartMessage(M_GetText("No NiGHTS-attackable levels found.\n"),NULL,MM_NOTHING); return; @@ -8243,42 +8339,17 @@ static void M_DrawServerMenu(void) } } -static void M_GameTypeChange(INT32 choice) +static void M_MapChange(INT32 choice) { (void)choice; - MISC_ChangeGameTypeDef.prevMenu = currentMenu; - M_SetupNextMenu(&MISC_ChangeGameTypeDef); - if (Playing()) - itemOn = gametype; - - Z_Free(char_notes); - char_notes = NULL; -} - -void M_DrawGameTypeMenu(void) -{ - M_DrawGenericMenu(); - M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight, "Select Gametype", true, false); - - if (!char_notes) - char_notes = V_WordWrap(0, (160 - 30) - 8, V_ALLOWLOWERCASE, gametypedesc[itemOn].notes); - - V_DrawFill(160, currentMenu->y, (160 - 30), 72 + 8, 159); - V_DrawString(164, currentMenu->y + 4, V_RETURN8|V_ALLOWLOWERCASE, char_notes); -} - -static void M_MapChange(INT32 choice) -{ MISC_ChangeLevelDef.prevMenu = currentMenu; levellistmode = LLM_CREATESERVER; - CV_SetValue(&cv_newgametype, choice); - - if (Playing() && !(M_CanShowLevelOnPlatter(cv_nextmap.value-1, choice)) && (M_CanShowLevelOnPlatter(gamemap-1, choice))) + if (Playing() && !(M_CanShowLevelOnPlatter(cv_nextmap.value-1, cv_newgametype.value)) && (M_CanShowLevelOnPlatter(gamemap-1, cv_newgametype.value))) CV_SetValue(&cv_nextmap, gamemap); - if (!M_PrepareLevelPlatter(choice)) + if (!M_PrepareLevelPlatter(cv_newgametype.value, (currentMenu == &MPauseDef))) { M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); return; @@ -9392,7 +9463,10 @@ static void M_ToggleDigital(INT32 choice) if (nodigimusic) return; S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); S_StopMusic(); - S_ChangeMusicInternal("_clear", false); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("_clear", false); //M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); } else @@ -9400,7 +9474,10 @@ static void M_ToggleDigital(INT32 choice) if (digital_disabled) { digital_disabled = false; - S_ChangeMusicInternal("_clear", false); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("_clear", false); //M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); } else @@ -9442,7 +9519,10 @@ static void M_ToggleMIDI(INT32 choice) I_InitMIDIMusic(); if (nomidimusic) return; S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); - S_ChangeMusicInternal("_clear", false); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("_clear", false); //M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); } else @@ -9450,7 +9530,10 @@ static void M_ToggleMIDI(INT32 choice) if (music_disabled) { music_disabled = false; - S_ChangeMusicInternal("_clear", false); + if (Playing()) + P_RestoreMusic(&players[consoleplayer]); + else + S_ChangeMusicInternal("_clear", false); //M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); } else diff --git a/src/m_menu.h b/src/m_menu.h index aa80445c8..9df56e897 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -201,6 +201,7 @@ typedef struct // descriptions for gametype select screen typedef struct { + UINT8 col[2]; char notes[441]; } gtdesc_t; diff --git a/src/p_local.h b/src/p_local.h index 91ee0c496..f239bcc68 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -28,7 +28,7 @@ #define VIEWHEIGHTS "41" // Maximum player score. -#define MAXSCORE 999999990 +#define MAXSCORE 99999990 // 999999990 // mapblocks are used to check movement // against lines and things diff --git a/src/p_setup.c b/src/p_setup.c index 26234bccb..df7638b30 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3080,6 +3080,8 @@ boolean P_SetupLevel(boolean skipprecip) if (!(netgame || multiplayer) && (!modifiedgame || savemoddata)) mapvisited[gamemap-1] |= MV_VISITED; + else + mapvisited[gamemap-1] |= MV_MP; // you want to record that you've been there this session, but not permanently levelloading = false; diff --git a/src/p_user.c b/src/p_user.c index be0ca803e..c5326b730 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1092,9 +1092,8 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) oldscore = player->score; // Don't go above MAXSCORE. - if (player->score + amount < MAXSCORE) - player->score += amount; - else + player->score += amount; + if (player->score > MAXSCORE) player->score = MAXSCORE; // check for extra lives every 50000 pts diff --git a/src/s_sound.c b/src/s_sound.c index 4d041dae4..0ac3a2c76 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -951,21 +951,27 @@ void S_UpdateSounds(void) notinlevel: I_UpdateSound(); - for (i = 0; i < NUMCAPTIONS; i++) // update captions { - if (!closedcaptions[i].s) - continue; + boolean gamestopped = (paused || P_AutoPause()); + for (i = 0; i < NUMCAPTIONS; i++) // update captions + { + if (!closedcaptions[i].s) + continue; - if (!(--closedcaptions[i].t)) - { - closedcaptions[i].c = NULL; - closedcaptions[i].s = NULL; - } - else if (closedcaptions[i].c && !I_SoundIsPlaying(closedcaptions[i].c->handle)) - { - closedcaptions[i].c = NULL; - if (closedcaptions[i].t > CAPTIONFADETICS) - closedcaptions[i].t = CAPTIONFADETICS; + if (i == 0 && (closedcaptions[0].s-S_sfx == sfx_None) && gamestopped) + continue; + + if (!(--closedcaptions[i].t)) + { + closedcaptions[i].c = NULL; + closedcaptions[i].s = NULL; + } + else if (closedcaptions[i].c && !I_SoundIsPlaying(closedcaptions[i].c->handle)) + { + closedcaptions[i].c = NULL; + if (closedcaptions[i].t > CAPTIONFADETICS) + closedcaptions[i].t = CAPTIONFADETICS; + } } } } diff --git a/src/screen.c b/src/screen.c index fd0d8ab52..28765785b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -31,6 +31,7 @@ #include "i_sound.h" // closed captions #include "s_sound.h" // ditto #include "g_game.h" // ditto +#include "p_local.h" // P_AutoPause() #if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200)) @@ -438,6 +439,7 @@ void SCR_DisplayTicRate(void) void SCR_ClosedCaptions(void) { UINT8 i; + boolean gamestopped = (paused || P_AutoPause()); for (i = 0; i < NUMCAPTIONS; i++) { @@ -448,7 +450,9 @@ void SCR_ClosedCaptions(void) if (!closedcaptions[i].s) continue; - if ((music = (closedcaptions[i].s-S_sfx == sfx_None)) && (closedcaptions[i].t < flashingtics) && (closedcaptions[i].t & 1)) + music = (closedcaptions[i].s-S_sfx == sfx_None); + + if (music && !gamestopped && (closedcaptions[i].t < flashingtics) && (closedcaptions[i].t & 1)) continue; flags = V_NOSCALESTART|V_ALLOWLOWERCASE; diff --git a/src/st_stuff.c b/src/st_stuff.c index 66907036e..92f75e463 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -132,22 +132,23 @@ hudinfo_t hudinfo[NUMHUDITEMS] = { 16, 42}, // HUD_RINGS { 220, 10}, // HUD_RINGSSPLIT - { 120, 42}, // HUD_RINGSNUM + { 96, 42}, // HUD_RINGSNUM { 296, 10}, // HUD_RINGSNUMSPLIT + { 120, 42}, // HUD_RINGSNUMTICS { 16, 10}, // HUD_SCORE { 120, 10}, // HUD_SCORENUM { 16, 26}, // HUD_TIME { 128, 10}, // HUD_TIMESPLIT - { 96, 26}, // HUD_MINUTES + { 72, 26}, // HUD_MINUTES { 188, 10}, // HUD_MINUTESSPLIT - { 96, 26}, // HUD_TIMECOLON + { 72, 26}, // HUD_TIMECOLON { 188, 10}, // HUD_TIMECOLONSPLIT - { 120, 26}, // HUD_SECONDS + { 96, 26}, // HUD_SECONDS { 212, 10}, // HUD_SECONDSSPLIT - { 120, 26}, // HUD_TIMETICCOLON - { 144, 26}, // HUD_TICS + { 96, 26}, // HUD_TIMETICCOLON + { 120, 26}, // HUD_TICS { 120, 56}, // HUD_SS_TOTALRINGS { 296, 40}, // HUD_SS_TOTALRINGS_SPLIT @@ -653,7 +654,7 @@ static void ST_drawTime(void) ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds - if (!splitscreen && (cv_timetic.value == 2 || modeattacking)) // there's not enough room for tics in splitscreen, don't even bother trying! + if (!splitscreen && (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking)) // there's not enough room for tics in splitscreen, don't even bother trying! { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics @@ -663,7 +664,7 @@ static void ST_drawTime(void) static inline void ST_drawRings(void) { - INT32 ringnum = max(stplyr->rings, 0); + INT32 ringnum; ST_DrawPatchFromHudWS(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); @@ -677,8 +678,13 @@ static inline void ST_drawRings(void) if (playeringame[i] && players[i].mo && players[i].rings > 0) ringnum += players[i].rings; } + else + ringnum = max(stplyr->rings, 0); - ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + if (!splitscreen && cv_timetic.value == 3) // Yes, even in modeattacking + ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + else + ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } static void ST_drawLives(void) diff --git a/src/st_stuff.h b/src/st_stuff.h index ddb119fb8..9be37b502 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -86,6 +86,7 @@ typedef enum HUD_RINGSSPLIT, HUD_RINGSNUM, HUD_RINGSNUMSPLIT, + HUD_RINGSNUMTICS, HUD_SCORE, HUD_SCORENUM, diff --git a/src/v_video.c b/src/v_video.c index fa366eb65..20fe9229e 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -525,22 +525,6 @@ static inline UINT8 transmappedpdraw(const UINT8 *dest, const UINT8 *source, fix return *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff)); } -static UINT8 staticstep = 0; -static fixed_t staticval = 0; - -static inline UINT8 staticpdraw(const UINT8 *dest, const UINT8 *source, fixed_t ofs) -{ - UINT8 val = source[ofs>>FRACBITS]; - (void)dest; - if ((++staticstep) >= 4) - { - staticstep = 0; - staticval = M_RandomFixed(); - } - if (val < 7) return val; - return ((staticval>>staticstep)&7)+(val-7); -} - // Draws a patch scaled to arbitrary size. void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, const UINT8 *colormap) { @@ -571,25 +555,18 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t patchdrawfunc = standardpdraw; v_translevel = NULL; - if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT)) == 12) // static + if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT))) { - alphalevel = 0; - patchdrawfunc = staticpdraw; - } - else - { - if (alphalevel) - { - if (alphalevel == 13) - alphalevel = hudminusalpha[cv_translucenthud.value]; - else if (alphalevel == 14) - alphalevel = 10 - cv_translucenthud.value; - else if (alphalevel == 15) - alphalevel = hudplusalpha[cv_translucenthud.value]; + if (alphalevel == 13) + alphalevel = hudminusalpha[cv_translucenthud.value]; + else if (alphalevel == 14) + alphalevel = 10 - cv_translucenthud.value; + else if (alphalevel == 15) + alphalevel = hudplusalpha[cv_translucenthud.value]; + + if (alphalevel >= 10) + return; // invis - if (alphalevel >= 10) - return; // invis - } if (alphalevel) { v_translevel = transtables + ((alphalevel-1)<> V_ALPHASHIFT))) + { + if (alphalevel == 13) + alphalevel = hudminusalpha[cv_translucenthud.value]; + else if (alphalevel == 14) + alphalevel = 10 - cv_translucenthud.value; + else if (alphalevel == 15) + alphalevel = hudplusalpha[cv_translucenthud.value]; + + if (alphalevel >= 10) + return; // invis + + if (alphalevel) + { + v_translevel = transtables + ((alphalevel-1)<>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++) + for (col = sx<>FRACBITS) < SHORT(patch->width) && ((col>>FRACBITS) - sx) < w; col += colfrac, ++x, desttop++) { INT32 topdelta, prevdelta = -1; if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION) @@ -863,10 +866,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ dest = desttop; dest += FixedInt(FixedMul(topdelta<>FRACBITS) < column->length && ((ofs>>FRACBITS) + topdelta) < h; ofs += rowfrac) + for (ofs = sy<>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac) { if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION) - *dest = source[ofs>>FRACBITS]; + *dest = patchdrawfunc(dest, source, ofs); dest += vid.width; } column = (const column_t *)((const UINT8 *)column + column->length + 4); diff --git a/src/v_video.h b/src/v_video.h index 3781f3337..f9fd475f4 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -94,7 +94,6 @@ extern RGBA_t *pMasterPalette; #define V_70TRANS 0x00070000 #define V_80TRANS 0x00080000 // used to be V_8020TRANS #define V_90TRANS 0x00090000 -#define V_STATIC 0x000C0000 // ogl unsupported kthnxbai #define V_HUDTRANSHALF 0x000D0000 #define V_HUDTRANS 0x000E0000 // draw the hud translucent #define V_HUDTRANSDOUBLE 0x000F0000 diff --git a/src/y_inter.c b/src/y_inter.c index 0907d396c..0812ba80f 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -205,7 +205,7 @@ static void Y_IntermissionTokenDrawer(void) calc = (lowy - y)*2; if (calc > 0) - V_DrawCroppedPatch(32<width), calc); + V_DrawCroppedPatch(32<width), calc); } // @@ -764,6 +764,8 @@ void Y_Ticker(void) data.coop.total += data.coop.bonuses[i].points; data.coop.bonuses[i].points = 0; } + if (data.coop.score > MAXSCORE) + data.coop.score = MAXSCORE; if (data.coop.bonuses[i].points > 0) anybonuses = true; } @@ -1765,6 +1767,8 @@ static void Y_AwardCoopBonuses(void) { (bonuses_list[bonusnum][j])(&players[i], &localbonuses[j]); players[i].score += localbonuses[j].points; + if (players[i].score > MAXSCORE) + players[i].score = MAXSCORE; } ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; @@ -1807,6 +1811,8 @@ static void Y_AwardSpecialStageBonus(void) else Y_SetRingBonus(&players[i], &localbonus); players[i].score += localbonus.points; + if (players[i].score > MAXSCORE) + players[i].score = MAXSCORE; // grant extra lives right away since tally is faked ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0;