Merge branch 'hud-n-menu-tidbits' into 'master'

Improved addons menu performance and other HUD tidbits

See merge request STJr/SRB2Internal!151
This commit is contained in:
Digiku 2018-11-21 16:29:24 -05:00
commit 973df61ec2
20 changed files with 597 additions and 319 deletions

View file

@ -281,7 +281,7 @@ static void D_Display(void)
if (rendermode != render_none)
{
// Fade to black first
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) // fades to black on its own timing, always
if ((wipegamestate != (gamestate_t)-2) // fades to black on its own timing, always
&& wipedefs[wipedefindex] != UINT8_MAX)
{
F_WipeStartScreen();
@ -359,89 +359,96 @@ static void D_Display(void)
break;
}
// clean up border stuff
// see if the border needs to be initially drawn
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
// STUPID race condition...
if (wipegamestate == GS_INTRO && gamestate == GS_TITLESCREEN)
wipegamestate = -2;
else
{
// draw the view directly
wipegamestate = gamestate;
if (!automapactive && !dedicated && cv_renderview.value)
// clean up border stuff
// see if the border needs to be initially drawn
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
{
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
objectsdrawn = 0;
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(0, &players[displayplayer]);
else
#endif
if (rendermode != render_none)
R_RenderPlayerView(&players[displayplayer]);
}
// draw the view directly
// render the second screen
if (splitscreen && players[secondarydisplayplayer].mo)
if (!automapactive && !dedicated && cv_renderview.value)
{
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
else
#endif
if (rendermode != render_none)
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{
viewwindowy = vid.height / 2;
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
objectsdrawn = 0;
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(0, &players[displayplayer]);
else
#endif
if (rendermode != render_none)
R_RenderPlayerView(&players[displayplayer]);
}
R_RenderPlayerView(&players[secondarydisplayplayer]);
// render the second screen
if (splitscreen && players[secondarydisplayplayer].mo)
{
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
else
#endif
if (rendermode != render_none)
{
viewwindowy = vid.height / 2;
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
viewwindowy = 0;
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
R_RenderPlayerView(&players[secondarydisplayplayer]);
viewwindowy = 0;
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
}
}
// Image postprocessing effect
if (rendermode == render_soft)
{
if (postimgtype)
V_DoPostProcessor(0, postimgtype, postimgparam);
if (postimgtype2)
V_DoPostProcessor(1, postimgtype2, postimgparam2);
}
}
// Image postprocessing effect
if (rendermode == render_soft)
if (lastdraw)
{
if (postimgtype)
V_DoPostProcessor(0, postimgtype, postimgparam);
if (postimgtype2)
V_DoPostProcessor(1, postimgtype2, postimgparam2);
if (rendermode == render_soft)
{
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
usebuffer = true;
}
lastdraw = false;
}
}
if (lastdraw)
{
if (rendermode == render_soft)
if (gamestate == GS_LEVEL)
{
VID_BlitLinearScreen(screens[0], screens[1], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
usebuffer = true;
ST_Drawer();
F_TextPromptDrawer();
HU_Drawer();
}
lastdraw = false;
else
F_TitleScreenDrawer();
}
if (gamestate == GS_LEVEL)
{
ST_Drawer();
F_TextPromptDrawer();
HU_Drawer();
}
else
F_TitleScreenDrawer();
}
// change gamma if needed
// (GS_LEVEL handles this already due to level-specific palettes)
if (forcerefresh && gamestate != GS_LEVEL)
if (forcerefresh && !(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
V_SetPalette(0);
wipegamestate = gamestate;
// draw pause pic
if (paused && cv_showhud.value && (!menuactive || netgame))
{
#if 0
INT32 py;
patch_t *patch;
if (automapactive)
@ -450,6 +457,11 @@ static void D_Display(void)
py = viewwindowy + 4;
patch = W_CachePatchName("M_PAUSE", PU_CACHE);
V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch);
#else
INT32 y = ((automapactive) ? (32) : (BASEVIDHEIGHT/2));
M_DrawTextBox((BASEVIDWIDTH/2) - (60), y - (16), 13, 2);
V_DrawCenteredString(BASEVIDWIDTH/2, y - (4), V_YELLOWMAP, "Game Paused");
#endif
}
// vid size change is now finished if it was on...

View file

@ -3105,26 +3105,14 @@ static void Command_Addfile(void)
if (*p == '\\' || *p == '/' || *p == ':')
break;
++p;
// check total packet size and no of files currently loaded
// See W_LoadWadFile in w_wad.c
if ((numwadfiles >= MAX_WADFILES)
|| ((packetsizetally + nameonlylength(fn) + 22) > MAXFILENEEDED*sizeof(UINT8)))
{
size_t packetsize = 0;
serverinfo_pak *dummycheck = NULL;
// Shut the compiler up.
(void)dummycheck;
// See W_LoadWadFile in w_wad.c
for (i = 0; i < numwadfiles; i++)
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
packetsize += nameonlylength(fn) + 22;
if ((numwadfiles >= MAX_WADFILES)
|| (packetsize > sizeof(dummycheck->fileneeded)))
{
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
return;
}
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
return;
}
WRITESTRINGN(buf_p,p,240);
@ -3174,11 +3162,6 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
boolean kick = false;
boolean toomany = false;
INT32 i;
size_t packetsize = 0;
serverinfo_pak *dummycheck = NULL;
// Shut the compiler up.
(void)dummycheck;
READSTRINGN(*cp, filename, 240);
READMEM(*cp, md5sum, 16);
@ -3205,13 +3188,8 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
}
// See W_LoadWadFile in w_wad.c
for (i = 0; i < numwadfiles; i++)
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
packetsize += nameonlylength(filename) + 22;
if ((numwadfiles >= MAX_WADFILES)
|| (packetsize > sizeof(dummycheck->fileneeded)))
|| ((packetsizetally + nameonlylength(filename) + 22) > MAXFILENEEDED*sizeof(UINT8)))
toomany = true;
else
ncs = findfile(filename,md5sum,true);
@ -3364,6 +3342,9 @@ static void Command_Playintro_f(void)
if (netgame)
return;
if (dirmenu)
closefilemenu(true);
F_StartIntro();
}
@ -4012,6 +3993,9 @@ void Command_ExitGame_f(void)
cv_debug = 0;
emeralds = 0;
if (dirmenu)
closefilemenu(true);
if (!modeattacking)
D_StartTitle();
}

View file

@ -324,10 +324,6 @@ INT32 CL_CheckFiles(void)
INT32 ret = 1;
size_t packetsize = 0;
size_t filestoget = 0;
serverinfo_pak *dummycheck = NULL;
// Shut the compiler up.
(void)dummycheck;
// if (M_CheckParm("-nofiles"))
// return 1;
@ -371,8 +367,7 @@ INT32 CL_CheckFiles(void)
}
// See W_LoadWadFile in w_wad.c
for (i = 0; i < numwadfiles; i++)
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
packetsize = packetsizetally;
for (i = 1; i < fileneedednum; i++)
{
@ -396,7 +391,7 @@ INT32 CL_CheckFiles(void)
packetsize += nameonlylength(fileneeded[i].filename) + 22;
if ((numwadfiles+filestoget >= MAX_WADFILES)
|| (packetsize > sizeof(dummycheck->fileneeded)))
|| (packetsize > MAXFILENEEDED*sizeof(UINT8)))
return 3;
filestoget++;
@ -899,10 +894,11 @@ void nameonly(char *s)
{
ns = &(s[j+1]);
len = strlen(ns);
if (false)
M_Memcpy(s, ns, len+1);
else
memmove(s, ns, len+1);
#if 0
M_Memcpy(s, ns, len+1);
#else
memmove(s, ns, len+1);
#endif
return;
}
}

View file

@ -29,6 +29,7 @@
#include "g_input.h"
#include "console.h"
#include "m_random.h"
#include "m_misc.h" // moviemode functionality
#include "y_inter.h"
#include "m_cond.h"
#include "p_local.h"
@ -331,7 +332,7 @@ void F_StartIntro(void)
introtext[2] = M_GetText(
"As it was about to drain the rings\n"
"away from the planet, Sonic burst into\n"
"the Satellite and for what he thought\n"
"the control room and for what he thought\n"
"would be the last time,\xB4 defeated\n"
"Dr. Eggman.\n#");
@ -341,11 +342,11 @@ void F_StartIntro(void)
"return,\xB8 bringing an all new threat.\n#");
introtext[4] = M_GetText(
"\xA8""About once every year, a strange asteroid\n"
"\xA8""About every five years, a strange asteroid\n"
"hovers around the planet.\xBF It suddenly\n"
"appears from nowhere, circles around, and\n"
"\xB6- just as mysteriously as it arrives -\xB6\n"
"vanishes after about one week.\xBF\n"
"vanishes after only one week.\xBF\n"
"No one knows why it appears, or how.\n#");
introtext[5] = M_GetText(
@ -398,7 +399,7 @@ void F_StartIntro(void)
"\xA5\"6...\xD2""5...\xD2""4...\"\xA8\xD2\n"
"Sonic knew he was getting closer to the\n"
"zone, and pushed himself harder.\xB4 Finally,\n"
"the mountain appeared in the horizon.\xD2\xD2\n"
"the mountain appeared on the horizon.\xD2\xD2\n"
"\xA5\"3...\xD2""2...\xD2""1...\xD2""Zero.\"\n#");
introtext[11] = M_GetText(
@ -831,18 +832,27 @@ void F_IntroDrawer(void)
// Stay on black for a bit. =)
{
tic_t quittime;
quittime = I_GetTime() + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds
while (quittime > I_GetTime())
tic_t nowtime, quittime, lasttime;
nowtime = lasttime = I_GetTime();
quittime = nowtime + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds
while (quittime > nowtime)
{
while (!((nowtime = I_GetTime()) - lasttime))
I_Sleep();
lasttime = nowtime;
I_OsPolling();
I_UpdateNoBlit();
M_Drawer(); // menu is drawn even on top of wipes
I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame();
}
}
D_StartTitle();
wipegamestate = GS_INTRO;
return;
}
F_NewCutscene(introtext[++intro_scenenum]);
@ -1547,7 +1557,7 @@ void F_TitleScreenDrawer(void)
if (!titlemapinaction)
F_SkyScroll(titlescrollspeed);
// Don't draw outside of the title screewn, or if the patch isn't there.
// Don't draw outside of the title screen, or if the patch isn't there.
if (!ttwing || (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS))
return;
@ -1892,6 +1902,9 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
G_SetGamestate(GS_CUTSCENE);
if (wipegamestate == GS_CUTSCENE)
wipegamestate = -1;
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();

View file

@ -306,9 +306,14 @@ closedir (DIR * dirp)
}
#endif
static CV_PossibleValue_t addons_cons_t[] = {{0, "SRB2 Folder"}, /*{1, "HOME"}, {2, "SRB2 Folder"},*/ {3, "CUSTOM"}, {0, NULL}};
consvar_t cv_addons_option = {"addons_option", "SRB2 Folder", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_addons_folder = {"addons_folder", "./", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"},
#if 1
{1, "HOME"}, {2, "SRB2"},
#endif
{3, "CUSTOM"}, {0, NULL}};
consvar_t cv_addons_option = {"addons_option", "Default", CV_SAVE|CV_CALL, addons_cons_t, Addons_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_addons_folder = {"addons_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t addons_md5_cons_t[] = {{0, "Name"}, {1, "Contents"}, {0, NULL}};
consvar_t cv_addons_md5 = {"addons_md5", "Name", CV_SAVE, addons_md5_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -326,10 +331,11 @@ size_t menudepthleft = menudepth;
char menusearch[MAXSTRINGLENGTH+1];
char **dirmenu;
size_t sizedirmenu;
char **dirmenu, **coredirmenu; // core only local for this file
size_t sizedirmenu, sizecoredirmenu; // ditto
size_t dir_on[menudepth];
UINT8 refreshdirmenu = 0;
char *refreshdirname = NULL;
size_t packetsizetally = 0;
size_t mainwadstally = 0;
@ -362,9 +368,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
return FS_NOTFOUND;
}
if (searchpath[searchpathindex[depthleft]-2] != '/')
if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0])
{
searchpath[searchpathindex[depthleft]-1] = '/';
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
searchpath[searchpathindex[depthleft]] = 0;
}
else
@ -406,7 +412,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
depthleft++;
}
searchpath[searchpathindex[depthleft]-1]='/';
searchpath[searchpathindex[depthleft]-1]=PATHSEP[0];
searchpath[searchpathindex[depthleft]]=0;
}
else if (!strcasecmp(searchname, dent->d_name))
@ -446,7 +452,7 @@ char exttable[NUM_EXT_TABLE][5] = {
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
static boolean filemenusearch(char *haystack, char *needle)
static boolean filemenucmp(char *haystack, char *needle)
{
static char localhaystack[128];
strlcpy(localhaystack, haystack, 128);
@ -457,21 +463,151 @@ static boolean filemenusearch(char *haystack, char *needle)
: (!strncmp(localhaystack, needle, menusearch[0])));
}
#define searchdir if (menusearch[0] && !filemenusearch(dent->d_name, localmenusearch))\
{\
rejected++;\
continue;\
}\
void closefilemenu(boolean validsize)
{
// search
if (dirmenu)
{
if (dirmenu != coredirmenu)
{
if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS))
{
Z_Free(dirmenu[0]);
dirmenu[0] = NULL;
}
Z_Free(dirmenu);
}
dirmenu = NULL;
sizedirmenu = 0;
}
if (coredirmenu)
{
// core
if (validsize)
{
for (; sizecoredirmenu > 0; sizecoredirmenu--)
{
Z_Free(coredirmenu[sizecoredirmenu-1]);
coredirmenu[sizecoredirmenu-1] = NULL;
}
}
else
sizecoredirmenu = 0;
Z_Free(coredirmenu);
coredirmenu = NULL;
}
if (refreshdirname)
Z_Free(refreshdirname);
refreshdirname = NULL;
}
void searchfilemenu(char *tempname)
{
size_t i, first;
char localmenusearch[MAXSTRINGLENGTH] = "";
if (dirmenu)
{
if (dirmenu != coredirmenu)
{
if (dirmenu[0] && ((UINT8)(dirmenu[0][DIR_TYPE]) == EXT_NORESULTS))
{
Z_Free(dirmenu[0]);
dirmenu[0] = NULL;
}
//Z_Free(dirmenu); -- Z_Realloc later tho...
}
else
dirmenu = NULL;
}
first = (((UINT8)(coredirmenu[0][DIR_TYPE]) == EXT_UP) ? 1 : 0); // skip UP...
if (!menusearch[0])
{
if (dirmenu)
Z_Free(dirmenu);
dirmenu = coredirmenu;
sizedirmenu = sizecoredirmenu;
if (tempname)
{
for (i = first; i < sizedirmenu; i++)
{
if (!strcmp(dirmenu[i]+DIR_STRING, tempname))
{
dir_on[menudepthleft] = i;
break;
}
}
if (i == sizedirmenu)
dir_on[menudepthleft] = first;
Z_Free(tempname);
}
return;
}
strcpy(localmenusearch, menusearch+1);
if (!cv_addons_search_case.value)
strupr(localmenusearch);
sizedirmenu = 0;
for (i = first; i < sizecoredirmenu; i++)
{
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
sizedirmenu++;
}
if (!sizedirmenu) // no results...
{
if ((!(dirmenu = Z_Realloc(dirmenu, sizeof(char *), PU_STATIC, NULL)))
|| !(dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS))))
I_Error("Ran out of memory whilst preparing add-ons menu");
sizedirmenu = 1;
dir_on[menudepthleft] = 0;
if (tempname)
Z_Free(tempname);
return;
}
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
I_Error("Ran out of memory whilst preparing add-ons menu");
sizedirmenu = 0;
for (i = first; i < sizecoredirmenu; i++)
{
if (filemenucmp(coredirmenu[i]+DIR_STRING, localmenusearch))
{
if (tempname && !strcmp(coredirmenu[i]+DIR_STRING, tempname))
{
dir_on[menudepthleft] = sizedirmenu;
Z_Free(tempname);
tempname = NULL;
}
dirmenu[sizedirmenu++] = coredirmenu[i]; // pointer reuse
}
}
if (tempname)
{
dir_on[menudepthleft] = 0;
Z_Free(tempname);
}
}
boolean preparefilemenu(boolean samedepth)
{
DIR *dirhandle;
struct dirent *dent;
struct stat fsstat;
size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0;
size_t pos = 0, folderpos = 0, numfolders = 0;
char *tempname = NULL;
boolean noresults = false;
char localmenusearch[MAXSTRINGLENGTH] = "";
if (samedepth)
{
@ -481,20 +617,16 @@ boolean preparefilemenu(boolean samedepth)
else
menusearch[0] = menusearch[1] = 0; // clear search
for (; sizedirmenu > 0; sizedirmenu--) // clear out existing items
if (!(dirhandle = opendir(menupath))) // get directory
{
Z_Free(dirmenu[sizedirmenu-1]);
dirmenu[sizedirmenu-1] = NULL;
closefilemenu(true);
return false;
}
if (!(dirhandle = opendir(menupath))) // get directory
return false;
if (menusearch[0])
for (; sizecoredirmenu > 0; sizecoredirmenu--) // clear out existing items
{
strcpy(localmenusearch, menusearch+1);
if (!cv_addons_search_case.value)
strupr(localmenusearch);
Z_Free(coredirmenu[sizecoredirmenu-1]);
coredirmenu[sizecoredirmenu-1] = NULL;
}
while (true)
@ -526,43 +658,42 @@ boolean preparefilemenu(boolean samedepth)
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison
if (ext == NUM_EXT_TABLE) continue; // not an addfile-able (or exec-able) file
}
searchdir;
}
else // directory
{
searchdir;
numfolders++;
}
sizedirmenu++;
sizecoredirmenu++;
}
}
if (!rejected && !sizedirmenu)
if (!sizecoredirmenu)
{
closedir(dirhandle);
closefilemenu(false);
if (tempname)
Z_Free(tempname);
closedir(dirhandle);
return false;
}
if (((noresults = (menusearch[0] && !sizedirmenu)))
|| (!menusearch[0] && menudepthleft != menudepth-1)) // Make room for UP... or search entry
if (menudepthleft != menudepth-1) // Make room for UP...
{
sizedirmenu++;
sizecoredirmenu++;
numfolders++;
folderpos++;
}
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*sizeof(char *), PU_STATIC, NULL)))
if (dirmenu && dirmenu == coredirmenu)
dirmenu = NULL;
if (!(coredirmenu = Z_Realloc(coredirmenu, sizecoredirmenu*sizeof(char *), PU_STATIC, NULL)))
{
closedir(dirhandle); // just in case
I_Error("Ran out of memory whilst preparing add-ons menu");
}
rejected = 0;
rewinddir(dirhandle);
while ((pos+folderpos) < sizedirmenu)
while ((pos+folderpos) < sizecoredirmenu)
{
menupath[menupathindex[menudepthleft]] = 0;
dent = readdir(dirhandle);
@ -588,14 +719,12 @@ boolean preparefilemenu(boolean samedepth)
if (!S_ISDIR(fsstat.st_mode)) // file
{
if (!((numfolders+pos) < sizedirmenu)) continue; // crash prevention
if (!((numfolders+pos) < sizecoredirmenu)) continue; // crash prevention
for (; ext < NUM_EXT_TABLE; ext++)
if (!strcasecmp(exttable[ext], dent->d_name+len-5)) break; // extension comparison
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file
ext += EXT_START; // moving to be appropriate position
searchdir;
if (ext >= EXT_LOADSTART)
{
size_t i;
@ -628,10 +757,7 @@ boolean preparefilemenu(boolean samedepth)
folder = 0;
}
else // directory
{
searchdir;
len += (folder = 1);
}
if (len > 255)
len = 255;
@ -643,46 +769,31 @@ boolean preparefilemenu(boolean samedepth)
strlcpy(temp+DIR_STRING, dent->d_name, len);
if (folder)
{
strcpy(temp+len, "/");
dirmenu[folderpos++] = temp;
strcpy(temp+len, PATHSEP);
coredirmenu[folderpos++] = temp;
}
else
dirmenu[numfolders + pos++] = temp;
coredirmenu[numfolders + pos++] = temp;
}
}
closedir(dirhandle);
if (noresults) // no results
dirmenu[0] = Z_StrDup(va("%c\13No results...", EXT_NORESULTS));
else if (!menusearch[0] &&menudepthleft != menudepth-1) // now for UP... entry
dirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP));
if ((menudepthleft != menudepth-1) // now for UP... entry
&& !(coredirmenu[0] = Z_StrDup(va("%c\5UP...", EXT_UP))))
I_Error("Ran out of memory whilst preparing add-ons menu");
menupath[menupathindex[menudepthleft]] = 0;
sizedirmenu = (numfolders+pos); // just in case things shrink between opening and rewind
sizecoredirmenu = (numfolders+pos); // just in case things shrink between opening and rewind
if (tempname)
{
size_t i;
for (i = 0; i < sizedirmenu; i++)
{
if (!strcmp(dirmenu[i]+DIR_STRING, tempname))
{
dir_on[menudepthleft] = i;
break;
}
}
Z_Free(tempname);
}
if (!sizedirmenu)
if (!sizecoredirmenu)
{
dir_on[menudepthleft] = 0;
Z_Free(dirmenu);
closefilemenu(false);
return false;
}
else if (dir_on[menudepthleft] >= sizedirmenu)
dir_on[menudepthleft] = sizedirmenu-1;
searchfilemenu(tempname);
return true;
}

View file

@ -40,6 +40,7 @@ extern char **dirmenu;
extern size_t sizedirmenu;
extern size_t dir_on[menudepth];
extern UINT8 refreshdirmenu;
extern char *refreshdirname;
extern size_t packetsizetally;
extern size_t mainwadstally;
@ -87,6 +88,8 @@ typedef enum
REFRESHDIR_MAX = 32
} refreshdir_enum;
void closefilemenu(boolean validsize);
void searchfilemenu(char *tempname);
boolean preparefilemenu(boolean samedepth);
#endif // __FILESRCH_H__

View file

@ -328,19 +328,21 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
consvar_t cv_crosshair = {"crosshair", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_crosshair2 = {"crosshair2", "Cross", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_invertmouse = {"invertmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_alwaysfreelook = {"alwaysmlook", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_alwaysfreelook = {"alwaysmlook", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_invertmouse2 = {"invertmouse2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_alwaysfreelook2 = {"alwaysmlook2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousemove = {"mousemove", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousemove2 = {"mousemove2", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_analog = {"analog", "Off", CV_CALL, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_analog2 = {"analog2", "Off", CV_CALL, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog = {"useranalog", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog2 = {"useranalog2", "Off", CV_SAVE|CV_CALL, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousemove = {"mousemove", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mousemove2 = {"mousemove2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}};
// previously "analog", "analog2", "useranalog", and "useranalog2", invalidating 2.1-era copies of config.cfg
// changed because it'd be nice to see people try out our actually good controls with gamepads now autobrake exists
consvar_t cv_analog = {"sessionanalog", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_analog2 = {"sessionanalog2", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog = {"configanalog", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_useranalog2 = {"configanalog2", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL};
// deez New User eXperiences
static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}};
consvar_t cv_directionchar = {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL};
@ -1650,7 +1652,8 @@ void G_DoLoadLevel(boolean resetplayer)
CON_ClearHUD();
}
static INT32 pausedelay = 0;
INT32 pausedelay = 0;
boolean pausebreakkey = false;
static INT32 camtoggledelay, camtoggledelay2 = 0;
//
@ -1798,19 +1801,35 @@ boolean G_Responder(event_t *ev)
{
case ev_keydown:
if (ev->data1 == gamecontrol[gc_pause][0]
|| ev->data1 == gamecontrol[gc_pause][1])
|| ev->data1 == gamecontrol[gc_pause][1]
|| ev->data1 == KEY_PAUSE)
{
if (!pausedelay)
if (modeattacking && !demoplayback && (gamestate == GS_LEVEL))
{
// don't let busy scripts prevent pausing
pausedelay = NEWTICRATE/7;
pausebreakkey = (ev->data1 == KEY_PAUSE);
if (menuactive || pausedelay < 0 || leveltime < 2)
return true;
// command will handle all the checks for us
COM_ImmedExecute("pause");
return true;
if (pausedelay < 1+(NEWTICRATE/2))
pausedelay = 1+(NEWTICRATE/2);
else if (++pausedelay > 1+(NEWTICRATE/2)+(NEWTICRATE/3))
{
G_SetRetryFlag();
return true;
}
pausedelay++; // counteract subsequent subtraction this frame
}
else
pausedelay = NEWTICRATE/7;
{
INT32 oldpausedelay = pausedelay;
pausedelay = (NEWTICRATE/7);
if (!oldpausedelay)
{
// command will handle all the checks for us
COM_ImmedExecute("pause");
return true;
}
}
}
if (ev->data1 == gamecontrol[gc_camtoggle][0]
|| ev->data1 == gamecontrol[gc_camtoggle][1])
@ -1870,11 +1889,19 @@ void G_Ticker(boolean run)
{
G_ClearRetryFlag();
// Costs a life to retry ... unless the player in question is dead already.
if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE)
players[consoleplayer].lives -= 1;
if (modeattacking)
{
pausedelay = INT32_MIN;
M_ModeAttackRetry(0);
}
else
{
// Costs a life to retry ... unless the player in question is dead already.
if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES)
players[consoleplayer].lives -= 1;
G_DoReborn(consoleplayer);
G_DoReborn(consoleplayer);
}
}
for (i = 0; i < MAXPLAYERS; i++)
@ -1973,8 +2000,13 @@ void G_Ticker(boolean run)
if (run)
{
if (pausedelay)
pausedelay--;
if (pausedelay && pausedelay != INT32_MIN)
{
if (pausedelay > 0)
pausedelay--;
else
pausedelay++;
}
if (camtoggledelay)
camtoggledelay--;
@ -2920,6 +2952,9 @@ static void G_DoCompleted(void)
tokenlist = 0; // Reset the list
if (modeattacking && pausedelay)
pausedelay = 0;
gameaction = ga_nothing;
if (metalplayback)

View file

@ -53,6 +53,8 @@ extern INT16 prevmap, nextmap;
extern INT32 gameovertics;
extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display)
extern INT16 rw_maximums[NUM_WEAPONS];
extern INT32 pausedelay;
extern boolean pausebreakkey;
// used in game menu
extern consvar_t cv_tutorialprompt;

View file

@ -709,7 +709,7 @@ void G_DefineDefaultControls(void)
gamecontroldefault[i][gc_teamkey ][0] = 'y';
gamecontroldefault[i][gc_scores ][0] = KEY_TAB;
gamecontroldefault[i][gc_console ][0] = KEY_CONSOLE;
gamecontroldefault[i][gc_pause ][0] = KEY_PAUSE;
gamecontroldefault[i][gc_pause ][0] = 'p';
}
}
@ -814,6 +814,8 @@ static void setcontrol(INT32 (*gc)[2], INT32 na)
return;
}
keynum = G_KeyStringtoNum(COM_Argv(2));
if (keynum == KEY_PAUSE) // fail silently; pause is hardcoded
return;
G_CheckDoubleUsage(keynum);
gc[numctrl][0] = keynum;

View file

@ -29,6 +29,7 @@
#include "../m_argv.h"
#include "../i_video.h"
#include "../w_wad.h"
#include "../p_setup.h" // levelfadecol
// --------------------------------------------------------------------------
// This is global data for planes rendering
@ -644,7 +645,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
sprintf(s, "%d%%", (++ls_percent)<<1);
x = BASEVIDWIDTH/2;
y = BASEVIDHEIGHT/2;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Black background to match fade in effect
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); // Background to match fade in effect
//V_DrawPatchFill(W_CachePatchName("SRB2BACK",PU_CACHE)); // SRB2 background, ehhh too bright.
M_DrawTextBox(x-58, y-8, 13, 1);
V_DrawString(x-50, y, V_YELLOWMAP, "Loading...");

View file

@ -1040,25 +1040,29 @@ UINT16 hu_demorings;
static void HU_DrawDemoInfo(void)
{
V_DrawString(4, 188-24, V_YELLOWMAP, va(M_GetText("%s's replay"), player_names[0]));
INT32 h = 188;
if (modeattacking == ATTACKING_NIGHTS)
h -= 12;
V_DrawString(4, h-24, V_YELLOWMAP|V_ALLOWLOWERCASE, va(M_GetText("%s's replay"), player_names[0]));
if (modeattacking)
{
V_DrawString(4, 188-16, V_YELLOWMAP|V_MONOSPACE, "SCORE:");
V_DrawRightAlignedString(120, 188-16, V_MONOSPACE, va("%d", hu_demoscore));
V_DrawString(4, h-16, V_YELLOWMAP|V_MONOSPACE, "SCORE:");
V_DrawRightAlignedString(120, h-16, V_MONOSPACE, va("%d", hu_demoscore));
V_DrawString(4, 188- 8, V_YELLOWMAP|V_MONOSPACE, "TIME:");
V_DrawString(4, h-8, V_YELLOWMAP|V_MONOSPACE, "TIME:");
if (hu_demotime != UINT32_MAX)
V_DrawRightAlignedString(120, 188- 8, V_MONOSPACE, va("%i:%02i.%02i",
V_DrawRightAlignedString(120, h-8, V_MONOSPACE, va("%i:%02i.%02i",
G_TicsToMinutes(hu_demotime,true),
G_TicsToSeconds(hu_demotime),
G_TicsToCentiseconds(hu_demotime)));
else
V_DrawRightAlignedString(120, 188- 8, V_MONOSPACE, "--:--.--");
V_DrawRightAlignedString(120, h-8, V_MONOSPACE, "--:--.--");
if (modeattacking == ATTACKING_RECORD)
{
V_DrawString(4, 188 , V_YELLOWMAP|V_MONOSPACE, "RINGS:");
V_DrawRightAlignedString(120, 188 , V_MONOSPACE, va("%d", hu_demorings));
V_DrawString(4, h, V_YELLOWMAP|V_MONOSPACE, "RINGS:");
V_DrawRightAlignedString(120, h, V_MONOSPACE, va("%d", hu_demorings));
}
}
}
@ -1127,6 +1131,31 @@ void HU_Drawer(void)
V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_YELLOWMAP | V_ALLOWLOWERCASE, resynch_text);
}
if (modeattacking && pausedelay > 0 && !pausebreakkey)
{
INT32 strength = ((pausedelay - 1 - NEWTICRATE/2)*10)/(NEWTICRATE/3);
INT32 y = hudinfo[HUD_LIVES].y - 13;
if (players[consoleplayer].powers[pw_carry] == CR_NIGHTSMODE)
y -= 16;
else
{
if (players[consoleplayer].pflags & PF_AUTOBRAKE)
y -= 8;
if (players[consoleplayer].pflags & PF_ANALOGMODE)
y -= 8;
}
V_DrawThinString(hudinfo[HUD_LIVES].x-2, y,
hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_SKYMAP : V_BLUEMAP),
"HOLD TO RETRY...");
if (strength > 9)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
else if (strength > 0)
V_DrawFadeScreen(0, strength);
}
}
//======================================================================

View file

@ -283,7 +283,6 @@ static void M_Statistics(INT32 choice);
static void M_ReplayTimeAttack(INT32 choice);
static void M_ChooseTimeAttack(INT32 choice);
static void M_ChooseNightsAttack(INT32 choice);
static void M_ModeAttackRetry(INT32 choice);
static void M_ModeAttackEndGame(INT32 choice);
static void M_SetGuestReplay(INT32 choice);
static void M_HandleChoosePlayerMenu(INT32 choice);
@ -343,7 +342,6 @@ static void M_EraseData(INT32 choice);
static void M_Addons(INT32 choice);
static void M_AddonsOptions(INT32 choice);
static patch_t *addonsp[NUM_EXT+6];
static UINT8 addonsresponselimit = 0;
#define numaddonsshown 4
@ -1089,7 +1087,7 @@ static menuitem_t OP_ChangeControlsMenu[] =
{IT_SPACE, NULL, NULL, NULL, 0}, // padding
{IT_CALL | IT_STRING2, NULL, "Game Status",
M_ChangeControl, gc_scores },
{IT_CALL | IT_STRING2, NULL, "Pause", M_ChangeControl, gc_pause },
{IT_CALL | IT_STRING2, NULL, "Pause / Run Retry", M_ChangeControl, gc_pause },
{IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console },
{IT_HEADER, NULL, "Multiplayer", NULL, 0},
{IT_SPACE, NULL, NULL, NULL, 0}, // padding
@ -2128,15 +2126,19 @@ static void M_GoBack(INT32 choice)
if (!Playing() && netgame && multiplayer)
{
MSCloseUDPSocket(); // Clean up so we can re-open the connection later.
netgame = false;
multiplayer = false;
netgame = multiplayer = false;
}
if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef))
{
// D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate.
Z_Free(levelselect.rows);
levelselect.rows = NULL;
if (levelselect.rows)
{
Z_Free(levelselect.rows);
levelselect.rows = NULL;
}
menuactive = false;
D_StartTitle();
}
@ -4777,22 +4779,24 @@ static void M_Addons(INT32 choice)
(void)choice;
/*if (cv_addons_option.value == 0)
pathname = srb2home; usehome ? srb2home : srb2path;
#if 1
if (cv_addons_option.value == 0)
pathname = usehome ? srb2home : srb2path;
else if (cv_addons_option.value == 1)
pathname = srb2home;
else if (cv_addons_option.value == 2)
pathname = srb2path;
else*/
else
#endif
if (cv_addons_option.value == 3 && *cv_addons_folder.string != '\0')
pathname = cv_addons_folder.string;
strlcpy(menupath, pathname, 1024);
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath) + 1;
if (menupath[menupathindex[menudepthleft]-2] != '/')
if (menupath[menupathindex[menudepthleft]-2] != PATHSEP[0])
{
menupath[menupathindex[menudepthleft]-1] = '/';
menupath[menupathindex[menudepthleft]-1] = PATHSEP[0];
menupath[menupathindex[menudepthleft]] = 0;
}
else
@ -4886,11 +4890,7 @@ static char *M_AddonsHeaderPath(void)
UINT32 len;
static char header[1024];
if (menupath[0] == '.')
strlcpy(header, va("SRB2 folder%s", menupath+1), 1024);
else
strcpy(header, menupath);
strlcpy(header, va("%s folder%s", cv_addons_option.string, menupath+menupathindex[menudepth-1]-1), 1024);
len = strlen(header);
if (len > 34)
{
@ -4907,6 +4907,15 @@ static char *M_AddonsHeaderPath(void)
M_SetupNextMenu(MISC_AddonsDef.prevMenu);\
M_StartMessage(va("\x82%s\x80\nThis folder no longer exists!\nAborting to main menu.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING)
#define CLEARNAME Z_Free(refreshdirname);\
refreshdirname = NULL
static void M_AddonsClearName(INT32 choice)
{
CLEARNAME;
M_StopMessage(choice);
}
// returns whether to do message draw
static boolean M_AddonsRefresh(void)
{
@ -4918,35 +4927,35 @@ static boolean M_AddonsRefresh(void)
if (refreshdirmenu & REFRESHDIR_ADDFILE)
{
addonsresponselimit = 0;
char *message = NULL;
if (refreshdirmenu & REFRESHDIR_NOTLOADED)
{
char *message = NULL;
S_StartSound(NULL, sfx_lose);
if (refreshdirmenu & REFRESHDIR_MAX)
message = va("\x82%s\x80\nMaximum number of add-ons reached.\nThis file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING);
message = va("\x82%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", refreshdirname);
else
message = va("\x82%s\x80\nThe file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING);
M_StartMessage(message,NULL,MM_NOTHING);
return true;
message = va("\x82%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", refreshdirname);
}
if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR))
else if (refreshdirmenu & (REFRESHDIR_WARNING|REFRESHDIR_ERROR))
{
S_StartSound(NULL, sfx_skid);
M_StartMessage(va("\x82%s\x80\nThe file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")),NULL,MM_NOTHING);
message = va("\x82%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings"));
}
if (message)
{
M_StartMessage(message,M_AddonsClearName,MM_EVENTHANDLER);
return true;
}
S_StartSound(NULL, sfx_strpst);
CLEARNAME;
}
return false;
}
#define offs 1
#ifdef FIXUPO0
#pragma GCC optimize ("0")
#endif
@ -4964,9 +4973,6 @@ static void M_DrawAddons(void)
return;
}
if (addonsresponselimit)
addonsresponselimit--;
if (Playing())
topstr = "\x85""Adding files mid-game may cause problems.";
else if (savemoddata)
@ -4976,7 +4982,7 @@ static void M_DrawAddons(void)
else
topstr = LOCATIONSTRING;
V_DrawCenteredString(BASEVIDWIDTH/2, 4+offs, 0, topstr);
V_DrawCenteredString(BASEVIDWIDTH/2, 5, 0, topstr);
if (numwadfiles <= mainwads+1)
y = 0;
@ -4996,7 +5002,7 @@ static void M_DrawAddons(void)
// DRAW MENU
x = currentMenu->x;
y = currentMenu->y + offs;
y = currentMenu->y + 1;
//M_DrawLevelPlatterHeader(y - 16, M_AddonsHeaderPath(), true, true); -- wanted different width
V_DrawString(x-21, (y - 16) + (lsheadingheight - 12), V_YELLOWMAP|V_ALLOWLOWERCASE, M_AddonsHeaderPath());
@ -5004,7 +5010,7 @@ static void M_DrawAddons(void)
V_DrawFill(x-21 + (MAXSTRINGLENGTH*8+6 - 1), (y - 16) + (lsheadingheight - 3), 1, 1, 26);
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 2), MAXSTRINGLENGTH*8+6, 1, 26);
V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 1 + offs) - (y - 1), 159);
V_DrawFill(x - 21, y - 1, MAXSTRINGLENGTH*8+6, (BASEVIDHEIGHT - currentMenu->y + 2) - (y - 1), 159);
// get bottom...
max = dir_on[menudepthleft] + numaddonsshown + 1;
@ -5060,7 +5066,7 @@ static void M_DrawAddons(void)
if (max != (ssize_t)sizedirmenu)
V_DrawString(19, y-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B");
y = BASEVIDHEIGHT - currentMenu->y + offs;
y = BASEVIDHEIGHT - currentMenu->y + 1;
M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1);
if (menusearch[0])
@ -5074,21 +5080,17 @@ static void M_DrawAddons(void)
x -= (21 + 5 + 16);
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
#define CANSAVE (!modifiedgame || savemoddata)
x = BASEVIDWIDTH - x - 16;
V_DrawSmallScaledPatch(x, y + 4, (CANSAVE ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]);
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+5]);
if (modifiedgame)
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]);
#undef CANSAVE
}
#ifdef FIXUPO0
#pragma GCC reset_options
#endif
#undef offs
static void M_AddonExec(INT32 ch)
{
if (ch != 'y' && ch != KEY_ENTER)
@ -5140,16 +5142,17 @@ static void M_HandleAddons(INT32 choice)
{
boolean exitmenu = false; // exit to previous menu
if (addonsresponselimit)
return;
if (M_ChangeStringAddons(choice))
{
if (!preparefilemenu(true))
char *tempname = NULL;
if (dirmenu && dirmenu[dir_on[menudepthleft]])
tempname = Z_StrDup(dirmenu[dir_on[menudepthleft]]+DIR_STRING); // don't need to I_Error if can't make - not important, just QoL
searchfilemenu(tempname);
/*if (!preparefilemenu(true))
{
UNEXIST;
return;
}
}*/
}
switch (choice)
@ -5248,7 +5251,6 @@ static void M_HandleAddons(INT32 choice)
case EXT_WAD:
case EXT_PK3:
COM_BufAddText(va("addfile \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
addonsresponselimit = 5;
break;
default:
S_StartSound(NULL, sfx_lose);
@ -5268,14 +5270,7 @@ static void M_HandleAddons(INT32 choice)
}
if (exitmenu)
{
for (; sizedirmenu > 0; sizedirmenu--)
{
Z_Free(dirmenu[sizedirmenu-1]);
dirmenu[sizedirmenu-1] = NULL;
}
Z_Free(dirmenu);
dirmenu = NULL;
closefilemenu(true);
// secrets disabled by addfile...
MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
@ -7980,9 +7975,10 @@ static void M_SetGuestReplay(INT32 choice)
which(0);
}
static void M_ModeAttackRetry(INT32 choice)
void M_ModeAttackRetry(INT32 choice)
{
(void)choice;
// todo -- maybe seperate this out and G_SetRetryFlag() here instead? is just calling this from the menu 100% safe?
G_CheckDemoStatus(); // Cancel recording
if (modeattacking == ATTACKING_RECORD)
M_ChooseTimeAttack(0);
@ -9384,6 +9380,7 @@ static void M_DrawControl(void)
#undef controlbuffer
static INT32 controltochange;
static char controltochangetext[55];
static void M_ChangecontrolResponse(event_t *ev)
{
@ -9391,8 +9388,8 @@ static void M_ChangecontrolResponse(event_t *ev)
INT32 found;
INT32 ch = ev->data1;
// ESCAPE cancels
if (ch != KEY_ESCAPE)
// ESCAPE cancels; dummy out PAUSE
if (ch != KEY_ESCAPE && ch != KEY_PAUSE)
{
switch (ev->type)
@ -9453,6 +9450,24 @@ static void M_ChangecontrolResponse(event_t *ev)
}
S_StartSound(NULL, sfx_strpst);
}
else if (ch == KEY_PAUSE)
{
static char tmp[155];
menu_t *prev = currentMenu->prevMenu;
if (controltochange == gc_pause)
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit cannot be used to retry runs \nduring Record Attack. \n\nHit another key for\n%s\nESC for Cancel"),
controltochangetext);
else
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"),
controltochangetext);
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
currentMenu->prevMenu = prev;
S_StartSound(NULL, sfx_s3k42);
return;
}
else
S_StartSound(NULL, sfx_skid);
@ -9469,6 +9484,7 @@ static void M_ChangeControl(INT32 choice)
controltochange = currentMenu->menuitems[choice].alphaKey;
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
currentMenu->menuitems[choice].text);
strncpy(controltochangetext, currentMenu->menuitems[choice].text, 55);
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
}

View file

@ -235,7 +235,7 @@ extern INT16 startmap;
extern INT32 ultimate_selectable;
extern INT16 char_on, startchar;
#define MAXSAVEGAMES 31 //note: last save game is "no save"
#define MAXSAVEGAMES 31
#define NOSAVESLOT 0 //slot where Play Without Saving appears
#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he
@ -246,6 +246,8 @@ void M_ForceSaveSlotSelected(INT32 sslot);
void M_CheatActivationResponder(INT32 ch);
void M_ModeAttackRetry(INT32 choice);
// Level select updating
void Nextmap_OnChange(void);

View file

@ -56,8 +56,11 @@
#include "filesrch.h" // refreshdirmenu
// wipes
#include "f_finale.h"
#ifdef HAVE_BLUA
#include "lua_hud.h" // level title
#endif
#include "f_finale.h" // wipes
#include "md5.h" // map MD5
@ -100,6 +103,7 @@ side_t *sides;
mapthing_t *mapthings;
INT32 numstarposts;
boolean levelloading;
UINT8 levelfadecol;
// BLOCKMAP
// Created from axis aligned bounding box
@ -2672,7 +2676,6 @@ boolean P_SetupLevel(boolean skipprecip)
CON_Drawer(); // let the user know what we are going to do
I_FinishUpdate(); // page flip or blit buffer
// Reset the palette
if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");
@ -2725,9 +2728,14 @@ boolean P_SetupLevel(boolean skipprecip)
// will be set by player think.
players[consoleplayer].viewz = 1;
// Cancel all d_main.c fadeouts (keep fade in though).
wipegamestate = -2;
// Special stage fade to white
// This is handled BEFORE sounds are stopped.
if (rendermode != render_none && G_IsSpecialStage(gamemap))
if (modeattacking && !demoplayback && (pausedelay == INT32_MIN))
ranspecialwipe = 2;
else if (rendermode != render_none && G_IsSpecialStage(gamemap))
{
tic_t starttime = I_GetTime();
tic_t endtime = starttime + (3*TICRATE)/2;
@ -2760,36 +2768,45 @@ boolean P_SetupLevel(boolean skipprecip)
S_StopSounds();
S_ClearSfx();
// As oddly named as this is, this handles music only.
// We should be fine starting it here.
/// ... as long as this isn't a titlemap transition, that is
if (!titlemapinaction)
{
// As oddly named as this is, this handles music only.
// We should be fine starting it here.
S_Start();
// Let's fade to black here
// But only if we didn't do the special stage wipe
if (rendermode != render_none && !ranspecialwipe)
{
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
// Let's fade to black here
// But only if we didn't do the special stage wipe
if (rendermode != render_none && !ranspecialwipe)
{
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_toblack], false);
F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_toblack], false);
}
if (ranspecialwipe == 2)
{
pausedelay = -3; // preticker plus one
S_StartSound(NULL, sfx_s3k73);
}
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
if (rendermode != render_none)
{
// Don't include these in the fade!
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE",
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : "");
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
I_UpdateNoVsync();
}
}
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
if (!titlemapinaction && rendermode != render_none)
{
// Don't include these in the fade!
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE",
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : "");
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
I_UpdateNoVsync();
}
levelfadecol = (ranspecialwipe) ? 0 : 31;
// Close text prompt before freeing the old level
F_EndTextPrompt(false, true);
@ -3138,8 +3155,8 @@ boolean P_SetupLevel(boolean skipprecip)
P_MapEnd();
// Remove the loading shit from the screen
if (rendermode != render_none)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31);
if (rendermode != render_none && !titlemapinaction)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
if (precache || dedicated)
R_PrecacheLevel();
@ -3189,6 +3206,45 @@ boolean P_SetupLevel(boolean skipprecip)
#endif
}
// Stage title!
if (rendermode != render_none
&& (!titlemapinaction)
&& ranspecialwipe != 2
&& *mapheaderinfo[gamemap-1]->lvlttl != '\0'
#ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_stagetitle)
#endif
)
{
tic_t starttime = I_GetTime();
tic_t endtime = starttime + (10*NEWTICRATERATIO);
tic_t nowtime = starttime;
tic_t lasttime = starttime;
while (nowtime < endtime)
{
// draw loop
while (!((nowtime = I_GetTime()) - lasttime))
I_Sleep();
lasttime = nowtime;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
stplyr = &players[consoleplayer];
ST_drawLevelTitle(nowtime - starttime);
if (splitscreen)
{
stplyr = &players[secondarydisplayplayer];
ST_drawLevelTitle(nowtime - starttime);
}
I_OsPolling();
I_UpdateNoBlit();
I_FinishUpdate(); // page flip or blit buffer
if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame();
}
}
return true;
}

View file

@ -27,6 +27,7 @@ extern mapthing_t *deathmatchstarts[MAX_DM_STARTS];
extern INT32 numdmstarts, numcoopstarts, numredctfstarts, numbluectfstarts;
extern boolean levelloading;
extern UINT8 levelfadecol;
extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame
//

View file

@ -786,8 +786,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
// Don't show before title card
// Not consistency safe, but this only affects drawing
if (timeinmap + 40 < 110)
player->texttimer = (UINT8)(110 - timeinmap);
if (timeinmap + 40 < (110 - 70))
player->texttimer = (UINT8)((110 - 70) - timeinmap);
}
// force NiGHTS to face forward or backward

View file

@ -441,15 +441,17 @@ void SCR_ClosedCaptions(void)
boolean gamestopped = (paused || P_AutoPause());
INT32 basey = BASEVIDHEIGHT;
if (gamestate != wipegamestate)
return;
if (gamestate == GS_LEVEL)
{
if (splitscreen)
basey -= 8;
else if ((modeattacking == ATTACKING_NIGHTS)
|| (!(maptol & TOL_NIGHTS)
&& ((cv_powerupdisplay.value == 2)
|| (cv_powerupdisplay.value == 1 && ((stplyr == &players[displayplayer] && !camera.chase)
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase))))))
&& ((cv_powerupdisplay.value == 2) // "Always"
|| (cv_powerupdisplay.value == 1 && !camera.chase)))) // "First-person only"
basey -= 16;
}

View file

@ -1123,7 +1123,7 @@ static void ST_drawInput(void)
V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!");
}
static void ST_drawLevelTitle(void)
void ST_drawLevelTitle(tic_t titletime)
{
char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
char *subttl = mapheaderinfo[gamemap-1]->subttl;
@ -1131,7 +1131,7 @@ static void ST_drawLevelTitle(void)
INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos;
INT32 subttlxpos = BASEVIDWIDTH/2;
if (!(timeinmap > 2 && timeinmap-3 < 110))
if (!(titletime > 2 && titletime-3 < 110))
return;
lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2));
@ -1151,22 +1151,22 @@ static void ST_drawLevelTitle(void)
#define MIDZONEY 105
#define MIDDIFF 4
if (timeinmap < 10)
if (titletime < 10)
{
fixed_t z = ((timeinmap - 3)<<FRACBITS)/7;
fixed_t z = ((titletime - 3)<<FRACBITS)/7;
INT32 ttlh = V_LevelNameHeight(lvlttl);
zoney = (200<<FRACBITS) - ((200 - (MIDZONEY + MIDDIFF))*z);
lvlttly = ((MIDTTLY + ttlh - MIDDIFF)*z) - (ttlh<<FRACBITS);
}
else if (timeinmap < 105)
else if (titletime < 105)
{
fixed_t z = (((timeinmap - 10)*MIDDIFF)<<(FRACBITS+1))/95;
fixed_t z = (((titletime - 10)*MIDDIFF)<<(FRACBITS+1))/95;
zoney = ((MIDZONEY + MIDDIFF)<<FRACBITS) - z;
lvlttly = ((MIDTTLY - MIDDIFF)<<FRACBITS) + z;
}
else
{
fixed_t z = ((timeinmap - 105)<<FRACBITS)/7;
fixed_t z = ((titletime - 105)<<FRACBITS)/7;
INT32 zoneh = V_LevelNameHeight(M_GetText("ZONE"));
zoney = (MIDZONEY + zoneh - MIDDIFF)*(FRACUNIT - z) - (zoneh<<FRACBITS);
lvlttly = ((MIDTTLY + MIDDIFF)<<FRACBITS) + ((200 - (MIDTTLY + MIDDIFF))*z);
@ -1177,8 +1177,8 @@ static void ST_drawLevelTitle(void)
#undef MIDDIFF
#else
// There's no consistent algorithm that can accurately define the old positions
// so I just ended up resorting to a single switct statement to define them
switch (timeinmap-3)
// so I just ended up resorting to a single switch statement to define them
switch (titletime-3)
{
case 0: zoney = 200; lvlttly = 0; break;
case 1: zoney = 188; lvlttly = 12; break;
@ -2461,12 +2461,14 @@ static void ST_overlayDrawer(void)
{
ST_drawFirstPersonHUD();
if (cv_powerupdisplay.value)
ST_drawPowerupHUD();
ST_drawPowerupHUD(); // same as it ever was...
}
else if (cv_powerupdisplay.value == 2)
ST_drawPowerupHUD();
ST_drawPowerupHUD(); // same as it ever was...
}
}
else if (!(netgame || multiplayer) && cv_powerupdisplay.value == 2)
ST_drawPowerupHUD(); // same as it ever was...
#ifdef HAVE_BLUA
if (!(netgame || multiplayer) || !hu_showscores)
@ -2479,7 +2481,7 @@ static void ST_overlayDrawer(void)
&& LUA_HudEnabled(hud_stagetitle)
#endif
)
ST_drawLevelTitle();
ST_drawLevelTitle(timeinmap+70);
if (!hu_showscores && (netgame || multiplayer)
#ifdef HAVE_BLUA
@ -2488,7 +2490,7 @@ static void ST_overlayDrawer(void)
)
ST_drawTextHUD();
if (modeattacking)
if (modeattacking && !(demoplayback && hu_showscores))
ST_drawInput();
ST_drawDebugInfo();

View file

@ -47,6 +47,9 @@ void ST_ReloadSkinFaceGraphics(void);
void ST_doPaletteStuff(void);
// level title draw
void ST_drawLevelTitle(tic_t titletime);
// return if player a is in the same team as player b
boolean ST_SameTeam(player_t *a, player_t *b);

View file

@ -340,6 +340,16 @@ UINT16 W_InitFile(const char *filename)
if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
if (refreshdirname)
Z_Free(refreshdirname);
if (dirmenu)
{
refreshdirname = Z_StrDup(filename);
nameonly(refreshdirname);
}
else
refreshdirname = NULL;
//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
//
// check if limit of active wadfiles
@ -360,9 +370,7 @@ UINT16 W_InitFile(const char *filename)
// see PutFileNeeded in d_netfil.c
if ((important = !W_VerifyNMUSlumps(filename)))
{
packetsize = packetsizetally;
packetsize += nameonlylength(filename) + 22;
packetsize = packetsizetally + nameonlylength(filename) + 22;
if (packetsize > MAXFILENEEDED*sizeof(UINT8))
{