Merge branch 'more_about_menus' into 'master'

More about menus

Closes #72

See merge request STJr/SRB2Internal!122
This commit is contained in:
toaster 2017-11-02 16:31:51 -04:00
commit 605e51f6f3
20 changed files with 404 additions and 267 deletions

View File

@ -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();
}

View File

@ -340,6 +340,7 @@ static void D_Display(void)
case GS_EVALUATION:
F_GameEvaluationDrawer();
HU_Erase();
HU_Drawer();
break;

View File

@ -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)

View File

@ -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},

View File

@ -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

View File

@ -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;)

View File

@ -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;

View File

@ -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

View File

@ -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<<FRACBITS, y<<FRACBITS, FRACUNIT/2, flags, patch, staticalong, 0, sw, h*2); // FixedDiv(h, scale)); -- for scale FRACUNIT/2
staticalong += sw; //M_RandomRange(sw/2, 2*sw); -- turns out less randomisation looks better because immediately adjacent frames can't end up close to each other
W_UnlockCachedPatch(patch);
}
//
// Draw border for the savegame description
//
@ -3816,16 +3811,23 @@ static boolean M_LevelAvailableOnPlatter(INT32 mapnum)
switch (levellistmode)
{
case LLM_CREATESERVER:
if (!(mapheaderinfo[mapnum]->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<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, SHORT(patch->height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height));
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, SHORT(patch->height) + 2*(o-32), SHORT(patch->width), 64 - 2*o);
else
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, SHORT(patch->height) - 32 + o, SHORT(patch->width), SHORT(patch->height));
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, SHORT(patch->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<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT/2, 0, patch, 0, 0, SHORT(patch->width), o*2);
V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT/2, 0, patch, 0, 0, SHORT(patch->width), 2*o);
else
V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT, 0, patch, 0, 0, SHORT(patch->width), o);
W_UnlockCachedPatch(patch);
@ -6875,9 +6971,9 @@ static void M_DrawSetupChoosePlayerMenu(void)
else
{
if (SHORT(patch->width) >= 256)
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, (o-32)*2, SHORT(patch->width), SHORT(patch->height));
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, (o-32)*2, SHORT(patch->width), SHORT(patch->height) - 2*(o-32));
else
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, (o-32), SHORT(patch->width), SHORT(patch->height));
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, (o-32), SHORT(patch->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

View File

@ -201,6 +201,7 @@ typedef struct
// descriptions for gametype select screen
typedef struct
{
UINT8 col[2];
char notes[441];
} gtdesc_t;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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;

View File

@ -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)

View File

@ -86,6 +86,7 @@ typedef enum
HUD_RINGSSPLIT,
HUD_RINGSNUM,
HUD_RINGSNUMSPLIT,
HUD_RINGSNUMTICS,
HUD_SCORE,
HUD_SCORENUM,

View File

@ -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)<<FF_TRANSSHIFT);
@ -763,6 +740,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
// Draws a patch cropped and scaled to arbitrary size.
void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h)
{
UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t);
UINT32 alphalevel = 0;
// boolean flip = false;
fixed_t col, ofs, colfrac, rowfrac, fdup;
INT32 dupx, dupy;
const column_t *column;
@ -781,6 +762,28 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
}
#endif
patchdrawfunc = standardpdraw;
v_translevel = NULL;
if ((alphalevel = ((scrn & V_ALPHAMASK) >> 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)<<FF_TRANSSHIFT);
patchdrawfunc = translucentpdraw;
}
}
// only use one dup, to avoid stretching (har har)
dupx = dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
fdup = FixedMul(dupx<<FRACBITS, pscale);
@ -844,7 +847,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
desttop += (y*vid.width) + x;
}
for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++)
for (col = sx<<FRACBITS; (col>>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,fdup))*vid.width;
for (ofs = sy<<FRACBITS; dest < deststop && (ofs>>FRACBITS) < column->length && ((ofs>>FRACBITS) + topdelta) < h; ofs += rowfrac)
for (ofs = sy<<FRACBITS; dest < deststop && (ofs>>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);

View File

@ -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

View File

@ -205,7 +205,7 @@ static void Y_IntermissionTokenDrawer(void)
calc = (lowy - y)*2;
if (calc > 0)
V_DrawCroppedPatch(32<<FRACBITS, y<<FRACBITS, FRACUNIT/2, 0, tokenicon, 32*FRACUNIT, y<<FRACBITS, SHORT(tokenicon->width), calc);
V_DrawCroppedPatch(32<<FRACBITS, y<<FRACBITS, FRACUNIT/2, 0, tokenicon, 0, 0, SHORT(tokenicon->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;