mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2Internal.git into new_coop
# Conflicts: # src/m_menu.c
This commit is contained in:
commit
0a1e055ba1
23 changed files with 1223 additions and 229 deletions
|
|
@ -33,6 +33,7 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_menu.h"
|
#include "m_menu.h"
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include "win32/win_main.h"
|
#include "win32/win_main.h"
|
||||||
|
|
@ -1275,12 +1276,15 @@ void CONS_Alert(alerttype_t level, const char *fmt, ...)
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case CONS_NOTICE:
|
case CONS_NOTICE:
|
||||||
|
// no notice for notices, hehe
|
||||||
CONS_Printf("\x83" "%s" "\x80 ", M_GetText("NOTICE:"));
|
CONS_Printf("\x83" "%s" "\x80 ", M_GetText("NOTICE:"));
|
||||||
break;
|
break;
|
||||||
case CONS_WARNING:
|
case CONS_WARNING:
|
||||||
|
refreshdirmenu |= REFRESHDIR_WARNING;
|
||||||
CONS_Printf("\x82" "%s" "\x80 ", M_GetText("WARNING:"));
|
CONS_Printf("\x82" "%s" "\x80 ", M_GetText("WARNING:"));
|
||||||
break;
|
break;
|
||||||
case CONS_ERROR:
|
case CONS_ERROR:
|
||||||
|
refreshdirmenu |= REFRESHDIR_ERROR;
|
||||||
CONS_Printf("\x85" "%s" "\x80 ", M_GetText("ERROR:"));
|
CONS_Printf("\x85" "%s" "\x80 ", M_GetText("ERROR:"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,7 @@ typedef struct
|
||||||
} ATTRPACK clientconfig_pak;
|
} ATTRPACK clientconfig_pak;
|
||||||
|
|
||||||
#define MAXSERVERNAME 32
|
#define MAXSERVERNAME 32
|
||||||
|
#define MAXFILENEEDED 915
|
||||||
// This packet is too large
|
// This packet is too large
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
@ -337,7 +338,7 @@ typedef struct
|
||||||
unsigned char mapmd5[16];
|
unsigned char mapmd5[16];
|
||||||
UINT8 actnum;
|
UINT8 actnum;
|
||||||
UINT8 iszone;
|
UINT8 iszone;
|
||||||
UINT8 fileneeded[915]; // is filled with writexxx (byteptr.h)
|
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
||||||
} ATTRPACK serverinfo_pak;
|
} ATTRPACK serverinfo_pak;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
||||||
10
src/d_main.c
10
src/d_main.c
|
|
@ -74,6 +74,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
#include "m_cond.h" // condition initialization
|
#include "m_cond.h" // condition initialization
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
#include "filesrch.h" // refreshdirmenu, mainwadstally
|
||||||
|
|
||||||
#ifdef CMAKECONFIG
|
#ifdef CMAKECONFIG
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
@ -584,6 +585,8 @@ void D_SRB2Loop(void)
|
||||||
realtics = entertic - oldentertics;
|
realtics = entertic - oldentertics;
|
||||||
oldentertics = entertic;
|
oldentertics = entertic;
|
||||||
|
|
||||||
|
refreshdirmenu = 0; // not sure where to put this, here as good as any?
|
||||||
|
|
||||||
#ifdef DEBUGFILE
|
#ifdef DEBUGFILE
|
||||||
if (!realtics)
|
if (!realtics)
|
||||||
if (debugload)
|
if (debugload)
|
||||||
|
|
@ -878,7 +881,7 @@ static void IdentifyVersion(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 // This section can be deleted when music_new is merged with music.dta
|
#ifdef DEVELOP // This section can be deleted when music_new is merged with music.dta
|
||||||
{
|
{
|
||||||
const char *musicfile = "music_new.dta";
|
const char *musicfile = "music_new.dta";
|
||||||
const char *musicpath = va(pandf,srb2waddir,musicfile);
|
const char *musicpath = va(pandf,srb2waddir,musicfile);
|
||||||
|
|
@ -1170,6 +1173,11 @@ void D_SRB2Main(void)
|
||||||
#ifdef USE_PATCH_DTA
|
#ifdef USE_PATCH_DTA
|
||||||
++mainwads; // patch.dta adds one more
|
++mainwads; // patch.dta adds one more
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DEVELOP
|
||||||
|
++mainwads; // music_new, too
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mainwadstally = packetsizetally;
|
||||||
|
|
||||||
cht_Init();
|
cht_Init();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
#include "filesrch.h"
|
||||||
#include "mserv.h"
|
#include "mserv.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
@ -740,6 +741,14 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_firenaxis);
|
CV_RegisterVar(&cv_firenaxis);
|
||||||
CV_RegisterVar(&cv_firenaxis2);
|
CV_RegisterVar(&cv_firenaxis2);
|
||||||
|
|
||||||
|
// filesrch.c
|
||||||
|
CV_RegisterVar(&cv_addons_option);
|
||||||
|
CV_RegisterVar(&cv_addons_folder);
|
||||||
|
CV_RegisterVar(&cv_addons_md5);
|
||||||
|
CV_RegisterVar(&cv_addons_showall);
|
||||||
|
CV_RegisterVar(&cv_addons_search_type);
|
||||||
|
CV_RegisterVar(&cv_addons_search_case);
|
||||||
|
|
||||||
// WARNING: the order is important when initialising mouse2
|
// WARNING: the order is important when initialising mouse2
|
||||||
// we need the mouse2port
|
// we need the mouse2port
|
||||||
CV_RegisterVar(&cv_mouse2port);
|
CV_RegisterVar(&cv_mouse2port);
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ INT32 lastfilenum = -1;
|
||||||
/** Fills a serverinfo packet with information about wad files loaded.
|
/** Fills a serverinfo packet with information about wad files loaded.
|
||||||
*
|
*
|
||||||
* \todo Give this function a better name since it is in global scope.
|
* \todo Give this function a better name since it is in global scope.
|
||||||
|
* Used to have size limiting built in - now handled via W_LoadWadFile in w_wad.c
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
UINT8 *PutFileNeeded(void)
|
UINT8 *PutFileNeeded(void)
|
||||||
|
|
@ -112,29 +113,22 @@ UINT8 *PutFileNeeded(void)
|
||||||
UINT8 *p = netbuffer->u.serverinfo.fileneeded;
|
UINT8 *p = netbuffer->u.serverinfo.fileneeded;
|
||||||
char wadfilename[MAX_WADPATH] = "";
|
char wadfilename[MAX_WADPATH] = "";
|
||||||
UINT8 filestatus;
|
UINT8 filestatus;
|
||||||
size_t bytesused = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < numwadfiles; i++)
|
for (i = 0; i < numwadfiles; i++)
|
||||||
{
|
{
|
||||||
// If it has only music/sound lumps, mark it as unimportant
|
// If it has only music/sound lumps, don't put it in the list
|
||||||
if (W_VerifyNMUSlumps(wadfiles[i]->filename))
|
if (!wadfiles[i]->important)
|
||||||
filestatus = 0;
|
continue;
|
||||||
else
|
|
||||||
filestatus = 1; // Important
|
filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS
|
||||||
|
|
||||||
// Store in the upper four bits
|
// Store in the upper four bits
|
||||||
if (!cv_downloading.value)
|
if (!cv_downloading.value)
|
||||||
filestatus += (2 << 4); // Won't send
|
filestatus += (2 << 4); // Won't send
|
||||||
else if ((wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024))
|
else if ((wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024))
|
||||||
filestatus += (0 << 4); // Won't send
|
|
||||||
else
|
|
||||||
filestatus += (1 << 4); // Will send if requested
|
filestatus += (1 << 4); // Will send if requested
|
||||||
|
// else
|
||||||
bytesused += (nameonlylength(wadfilename) + 22);
|
// filestatus += (0 << 4); -- Won't send, too big
|
||||||
|
|
||||||
// Don't write too far...
|
|
||||||
if (bytesused > sizeof(netbuffer->u.serverinfo.fileneeded))
|
|
||||||
I_Error("Too many wad files added to host a game. (%s, stopped on %s)\n", sizeu1(bytesused), wadfilename);
|
|
||||||
|
|
||||||
WRITEUINT8(p, filestatus);
|
WRITEUINT8(p, filestatus);
|
||||||
|
|
||||||
|
|
@ -167,7 +161,6 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr)
|
||||||
{
|
{
|
||||||
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
||||||
filestatus = READUINT8(p); // The first byte is the file status
|
filestatus = READUINT8(p); // The first byte is the file status
|
||||||
fileneeded[i].important = (UINT8)(filestatus & 3);
|
|
||||||
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
||||||
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
|
fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size
|
||||||
fileneeded[i].file = NULL; // The file isn't open yet
|
fileneeded[i].file = NULL; // The file isn't open yet
|
||||||
|
|
@ -197,7 +190,7 @@ boolean CL_CheckDownloadable(void)
|
||||||
UINT8 i,dlstatus = 0;
|
UINT8 i,dlstatus = 0;
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important)
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||||
{
|
{
|
||||||
if (fileneeded[i].willsend == 1)
|
if (fileneeded[i].willsend == 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -218,7 +211,7 @@ boolean CL_CheckDownloadable(void)
|
||||||
// not downloadable, put reason in console
|
// not downloadable, put reason in console
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n"));
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && fileneeded[i].important)
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN)
|
||||||
{
|
{
|
||||||
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
|
||||||
|
|
||||||
|
|
@ -271,7 +264,7 @@ boolean CL_SendRequestFile(void)
|
||||||
|
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN
|
||||||
&& fileneeded[i].important && (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
&& (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2))
|
||||||
{
|
{
|
||||||
I_Error("Attempted to download files that were not sendable");
|
I_Error("Attempted to download files that were not sendable");
|
||||||
}
|
}
|
||||||
|
|
@ -280,8 +273,7 @@ boolean CL_SendRequestFile(void)
|
||||||
netbuffer->packettype = PT_REQUESTFILE;
|
netbuffer->packettype = PT_REQUESTFILE;
|
||||||
p = (char *)netbuffer->u.textcmd;
|
p = (char *)netbuffer->u.textcmd;
|
||||||
for (i = 0; i < fileneedednum; i++)
|
for (i = 0; i < fileneedednum; i++)
|
||||||
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)
|
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD))
|
||||||
&& fileneeded[i].important)
|
|
||||||
{
|
{
|
||||||
totalfreespaceneeded += fileneeded[i].totalsize;
|
totalfreespaceneeded += fileneeded[i].totalsize;
|
||||||
nameonly(fileneeded[i].filename);
|
nameonly(fileneeded[i].filename);
|
||||||
|
|
@ -360,15 +352,9 @@ INT32 CL_CheckFiles(void)
|
||||||
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
||||||
for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;)
|
for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;)
|
||||||
{
|
{
|
||||||
if (i < fileneedednum && !fileneeded[i].important)
|
if (j < numwadfiles && !wadfiles[j]->important)
|
||||||
{
|
{
|
||||||
// Eh whatever, don't care
|
// Unimportant on our side.
|
||||||
++i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (j < numwadfiles && W_VerifyNMUSlumps(wadfiles[j]->filename))
|
|
||||||
{
|
|
||||||
// Unimportant on our side. still don't care.
|
|
||||||
++j;
|
++j;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -411,7 +397,7 @@ INT32 CL_CheckFiles(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
|
if (fileneeded[i].status != FS_NOTFOUND)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||||
|
|
@ -449,27 +435,8 @@ void CL_LoadServerFiles(void)
|
||||||
fileneeded[i].status = FS_OPEN;
|
fileneeded[i].status = FS_OPEN;
|
||||||
}
|
}
|
||||||
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
||||||
{
|
I_Error("Wrong version of file %s", fileneeded[i].filename);
|
||||||
// If the file is marked important, don't even bother proceeding.
|
else
|
||||||
if (fileneeded[i].important)
|
|
||||||
I_Error("Wrong version of important file %s", fileneeded[i].filename);
|
|
||||||
|
|
||||||
// If it isn't, no need to worry the user with a console message,
|
|
||||||
// although it can't hurt to put something in the debug file.
|
|
||||||
|
|
||||||
// ...but wait a second. What if the local version is "important"?
|
|
||||||
if (!W_VerifyNMUSlumps(fileneeded[i].filename))
|
|
||||||
I_Error("File %s should only contain music and sound effects!",
|
|
||||||
fileneeded[i].filename);
|
|
||||||
|
|
||||||
// Okay, NOW we know it's safe. Whew.
|
|
||||||
P_AddWadFile(fileneeded[i].filename, NULL);
|
|
||||||
if (fileneeded[i].important)
|
|
||||||
G_SetGameModified(true);
|
|
||||||
fileneeded[i].status = FS_OPEN;
|
|
||||||
DEBFILE(va("File %s found but with different md5sum\n", fileneeded[i].filename));
|
|
||||||
}
|
|
||||||
else if (fileneeded[i].important)
|
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
switch(fileneeded[i].status)
|
switch(fileneeded[i].status)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ typedef enum
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT8 important;
|
|
||||||
UINT8 willsend; // Is the server willing to send it?
|
UINT8 willsend; // Is the server willing to send it?
|
||||||
char filename[MAX_WADPATH];
|
char filename[MAX_WADPATH];
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
|
|
||||||
|
|
@ -2227,12 +2227,12 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
||||||
emblemlocations[num-1].type = ET_TIME;
|
emblemlocations[num-1].type = ET_TIME;
|
||||||
else if (fastcmp(word2, "RINGS"))
|
else if (fastcmp(word2, "RINGS"))
|
||||||
emblemlocations[num-1].type = ET_RINGS;
|
emblemlocations[num-1].type = ET_RINGS;
|
||||||
|
else if (fastcmp(word2, "MAP"))
|
||||||
|
emblemlocations[num-1].type = ET_MAP;
|
||||||
else if (fastcmp(word2, "NGRADE"))
|
else if (fastcmp(word2, "NGRADE"))
|
||||||
emblemlocations[num-1].type = ET_NGRADE;
|
emblemlocations[num-1].type = ET_NGRADE;
|
||||||
else if (fastcmp(word2, "NTIME"))
|
else if (fastcmp(word2, "NTIME"))
|
||||||
emblemlocations[num-1].type = ET_NTIME;
|
emblemlocations[num-1].type = ET_NTIME;
|
||||||
else if (fastcmp(word2, "MAP"))
|
|
||||||
emblemlocations[num-1].type = ET_MAP;
|
|
||||||
else
|
else
|
||||||
emblemlocations[num-1].type = (UINT8)value;
|
emblemlocations[num-1].type = (UINT8)value;
|
||||||
}
|
}
|
||||||
|
|
@ -5936,16 +5936,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
||||||
"S_NIGHTSWING_XMAS",
|
"S_NIGHTSWING_XMAS",
|
||||||
|
|
||||||
// NiGHTS Paraloop Powerups
|
// NiGHTS Paraloop Powerups
|
||||||
"S_NIGHTSPOWERUP1",
|
"S_NIGHTSSUPERLOOP",
|
||||||
"S_NIGHTSPOWERUP2",
|
"S_NIGHTSDRILLREFILL",
|
||||||
"S_NIGHTSPOWERUP3",
|
"S_NIGHTSHELPER",
|
||||||
"S_NIGHTSPOWERUP4",
|
"S_NIGHTSEXTRATIME",
|
||||||
"S_NIGHTSPOWERUP5",
|
"S_NIGHTSLINKFREEZE",
|
||||||
"S_NIGHTSPOWERUP6",
|
|
||||||
"S_NIGHTSPOWERUP7",
|
|
||||||
"S_NIGHTSPOWERUP8",
|
|
||||||
"S_NIGHTSPOWERUP9",
|
|
||||||
"S_NIGHTSPOWERUP10",
|
|
||||||
"S_EGGCAPSULE",
|
"S_EGGCAPSULE",
|
||||||
|
|
||||||
// Orbiting Chaos Emeralds
|
// Orbiting Chaos Emeralds
|
||||||
|
|
@ -7220,6 +7215,10 @@ struct {
|
||||||
{"SF_NOINTERRUPT",SF_NOINTERRUPT},
|
{"SF_NOINTERRUPT",SF_NOINTERRUPT},
|
||||||
{"SF_X2AWAYSOUND",SF_X2AWAYSOUND},
|
{"SF_X2AWAYSOUND",SF_X2AWAYSOUND},
|
||||||
|
|
||||||
|
// Global emblem var flags
|
||||||
|
{"GE_NIGHTSPULL",GE_NIGHTSPULL},
|
||||||
|
{"GE_NIGHTSITEM",GE_NIGHTSITEM},
|
||||||
|
|
||||||
// Map emblem var flags
|
// Map emblem var flags
|
||||||
{"ME_ALLEMERALDS",ME_ALLEMERALDS},
|
{"ME_ALLEMERALDS",ME_ALLEMERALDS},
|
||||||
{"ME_ULTIMATE",ME_ULTIMATE},
|
{"ME_ULTIMATE",ME_ULTIMATE},
|
||||||
|
|
|
||||||
335
src/filesrch.c
335
src/filesrch.c
|
|
@ -31,6 +31,8 @@
|
||||||
#include "filesrch.h"
|
#include "filesrch.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
|
#include "z_zone.h"
|
||||||
|
#include "m_menu.h" // Addons_option_Onchange
|
||||||
|
|
||||||
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
||||||
|
|
||||||
|
|
@ -255,6 +257,28 @@ readdir (DIR * dirp)
|
||||||
return (struct dirent *) 0;
|
return (struct dirent *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rewinddir
|
||||||
|
*
|
||||||
|
* Makes the next readdir start from the beginning.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rewinddir (DIR * dirp)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* Check for valid DIR struct. */
|
||||||
|
if (!dirp)
|
||||||
|
{
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dirp->dd_stat = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* closedir
|
* closedir
|
||||||
*
|
*
|
||||||
|
|
@ -285,6 +309,35 @@ closedir (DIR * dirp)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#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_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};
|
||||||
|
|
||||||
|
consvar_t cv_addons_showall = {"addons_showall", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
consvar_t cv_addons_search_case = {"addons_search_case", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
static CV_PossibleValue_t addons_search_type_cons_t[] = {{0, "Start"}, {1, "Anywhere"}, {0, NULL}};
|
||||||
|
consvar_t cv_addons_search_type = {"addons_search_type", "Anywhere", CV_SAVE, addons_search_type_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
char menupath[1024];
|
||||||
|
size_t menupathindex[menudepth];
|
||||||
|
size_t menudepthleft = menudepth;
|
||||||
|
|
||||||
|
char menusearch[MAXSTRINGLENGTH+1];
|
||||||
|
|
||||||
|
char **dirmenu;
|
||||||
|
size_t sizedirmenu;
|
||||||
|
size_t dir_on[menudepth];
|
||||||
|
UINT8 refreshdirmenu = 0;
|
||||||
|
|
||||||
|
size_t packetsizetally = 0;
|
||||||
|
size_t mainwadstally = 0;
|
||||||
|
|
||||||
#if defined (_XBOX) && defined (_MSC_VER)
|
#if defined (_XBOX) && defined (_MSC_VER)
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth)
|
boolean completepath, int maxsearchdepth)
|
||||||
|
|
@ -296,6 +349,13 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
completepath = false;
|
completepath = false;
|
||||||
return FS_NOTFOUND;
|
return FS_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
(void)samedepth;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined (_WIN32_WCE)
|
#elif defined (_WIN32_WCE)
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth)
|
boolean completepath, int maxsearchdepth)
|
||||||
|
|
@ -346,6 +406,12 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
#endif
|
#endif
|
||||||
return FS_NOTFOUND;
|
return FS_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
(void)samedepth;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
||||||
{
|
{
|
||||||
|
|
@ -387,25 +453,29 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
{
|
{
|
||||||
searchpath[searchpathindex[depthleft]]=0;
|
searchpath[searchpathindex[depthleft]]=0;
|
||||||
dent = readdir(dirhandle[depthleft]);
|
dent = readdir(dirhandle[depthleft]);
|
||||||
if (dent)
|
|
||||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
|
||||||
|
|
||||||
if (!dent)
|
if (!dent)
|
||||||
|
{
|
||||||
closedir(dirhandle[depthleft++]);
|
closedir(dirhandle[depthleft++]);
|
||||||
else if (dent->d_name[0]=='.' &&
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dent->d_name[0]=='.' &&
|
||||||
(dent->d_name[1]=='\0' ||
|
(dent->d_name[1]=='\0' ||
|
||||||
(dent->d_name[1]=='.' &&
|
(dent->d_name[1]=='.' &&
|
||||||
dent->d_name[2]=='\0')))
|
dent->d_name[2]=='\0')))
|
||||||
{
|
{
|
||||||
// we don't want to scan uptree
|
// we don't want to scan uptree
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
|
||||||
{
|
// okay, now we actually want searchpath to incorporate d_name
|
||||||
// was the file (re)moved? can't stat it
|
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||||
}
|
|
||||||
|
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
else if (S_ISDIR(fsstat.st_mode) && depthleft)
|
else if (S_ISDIR(fsstat.st_mode) && depthleft)
|
||||||
{
|
{
|
||||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
|
||||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||||
dirhandle[depthleft] = opendir(searchpath);
|
dirhandle[depthleft] = opendir(searchpath);
|
||||||
if (!dirhandle[depthleft])
|
if (!dirhandle[depthleft])
|
||||||
|
|
@ -444,6 +514,255 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||||
free(searchname);
|
free(searchname);
|
||||||
free(searchpathindex);
|
free(searchpathindex);
|
||||||
free(dirhandle);
|
free(dirhandle);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char exttable[NUM_EXT_TABLE][5] = {
|
||||||
|
".txt", ".cfg", // exec
|
||||||
|
".wad", ".soc", ".lua"}; // addfile
|
||||||
|
|
||||||
|
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||||
|
|
||||||
|
|
||||||
|
static boolean filemenusearch(char *haystack, char *needle)
|
||||||
|
{
|
||||||
|
static char localhaystack[128];
|
||||||
|
strlcpy(localhaystack, haystack, 128);
|
||||||
|
if (!cv_addons_search_case.value)
|
||||||
|
strupr(localhaystack);
|
||||||
|
return ((cv_addons_search_type.value)
|
||||||
|
? (strstr(localhaystack, needle) != 0)
|
||||||
|
: (!strncmp(localhaystack, needle, menusearch[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define searchdir if (menusearch[0] && !filemenusearch(dent->d_name, localmenusearch))\
|
||||||
|
{\
|
||||||
|
rejected++;\
|
||||||
|
continue;\
|
||||||
|
}\
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth)
|
||||||
|
{
|
||||||
|
DIR *dirhandle;
|
||||||
|
struct dirent *dent;
|
||||||
|
struct stat fsstat;
|
||||||
|
size_t pos = 0, folderpos = 0, numfolders = 0, rejected = 0;
|
||||||
|
char *tempname = NULL;
|
||||||
|
boolean noresults = false;
|
||||||
|
char localmenusearch[MAXSTRINGLENGTH] = "";
|
||||||
|
|
||||||
|
if (samedepth)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
}
|
||||||
|
else
|
||||||
|
menusearch[0] = menusearch[1] = 0; // clear search
|
||||||
|
|
||||||
|
for (; sizedirmenu > 0; sizedirmenu--) // clear out existing items
|
||||||
|
{
|
||||||
|
Z_Free(dirmenu[sizedirmenu-1]);
|
||||||
|
dirmenu[sizedirmenu-1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dirhandle = opendir(menupath))) // get directory
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (menusearch[0])
|
||||||
|
{
|
||||||
|
strcpy(localmenusearch, menusearch+1);
|
||||||
|
if (!cv_addons_search_case.value)
|
||||||
|
strupr(localmenusearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
dent = readdir(dirhandle);
|
||||||
|
|
||||||
|
if (!dent)
|
||||||
|
break;
|
||||||
|
else if (dent->d_name[0]=='.' &&
|
||||||
|
(dent->d_name[1]=='\0' ||
|
||||||
|
(dent->d_name[1]=='.' &&
|
||||||
|
dent->d_name[2]=='\0')))
|
||||||
|
continue; // we don't want to scan uptree
|
||||||
|
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||||
|
|
||||||
|
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
|
else // is a file or directory
|
||||||
|
{
|
||||||
|
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||||
|
{
|
||||||
|
if (!cv_addons_showall.value)
|
||||||
|
{
|
||||||
|
size_t len = strlen(dent->d_name)+1;
|
||||||
|
UINT8 ext;
|
||||||
|
for (ext = 0; ext < NUM_EXT_TABLE; ext++)
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rejected && !sizedirmenu)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
sizedirmenu++;
|
||||||
|
numfolders++;
|
||||||
|
folderpos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dirmenu = Z_Realloc(dirmenu, sizedirmenu*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)
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
dent = readdir(dirhandle);
|
||||||
|
|
||||||
|
if (!dent)
|
||||||
|
break;
|
||||||
|
else if (dent->d_name[0]=='.' &&
|
||||||
|
(dent->d_name[1]=='\0' ||
|
||||||
|
(dent->d_name[1]=='.' &&
|
||||||
|
dent->d_name[2]=='\0')))
|
||||||
|
continue; // we don't want to scan uptree
|
||||||
|
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name);
|
||||||
|
|
||||||
|
if (stat(menupath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||||
|
; // was the file (re)moved? can't stat it
|
||||||
|
else // is a file or directory
|
||||||
|
{
|
||||||
|
char *temp;
|
||||||
|
size_t len = strlen(dent->d_name)+1;
|
||||||
|
UINT8 ext = EXT_FOLDER;
|
||||||
|
UINT8 folder;
|
||||||
|
|
||||||
|
if (!S_ISDIR(fsstat.st_mode)) // file
|
||||||
|
{
|
||||||
|
if (!((numfolders+pos) < sizedirmenu)) 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;
|
||||||
|
for (i = 0; i < numwadfiles; i++)
|
||||||
|
{
|
||||||
|
if (!filenamebuf[i][0])
|
||||||
|
{
|
||||||
|
strncpy(filenamebuf[i], wadfiles[i]->filename, MAX_WADPATH);
|
||||||
|
filenamebuf[i][MAX_WADPATH - 1] = '\0';
|
||||||
|
nameonly(filenamebuf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(dent->d_name, filenamebuf[i]))
|
||||||
|
continue;
|
||||||
|
if (cv_addons_md5.value && !checkfilemd5(menupath, wadfiles[i]->md5sum))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ext == EXT_TXT)
|
||||||
|
{
|
||||||
|
if (!strcmp(dent->d_name, "log.txt") || !strcmp(dent->d_name, "errorlog.txt"))
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(dent->d_name, configfile))
|
||||||
|
ext |= EXT_LOADED;
|
||||||
|
|
||||||
|
folder = 0;
|
||||||
|
}
|
||||||
|
else // directory
|
||||||
|
{
|
||||||
|
searchdir;
|
||||||
|
len += (folder = 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
if (!(temp = Z_Malloc((len+DIR_STRING+folder) * sizeof (char), PU_STATIC, NULL)))
|
||||||
|
I_Error("Ran out of memory whilst preparing add-ons menu");
|
||||||
|
temp[DIR_TYPE] = ext;
|
||||||
|
temp[DIR_LEN] = (UINT8)(len);
|
||||||
|
strlcpy(temp+DIR_STRING, dent->d_name, len);
|
||||||
|
if (folder)
|
||||||
|
{
|
||||||
|
strcpy(temp+len, "/");
|
||||||
|
dirmenu[folderpos++] = temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dirmenu[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));
|
||||||
|
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
sizedirmenu = (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)
|
||||||
|
{
|
||||||
|
dir_on[menudepthleft] = 0;
|
||||||
|
Z_Free(dirmenu);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (dir_on[menudepthleft] >= sizedirmenu)
|
||||||
|
dir_on[menudepthleft] = sizedirmenu-1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
|
#include "m_menu.h" // MAXSTRINGLENGTH
|
||||||
|
|
||||||
|
extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall, cv_addons_search_case, cv_addons_search_type;
|
||||||
|
|
||||||
/** \brief The filesearch function
|
/** \brief The filesearch function
|
||||||
|
|
||||||
|
|
@ -25,4 +28,64 @@
|
||||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||||
boolean completepath, int maxsearchdepth);
|
boolean completepath, int maxsearchdepth);
|
||||||
|
|
||||||
|
#define menudepth 20
|
||||||
|
|
||||||
|
extern char menupath[1024];
|
||||||
|
extern size_t menupathindex[menudepth];
|
||||||
|
extern size_t menudepthleft;
|
||||||
|
|
||||||
|
extern char menusearch[MAXSTRINGLENGTH+1];
|
||||||
|
|
||||||
|
extern char **dirmenu;
|
||||||
|
extern size_t sizedirmenu;
|
||||||
|
extern size_t dir_on[menudepth];
|
||||||
|
extern UINT8 refreshdirmenu;
|
||||||
|
|
||||||
|
extern size_t packetsizetally;
|
||||||
|
extern size_t mainwadstally;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
EXT_FOLDER = 0,
|
||||||
|
EXT_UP,
|
||||||
|
EXT_NORESULTS,
|
||||||
|
EXT_START,
|
||||||
|
EXT_TXT = EXT_START,
|
||||||
|
EXT_CFG,
|
||||||
|
EXT_LOADSTART,
|
||||||
|
EXT_WAD = EXT_LOADSTART,
|
||||||
|
EXT_SOC,
|
||||||
|
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
|
||||||
|
NUM_EXT,
|
||||||
|
NUM_EXT_TABLE = NUM_EXT-EXT_START,
|
||||||
|
EXT_LOADED = 0x80
|
||||||
|
/*
|
||||||
|
obviously there can only be 0x7F supported extensions in
|
||||||
|
addons menu because we're cramming this into a char out of
|
||||||
|
laziness/easy memory allocation (what's the difference?)
|
||||||
|
and have stolen a bit to show whether it's loaded or not
|
||||||
|
in practice the size of the data type is probably overkill
|
||||||
|
toast 02/05/17
|
||||||
|
*/
|
||||||
|
} ext_enum;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DIR_TYPE = 0,
|
||||||
|
DIR_LEN,
|
||||||
|
DIR_STRING
|
||||||
|
} dirname_enum;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
REFRESHDIR_NORMAL = 1,
|
||||||
|
REFRESHDIR_ADDFILE = 2,
|
||||||
|
REFRESHDIR_WARNING = 4,
|
||||||
|
REFRESHDIR_ERROR = 8,
|
||||||
|
REFRESHDIR_NOTLOADED = 16,
|
||||||
|
REFRESHDIR_MAX = 32
|
||||||
|
} refreshdir_enum;
|
||||||
|
|
||||||
|
boolean preparefilemenu(boolean samedepth);
|
||||||
|
|
||||||
#endif // __FILESRCH_H__
|
#endif // __FILESRCH_H__
|
||||||
|
|
|
||||||
|
|
@ -641,13 +641,13 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
||||||
{
|
{
|
||||||
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
|
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
|
||||||
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
|
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
|
||||||
angle = FOFsector->floorpic_angle>>ANGLETOFINESHIFT;
|
angle = FOFsector->floorpic_angle;
|
||||||
}
|
}
|
||||||
else // it's a ceiling
|
else // it's a ceiling
|
||||||
{
|
{
|
||||||
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize;
|
scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize;
|
||||||
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize;
|
scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize;
|
||||||
angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT;
|
angle = FOFsector->ceilingpic_angle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gr_frontsector)
|
else if (gr_frontsector)
|
||||||
|
|
@ -656,25 +656,19 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
||||||
{
|
{
|
||||||
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
|
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
|
||||||
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
|
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
|
||||||
angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT;
|
angle = gr_frontsector->floorpic_angle;
|
||||||
}
|
}
|
||||||
else // it's a ceiling
|
else // it's a ceiling
|
||||||
{
|
{
|
||||||
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize;
|
scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize;
|
||||||
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize;
|
scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize;
|
||||||
angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT;
|
angle = gr_frontsector->ceilingpic_angle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (angle) // Only needs to be done if there's an altered angle
|
if (angle) // Only needs to be done if there's an altered angle
|
||||||
{
|
{
|
||||||
|
angle = InvAngle(angle)>>ANGLETOFINESHIFT;
|
||||||
// This needs to be done so that it scrolls in a different direction after rotation like software
|
|
||||||
tempxsow = FLOAT_TO_FIXED(scrollx);
|
|
||||||
tempytow = FLOAT_TO_FIXED(scrolly);
|
|
||||||
scrollx = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
|
|
||||||
scrolly = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
|
|
||||||
|
|
||||||
// This needs to be done so everything aligns after rotation
|
// This needs to be done so everything aligns after rotation
|
||||||
// It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does
|
// It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does
|
||||||
tempxsow = FLOAT_TO_FIXED(flatxref);
|
tempxsow = FLOAT_TO_FIXED(flatxref);
|
||||||
|
|
@ -687,7 +681,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
||||||
{
|
{
|
||||||
// Hurdler: add scrolling texture on floor/ceiling
|
// Hurdler: add scrolling texture on floor/ceiling
|
||||||
v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx);
|
v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx);
|
||||||
v3d->tow = (float)(flatyref - (pv->y / fflatsize) + scrolly);
|
v3d->tow = (float)(-(pv->y / fflatsize) + flatyref + scrolly);
|
||||||
|
|
||||||
//v3d->sow = (float)(pv->x / fflatsize);
|
//v3d->sow = (float)(pv->x / fflatsize);
|
||||||
//v3d->tow = (float)(pv->y / fflatsize);
|
//v3d->tow = (float)(pv->y / fflatsize);
|
||||||
|
|
@ -698,7 +692,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
|
||||||
tempxsow = FLOAT_TO_FIXED(v3d->sow);
|
tempxsow = FLOAT_TO_FIXED(v3d->sow);
|
||||||
tempytow = FLOAT_TO_FIXED(v3d->tow);
|
tempytow = FLOAT_TO_FIXED(v3d->tow);
|
||||||
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
|
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
|
||||||
v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle))));
|
v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
|
||||||
}
|
}
|
||||||
|
|
||||||
//v3d->sow = (float)(v3d->sow - flatxref + scrollx);
|
//v3d->sow = (float)(v3d->sow - flatxref + scrollx);
|
||||||
|
|
|
||||||
35
src/info.c
35
src/info.c
|
|
@ -2896,16 +2896,11 @@ state_t states[NUMSTATES] =
|
||||||
{SPR_NWNG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSWING_XMAS
|
{SPR_NWNG, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSWING_XMAS
|
||||||
|
|
||||||
// NiGHTS Paraloop Powerups
|
// NiGHTS Paraloop Powerups
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP1
|
{SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSSUPERLOOP
|
||||||
{SPR_NPRU, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP2
|
{SPR_NPRU, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSDRILLREFILL
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP3
|
{SPR_NPRU, 2, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSHELPER
|
||||||
{SPR_NPRU, 1, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP4
|
{SPR_NPRU, 3, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSEXTRATIME
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP5
|
{SPR_NPRU, 4, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSLINKFREEZE
|
||||||
{SPR_NPRU, 2, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP6
|
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP7
|
|
||||||
{SPR_NPRU, 3, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP8
|
|
||||||
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP9
|
|
||||||
{SPR_NPRU, 4, -1, {NULL}, 0, 0, S_NULL}, // S_NIGHTSPOWERUP10
|
|
||||||
|
|
||||||
{SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE
|
{SPR_CAPS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGCAPSULE
|
||||||
|
|
||||||
|
|
@ -14296,9 +14291,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSSUPERLOOP
|
{ // MT_NIGHTSSUPERLOOP
|
||||||
1707, // doomednum
|
1707, // doomednum
|
||||||
S_NIGHTSPOWERUP1, // spawnstate
|
S_NIGHTSSUPERLOOP, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP2, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
|
@ -14323,9 +14318,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSDRILLREFILL
|
{ // MT_NIGHTSDRILLREFILL
|
||||||
1708, // doomednum
|
1708, // doomednum
|
||||||
S_NIGHTSPOWERUP3, // spawnstate
|
S_NIGHTSDRILLREFILL, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP4, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
|
@ -14350,9 +14345,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSHELPER
|
{ // MT_NIGHTSHELPER
|
||||||
1709, // doomednum
|
1709, // doomednum
|
||||||
S_NIGHTSPOWERUP5, // spawnstate
|
S_NIGHTSHELPER, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP6, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
|
@ -14377,9 +14372,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSEXTRATIME
|
{ // MT_NIGHTSEXTRATIME
|
||||||
1711, // doomednum
|
1711, // doomednum
|
||||||
S_NIGHTSPOWERUP7, // spawnstate
|
S_NIGHTSEXTRATIME, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP8, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
|
@ -14404,9 +14399,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
|
|
||||||
{ // MT_NIGHTSLINKFREEZE
|
{ // MT_NIGHTSLINKFREEZE
|
||||||
1712, // doomednum
|
1712, // doomednum
|
||||||
S_NIGHTSPOWERUP9, // spawnstate
|
S_NIGHTSLINKFREEZE, // spawnstate
|
||||||
1000, // spawnhealth
|
1000, // spawnhealth
|
||||||
S_NIGHTSPOWERUP10, // seestate
|
S_NULL, // seestate
|
||||||
sfx_None, // seesound
|
sfx_None, // seesound
|
||||||
0, // reactiontime
|
0, // reactiontime
|
||||||
sfx_None, // attacksound
|
sfx_None, // attacksound
|
||||||
|
|
|
||||||
15
src/info.h
15
src/info.h
|
|
@ -3041,16 +3041,11 @@ typedef enum state
|
||||||
S_NIGHTSWING_XMAS,
|
S_NIGHTSWING_XMAS,
|
||||||
|
|
||||||
// NiGHTS Paraloop Powerups
|
// NiGHTS Paraloop Powerups
|
||||||
S_NIGHTSPOWERUP1,
|
S_NIGHTSSUPERLOOP,
|
||||||
S_NIGHTSPOWERUP2,
|
S_NIGHTSDRILLREFILL,
|
||||||
S_NIGHTSPOWERUP3,
|
S_NIGHTSHELPER,
|
||||||
S_NIGHTSPOWERUP4,
|
S_NIGHTSEXTRATIME,
|
||||||
S_NIGHTSPOWERUP5,
|
S_NIGHTSLINKFREEZE,
|
||||||
S_NIGHTSPOWERUP6,
|
|
||||||
S_NIGHTSPOWERUP7,
|
|
||||||
S_NIGHTSPOWERUP8,
|
|
||||||
S_NIGHTSPOWERUP9,
|
|
||||||
S_NIGHTSPOWERUP10,
|
|
||||||
S_EGGCAPSULE,
|
S_EGGCAPSULE,
|
||||||
|
|
||||||
// Orbiting Chaos Emeralds
|
// Orbiting Chaos Emeralds
|
||||||
|
|
|
||||||
20
src/m_cond.h
20
src/m_cond.h
|
|
@ -66,14 +66,18 @@ typedef struct
|
||||||
} conditionset_t;
|
} conditionset_t;
|
||||||
|
|
||||||
// Emblem information
|
// Emblem information
|
||||||
#define ET_GLOBAL 0 // Global map emblem, var == color
|
#define ET_GLOBAL 0 // Emblem with a position in space
|
||||||
#define ET_SKIN 1 // Skin specific emblem, var == skin
|
#define ET_SKIN 1 // Skin specific emblem with a position in space, var == skin
|
||||||
#define ET_SCORE 2
|
#define ET_MAP 2 // Beat the map
|
||||||
#define ET_TIME 3
|
#define ET_SCORE 3 // Get the score
|
||||||
#define ET_RINGS 4
|
#define ET_TIME 4 // Get the time
|
||||||
#define ET_NGRADE 5
|
#define ET_RINGS 5 // Get the rings
|
||||||
#define ET_NTIME 6
|
#define ET_NGRADE 6 // Get the grade
|
||||||
#define ET_MAP 7
|
#define ET_NTIME 7 // Get the time (NiGHTS mode)
|
||||||
|
|
||||||
|
// Global emblem flags
|
||||||
|
#define GE_NIGHTSPULL 1 // sun off the nights track - loop it
|
||||||
|
#define GE_NIGHTSITEM 2 // moon on the nights track - find it
|
||||||
|
|
||||||
// Map emblem flags
|
// Map emblem flags
|
||||||
#define ME_ALLEMERALDS 1
|
#define ME_ALLEMERALDS 1
|
||||||
|
|
|
||||||
674
src/m_menu.c
674
src/m_menu.c
|
|
@ -33,6 +33,9 @@
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
|
|
||||||
|
// Addfile
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "i_video.h"
|
#include "i_video.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
|
@ -74,7 +77,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
#define SMALLLINEHEIGHT 8
|
#define SMALLLINEHEIGHT 8
|
||||||
#define SLIDER_RANGE 9
|
#define SLIDER_RANGE 9
|
||||||
#define SLIDER_WIDTH 78
|
#define SLIDER_WIDTH 78
|
||||||
#define MAXSTRINGLENGTH 32
|
|
||||||
#define SERVERS_PER_PAGE 11
|
#define SERVERS_PER_PAGE 11
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
@ -211,14 +213,13 @@ menu_t SPauseDef;
|
||||||
|
|
||||||
// Level Select
|
// Level Select
|
||||||
static levelselect_t levelselect = {0, NULL};
|
static levelselect_t levelselect = {0, NULL};
|
||||||
static UINT8 levelselectselect[4];
|
static UINT8 levelselectselect[3];
|
||||||
static patch_t *levselp[2][3];
|
static patch_t *levselp[2][3];
|
||||||
static INT32 lsoffs[2];
|
static INT32 lsoffs[2];
|
||||||
|
|
||||||
#define lsrow levelselectselect[0]
|
#define lsrow levelselectselect[0]
|
||||||
#define lscol levelselectselect[1]
|
#define lscol levelselectselect[1]
|
||||||
#define lstic levelselectselect[2]
|
#define lshli levelselectselect[2]
|
||||||
#define lshli levelselectselect[3]
|
|
||||||
|
|
||||||
#define lshseperation 101
|
#define lshseperation 101
|
||||||
#define lsbasevseperation 62
|
#define lsbasevseperation 62
|
||||||
|
|
@ -332,12 +333,20 @@ menu_t OP_MonitorToggleDef;
|
||||||
static void M_ScreenshotOptions(INT32 choice);
|
static void M_ScreenshotOptions(INT32 choice);
|
||||||
static void M_EraseData(INT32 choice);
|
static void M_EraseData(INT32 choice);
|
||||||
|
|
||||||
static void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight);
|
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
|
||||||
|
|
||||||
|
static void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight, boolean allowlowercase);
|
||||||
|
|
||||||
// Drawing functions
|
// Drawing functions
|
||||||
static void M_DrawGenericMenu(void);
|
static void M_DrawGenericMenu(void);
|
||||||
static void M_DrawGenericScrollMenu(void);
|
static void M_DrawGenericScrollMenu(void);
|
||||||
static void M_DrawCenteredMenu(void);
|
static void M_DrawCenteredMenu(void);
|
||||||
|
static void M_DrawAddons(void);
|
||||||
static void M_DrawSkyRoom(void);
|
static void M_DrawSkyRoom(void);
|
||||||
static void M_DrawChecklist(void);
|
static void M_DrawChecklist(void);
|
||||||
static void M_DrawEmblemHints(void);
|
static void M_DrawEmblemHints(void);
|
||||||
|
|
@ -374,6 +383,7 @@ static void M_DrawSetupMultiPlayerMenu(void);
|
||||||
// Handling functions
|
// Handling functions
|
||||||
static boolean M_ExitPandorasBox(void);
|
static boolean M_ExitPandorasBox(void);
|
||||||
static boolean M_QuitMultiPlayerMenu(void);
|
static boolean M_QuitMultiPlayerMenu(void);
|
||||||
|
static void M_HandleAddons(INT32 choice);
|
||||||
static void M_HandleLevelPlatter(INT32 choice);
|
static void M_HandleLevelPlatter(INT32 choice);
|
||||||
static void M_HandleSoundTest(INT32 choice);
|
static void M_HandleSoundTest(INT32 choice);
|
||||||
static void M_HandleImageDef(INT32 choice);
|
static void M_HandleImageDef(INT32 choice);
|
||||||
|
|
@ -483,14 +493,15 @@ static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dum
|
||||||
// ---------
|
// ---------
|
||||||
static menuitem_t MainMenu[] =
|
static menuitem_t MainMenu[] =
|
||||||
{
|
{
|
||||||
{IT_STRING|IT_CALL, NULL, "Secrets", M_SecretsMenu, 84},
|
{IT_STRING|IT_CALL, NULL, "Secrets", M_SecretsMenu, 76},
|
||||||
{IT_STRING|IT_CALL, NULL, "1 player", M_SinglePlayerMenu, 92},
|
{IT_STRING|IT_CALL, NULL, "1 player", M_SinglePlayerMenu, 84},
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
{IT_STRING|IT_SUBMENU, NULL, "multiplayer", &MP_MainDef, 100},
|
{IT_STRING|IT_SUBMENU, NULL, "multiplayer", &MP_MainDef, 92},
|
||||||
#else
|
#else
|
||||||
{IT_STRING|IT_CALL, NULL, "multiplayer", M_StartSplitServerMenu, 100},
|
{IT_STRING|IT_CALL, NULL, "multiplayer", M_StartSplitServerMenu, 92},
|
||||||
#endif
|
#endif
|
||||||
{IT_STRING|IT_CALL, NULL, "options", M_Options, 108},
|
{IT_STRING|IT_CALL, NULL, "options", M_Options, 100},
|
||||||
|
{IT_CALL |IT_STRING, NULL, "addons", M_Addons, 108},
|
||||||
{IT_STRING|IT_CALL, NULL, "quit game", M_QuitSRB2, 116},
|
{IT_STRING|IT_CALL, NULL, "quit game", M_QuitSRB2, 116},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -500,9 +511,15 @@ typedef enum
|
||||||
singleplr,
|
singleplr,
|
||||||
multiplr,
|
multiplr,
|
||||||
options,
|
options,
|
||||||
|
addons,
|
||||||
quitdoom
|
quitdoom
|
||||||
} main_e;
|
} main_e;
|
||||||
|
|
||||||
|
static menuitem_t MISC_AddonsMenu[] =
|
||||||
|
{
|
||||||
|
{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleAddons, 0}, // dummy menuitem for the control func
|
||||||
|
};
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
// Pause Menu Mode Attacking Edition
|
// Pause Menu Mode Attacking Edition
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
|
@ -525,26 +542,28 @@ typedef enum
|
||||||
// ---------------------
|
// ---------------------
|
||||||
static menuitem_t MPauseMenu[] =
|
static menuitem_t MPauseMenu[] =
|
||||||
{
|
{
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
|
{IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8},
|
||||||
{IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 24},
|
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
|
||||||
|
{IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_GameTypeChange, 24},
|
||||||
|
|
||||||
{IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,40},
|
{IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,40},
|
||||||
{IT_CALL | IT_STRING, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen
|
{IT_STRING | IT_CALL, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen
|
||||||
{IT_CALL | IT_STRING, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen
|
{IT_STRING | IT_CALL, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen
|
||||||
|
|
||||||
{IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48},
|
{IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48},
|
||||||
{IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48},
|
{IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48},
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48},
|
{IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48},
|
||||||
{IT_CALL | IT_STRING, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone
|
{IT_STRING | IT_CALL, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone
|
||||||
{IT_CALL | IT_STRING, NULL, "Options", M_Options, 64},
|
{IT_STRING | IT_CALL, NULL, "Options", M_Options, 64},
|
||||||
|
|
||||||
{IT_CALL | IT_STRING, NULL, "Return to Title", M_EndGame, 80},
|
{IT_STRING | IT_CALL, NULL, "Return to Title", M_EndGame, 80},
|
||||||
{IT_CALL | IT_STRING, NULL, "Quit Game", M_QuitSRB2, 88},
|
{IT_STRING | IT_CALL, NULL, "Quit Game", M_QuitSRB2, 88},
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
mpause_scramble = 0,
|
mpause_addons = 0,
|
||||||
|
mpause_scramble,
|
||||||
mpause_switchmap,
|
mpause_switchmap,
|
||||||
|
|
||||||
mpause_continue,
|
mpause_continue,
|
||||||
|
|
@ -587,6 +606,7 @@ typedef enum
|
||||||
spause_continue,
|
spause_continue,
|
||||||
spause_retry,
|
spause_retry,
|
||||||
spause_options,
|
spause_options,
|
||||||
|
|
||||||
spause_title,
|
spause_title,
|
||||||
spause_quit
|
spause_quit
|
||||||
} spause_e;
|
} spause_e;
|
||||||
|
|
@ -1315,9 +1335,10 @@ static menuitem_t OP_SoundOptionsMenu[] =
|
||||||
|
|
||||||
static menuitem_t OP_DataOptionsMenu[] =
|
static menuitem_t OP_DataOptionsMenu[] =
|
||||||
{
|
{
|
||||||
{IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10},
|
{IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 10},
|
||||||
|
{IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 20},
|
||||||
|
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 20},
|
{IT_STRING | IT_SUBMENU, NULL, "\x85" "Erase Data...", &OP_EraseDataDef, 40},
|
||||||
};
|
};
|
||||||
|
|
||||||
static menuitem_t OP_ScreenshotOptionsMenu[] =
|
static menuitem_t OP_ScreenshotOptionsMenu[] =
|
||||||
|
|
@ -1364,6 +1385,24 @@ static menuitem_t OP_EraseDataMenu[] =
|
||||||
{IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40},
|
{IT_STRING | IT_CALL, NULL, "\x85" "Erase ALL Data", M_EraseData, 40},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static menuitem_t OP_AddonsOptionsMenu[] =
|
||||||
|
{
|
||||||
|
{IT_HEADER, NULL, "Menu", NULL, 0},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 12},
|
||||||
|
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 22},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Identify add-ons via", &cv_addons_md5, 50},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 60},
|
||||||
|
|
||||||
|
{IT_HEADER, NULL, "Search", NULL, 78},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Matching", &cv_addons_search_type, 90},
|
||||||
|
{IT_STRING|IT_CVAR, NULL, "Case-sensitive", &cv_addons_search_case, 100},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
op_addons_folder = 2,
|
||||||
|
};
|
||||||
|
|
||||||
static menuitem_t OP_ServerOptionsMenu[] =
|
static menuitem_t OP_ServerOptionsMenu[] =
|
||||||
{
|
{
|
||||||
{IT_HEADER, NULL, "General", NULL, 0},
|
{IT_HEADER, NULL, "General", NULL, 0},
|
||||||
|
|
@ -1443,6 +1482,18 @@ static menuitem_t OP_MonitorToggleMenu[] =
|
||||||
// Main Menu and related
|
// Main Menu and related
|
||||||
menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72);
|
menu_t MainDef = CENTERMENUSTYLE(NULL, MainMenu, NULL, 72);
|
||||||
|
|
||||||
|
menu_t MISC_AddonsDef =
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
sizeof (MISC_AddonsMenu)/sizeof (menuitem_t),
|
||||||
|
&MainDef,
|
||||||
|
MISC_AddonsMenu,
|
||||||
|
M_DrawAddons,
|
||||||
|
50, 28,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72);
|
menu_t MAPauseDef = PAUSEMENUSTYLE(MAPauseMenu, 40, 72);
|
||||||
menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72);
|
menu_t SPauseDef = PAUSEMENUSTYLE(SPauseMenu, 40, 72);
|
||||||
menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72);
|
menu_t MPauseDef = PAUSEMENUSTYLE(MPauseMenu, 40, 72);
|
||||||
|
|
@ -1808,17 +1859,7 @@ menu_t OP_SoundOptionsDef =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
menu_t OP_ServerOptionsDef =
|
menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE("M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30);
|
||||||
{
|
|
||||||
"M_SERVER",
|
|
||||||
sizeof (OP_ServerOptionsMenu)/sizeof (menuitem_t),
|
|
||||||
&OP_MainDef,
|
|
||||||
OP_ServerOptionsMenu,
|
|
||||||
M_DrawGenericScrollMenu,
|
|
||||||
30, 30,
|
|
||||||
0,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
menu_t OP_MonitorToggleDef =
|
menu_t OP_MonitorToggleDef =
|
||||||
{
|
{
|
||||||
|
|
@ -1860,7 +1901,7 @@ menu_t OP_OpenGLColorDef =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 30, 30);
|
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
|
||||||
|
|
||||||
menu_t OP_ScreenshotOptionsDef =
|
menu_t OP_ScreenshotOptionsDef =
|
||||||
{
|
{
|
||||||
|
|
@ -1874,6 +1915,8 @@ menu_t OP_ScreenshotOptionsDef =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE("M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30);
|
||||||
|
|
||||||
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
|
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE("M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
@ -2092,6 +2135,12 @@ void Moviemode_mode_Onchange(void)
|
||||||
OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR;
|
OP_ScreenshotOptionsMenu[i].status = IT_STRING|IT_CVAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Addons_option_Onchange(void)
|
||||||
|
{
|
||||||
|
OP_AddonsOptionsMenu[op_addons_folder].status =
|
||||||
|
(cv_addons_option.value == 3 ? IT_CVAR|IT_STRING|IT_CV_STRING : IT_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// END ORGANIZATION STUFF.
|
// END ORGANIZATION STUFF.
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
@ -2154,9 +2203,12 @@ static void M_ChangeCvar(INT32 choice)
|
||||||
static boolean M_ChangeStringCvar(INT32 choice)
|
static boolean M_ChangeStringCvar(INT32 choice)
|
||||||
{
|
{
|
||||||
consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction;
|
consvar_t *cv = (consvar_t *)currentMenu->menuitems[itemOn].itemaction;
|
||||||
char buf[255];
|
char buf[MAXSTRINGLENGTH];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
if (shiftdown && choice >= 32 && choice <= 127)
|
||||||
|
choice = shiftxform[choice];
|
||||||
|
|
||||||
switch (choice)
|
switch (choice)
|
||||||
{
|
{
|
||||||
case KEY_BACKSPACE:
|
case KEY_BACKSPACE:
|
||||||
|
|
@ -2467,8 +2519,6 @@ boolean M_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
|
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
|
||||||
{
|
{
|
||||||
if (shiftdown && ch >= 32 && ch <= 127)
|
|
||||||
ch = shiftxform[ch];
|
|
||||||
if (M_ChangeStringCvar(ch))
|
if (M_ChangeStringCvar(ch))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
|
@ -2714,6 +2764,7 @@ void M_StartControlPanel(void)
|
||||||
else // multiplayer
|
else // multiplayer
|
||||||
{
|
{
|
||||||
MPauseMenu[mpause_switchmap].status = IT_DISABLED;
|
MPauseMenu[mpause_switchmap].status = IT_DISABLED;
|
||||||
|
MPauseMenu[mpause_addons].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_scramble].status = IT_DISABLED;
|
MPauseMenu[mpause_scramble].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_psetupsplit].status = IT_DISABLED;
|
MPauseMenu[mpause_psetupsplit].status = IT_DISABLED;
|
||||||
MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED;
|
MPauseMenu[mpause_psetupsplit2].status = IT_DISABLED;
|
||||||
|
|
@ -2725,6 +2776,7 @@ void M_StartControlPanel(void)
|
||||||
if ((server || adminplayer == consoleplayer))
|
if ((server || adminplayer == consoleplayer))
|
||||||
{
|
{
|
||||||
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
MPauseMenu[mpause_switchmap].status = IT_STRING | IT_CALL;
|
||||||
|
MPauseMenu[mpause_addons].status = IT_STRING | IT_CALL;
|
||||||
if (G_GametypeHasTeams())
|
if (G_GametypeHasTeams())
|
||||||
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
|
MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU;
|
||||||
}
|
}
|
||||||
|
|
@ -3281,7 +3333,7 @@ static void M_DrawGenericMenu(void)
|
||||||
y = currentMenu->y+currentMenu->menuitems[i].alphaKey;
|
y = currentMenu->y+currentMenu->menuitems[i].alphaKey;
|
||||||
|
|
||||||
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true, false);
|
||||||
y += SMALLLINEHEIGHT;
|
y += SMALLLINEHEIGHT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -3428,7 +3480,7 @@ static void M_DrawGenericScrollMenu(void)
|
||||||
break;
|
break;
|
||||||
case IT_HEADERTEXT:
|
case IT_HEADERTEXT:
|
||||||
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, true, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3945,7 +3997,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt)
|
||||||
I_Error("Insufficient memory to prepare level platter");
|
I_Error("Insufficient memory to prepare level platter");
|
||||||
|
|
||||||
// done here so lsrow and lscol can be set if cv_nextmap is on the platter
|
// done here so lsrow and lscol can be set if cv_nextmap is on the platter
|
||||||
lsrow = lscol = lstic = lshli = lsoffs[0] = lsoffs[1] = 0;
|
lsrow = lscol = lshli = lsoffs[0] = lsoffs[1] = 0;
|
||||||
|
|
||||||
while (mapnum < NUMMAPS)
|
while (mapnum < NUMMAPS)
|
||||||
{
|
{
|
||||||
|
|
@ -4204,10 +4256,10 @@ static void M_HandleLevelPlatter(INT32 choice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight)
|
void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlight, boolean allowlowercase)
|
||||||
{
|
{
|
||||||
y += lsheadingheight - 12;
|
y += lsheadingheight - 12;
|
||||||
V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0), header);
|
V_DrawString(19, y, (headerhighlight ? V_YELLOWMAP : 0)|(allowlowercase ? V_ALLOWLOWERCASE : 0), header);
|
||||||
y += 9;
|
y += 9;
|
||||||
if ((y >= 0) && (y < 200))
|
if ((y >= 0) && (y < 200))
|
||||||
{
|
{
|
||||||
|
|
@ -4216,9 +4268,7 @@ void M_DrawLevelPlatterHeader(INT32 y, const char *header, boolean headerhighlig
|
||||||
}
|
}
|
||||||
y++;
|
y++;
|
||||||
if ((y >= 0) && (y < 200))
|
if ((y >= 0) && (y < 200))
|
||||||
{
|
|
||||||
V_DrawFill(19, y, 282, 1, 26);
|
V_DrawFill(19, y, 282, 1, 26);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight)
|
static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolean highlight)
|
||||||
|
|
@ -4312,7 +4362,7 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y)
|
||||||
const boolean rowhighlight = (row == lsrow);
|
const boolean rowhighlight = (row == lsrow);
|
||||||
if (levelselect.rows[row].header[0])
|
if (levelselect.rows[row].header[0])
|
||||||
{
|
{
|
||||||
M_DrawLevelPlatterHeader(y, levelselect.rows[row].header, (rowhighlight || (row == lshli)));
|
M_DrawLevelPlatterHeader(y, levelselect.rows[row].header, (rowhighlight || (row == lshli)), false);
|
||||||
y += lsheadingheight;
|
y += lsheadingheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4331,9 +4381,6 @@ static void M_DrawLevelPlatterMenu(void)
|
||||||
INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow);
|
INT32 y = lsbasey + lsoffs[0] - getheadingoffset(lsrow);
|
||||||
const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation));
|
const INT32 cursorx = (sizeselect ? 0 : (lscol*lshseperation));
|
||||||
|
|
||||||
if (++lstic == 32)
|
|
||||||
lstic = 0;
|
|
||||||
|
|
||||||
if (gamestate == GS_TIMEATTACK)
|
if (gamestate == GS_TIMEATTACK)
|
||||||
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
|
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
|
||||||
|
|
||||||
|
|
@ -4353,7 +4400,7 @@ static void M_DrawLevelPlatterMenu(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw cursor box
|
// draw cursor box
|
||||||
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, ((lstic & 8) ? levselp[sizeselect][0] : levselp[sizeselect][1]));
|
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey, 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)]));
|
||||||
|
|
||||||
if (levelselect.rows[lsrow].maplist[lscol])
|
if (levelselect.rows[lsrow].maplist[lscol])
|
||||||
V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE));
|
||||||
|
|
@ -4653,6 +4700,511 @@ static void M_HandleImageDef(INT32 choice)
|
||||||
// MISC MAIN MENU OPTIONS
|
// MISC MAIN MENU OPTIONS
|
||||||
// ======================
|
// ======================
|
||||||
|
|
||||||
|
static void M_AddonsOptions(INT32 choice)
|
||||||
|
{
|
||||||
|
(void)choice;
|
||||||
|
Addons_option_Onchange();
|
||||||
|
|
||||||
|
M_SetupNextMenu(&OP_AddonsOptionsDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOCATIONSTRING "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!"
|
||||||
|
|
||||||
|
static void M_Addons(INT32 choice)
|
||||||
|
{
|
||||||
|
const char *pathname = ".";
|
||||||
|
|
||||||
|
(void)choice;
|
||||||
|
|
||||||
|
/*if (cv_addons_option.value == 0)
|
||||||
|
pathname = srb2home; usehome ? srb2home : srb2path;
|
||||||
|
else if (cv_addons_option.value == 1)
|
||||||
|
pathname = srb2home;
|
||||||
|
else if (cv_addons_option.value == 2)
|
||||||
|
pathname = srb2path;
|
||||||
|
else*/
|
||||||
|
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] != '/')
|
||||||
|
{
|
||||||
|
menupath[menupathindex[menudepthleft]-1] = '/';
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
--menupathindex[menudepthleft];
|
||||||
|
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
M_StartMessage(M_GetText("No files/folders found.\n\n"LOCATIONSTRING"\n\n(Press a key)\n"),NULL,MM_NOTHING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dir_on[menudepthleft] = 0;
|
||||||
|
|
||||||
|
if (addonsp[0]) // never going to have some provided but not all, saves individually checking
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < NUM_EXT+6; i++)
|
||||||
|
W_UnlockCachedPatch(addonsp[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC);
|
||||||
|
addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC);
|
||||||
|
addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_STATIC);
|
||||||
|
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC);
|
||||||
|
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC);
|
||||||
|
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC);
|
||||||
|
addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC);
|
||||||
|
addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL1", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+2] = W_CachePatchName("M_FSEL2", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+3] = W_CachePatchName("M_FLOAD", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+4] = W_CachePatchName("M_FSRCH", PU_STATIC);
|
||||||
|
addonsp[NUM_EXT+5] = W_CachePatchName("M_FSAVE", PU_STATIC);
|
||||||
|
|
||||||
|
MISC_AddonsDef.prevMenu = currentMenu;
|
||||||
|
M_SetupNextMenu(&MISC_AddonsDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define width 4
|
||||||
|
#define vpadding 27
|
||||||
|
#define h (BASEVIDHEIGHT-(2*vpadding))
|
||||||
|
#define NUMCOLOURS 8 // when toast's coding it's british english hacker fucker
|
||||||
|
static void M_DrawTemperature(INT32 x, fixed_t t)
|
||||||
|
{
|
||||||
|
INT32 y;
|
||||||
|
|
||||||
|
// bounds check
|
||||||
|
if (t > FRACUNIT)
|
||||||
|
t = FRACUNIT;
|
||||||
|
/*else if (t < 0) -- not needed
|
||||||
|
t = 0;*/
|
||||||
|
|
||||||
|
// scale
|
||||||
|
if (t > 1)
|
||||||
|
t = (FixedMul(h<<FRACBITS, t)>>FRACBITS);
|
||||||
|
|
||||||
|
// border
|
||||||
|
V_DrawFill(x - 1, vpadding, 1, h, 3);
|
||||||
|
V_DrawFill(x + width, vpadding, 1, h, 3);
|
||||||
|
V_DrawFill(x - 1, vpadding-1, width+2, 1, 3);
|
||||||
|
V_DrawFill(x - 1, vpadding+h, width+2, 1, 3);
|
||||||
|
|
||||||
|
// bar itself
|
||||||
|
y = h;
|
||||||
|
if (t)
|
||||||
|
for (t = h - t; y > 0; y--)
|
||||||
|
{
|
||||||
|
UINT8 colours[NUMCOLOURS] = {42, 40, 58, 222, 65, 90, 97, 98};
|
||||||
|
UINT8 c;
|
||||||
|
if (y <= t) break;
|
||||||
|
if (y+vpadding >= BASEVIDHEIGHT/2)
|
||||||
|
c = 113;
|
||||||
|
else
|
||||||
|
c = colours[(NUMCOLOURS*(y-1))/(h/2)];
|
||||||
|
V_DrawFill(x, y-1 + vpadding, width, 1, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill the rest of the backing
|
||||||
|
if (y)
|
||||||
|
V_DrawFill(x, vpadding, width, y, 27);
|
||||||
|
}
|
||||||
|
#undef width
|
||||||
|
#undef vpadding
|
||||||
|
#undef h
|
||||||
|
#undef NUMCOLOURS
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
len = strlen(header);
|
||||||
|
if (len > 34)
|
||||||
|
{
|
||||||
|
len = len-34;
|
||||||
|
header[len] = header[len+1] = header[len+2] = '.';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
return header+len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UNEXIST S_StartSound(NULL, sfx_lose);\
|
||||||
|
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)
|
||||||
|
|
||||||
|
// returns whether to do message draw
|
||||||
|
static boolean M_AddonsRefresh(void)
|
||||||
|
{
|
||||||
|
if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refreshdirmenu & REFRESHDIR_ADDFILE)
|
||||||
|
{
|
||||||
|
addonsresponselimit = 0;
|
||||||
|
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_strpst);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define offs 1
|
||||||
|
|
||||||
|
static void M_DrawAddons(void)
|
||||||
|
{
|
||||||
|
INT32 x, y;
|
||||||
|
ssize_t i, max;
|
||||||
|
|
||||||
|
// hack - need to refresh at end of frame to handle addfile...
|
||||||
|
if (refreshdirmenu & M_AddonsRefresh())
|
||||||
|
return M_DrawMessageMenu();
|
||||||
|
|
||||||
|
if (addonsresponselimit)
|
||||||
|
addonsresponselimit--;
|
||||||
|
|
||||||
|
V_DrawCenteredString(BASEVIDWIDTH/2, 4+offs, 0, (Playing()
|
||||||
|
? "\x85""Adding files mid-game may cause problems."
|
||||||
|
: LOCATIONSTRING));
|
||||||
|
|
||||||
|
if (numwadfiles <= mainwads+1)
|
||||||
|
y = 0;
|
||||||
|
else if (numwadfiles >= MAX_WADFILES)
|
||||||
|
y = FRACUNIT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = FixedDiv((numwadfiles - mainwads+1)<<FRACBITS, (MAX_WADFILES - mainwads+1)<<FRACBITS);
|
||||||
|
y = FixedDiv(((packetsizetally-mainwadstally)<<FRACBITS), (((MAXFILENEEDED*sizeof(UINT8)-mainwadstally)-(5+22))<<FRACBITS)); // 5+22 = (a.ext + checksum length) is minimum addition to packet size tally
|
||||||
|
if (x > y)
|
||||||
|
y = x;
|
||||||
|
if (y > FRACUNIT) // happens because of how we're shrinkin' it a little
|
||||||
|
y = FRACUNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_DrawTemperature(BASEVIDWIDTH - 19 - 5, y);
|
||||||
|
|
||||||
|
// DRAW MENU
|
||||||
|
x = currentMenu->x;
|
||||||
|
y = currentMenu->y + offs;
|
||||||
|
|
||||||
|
//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());
|
||||||
|
V_DrawFill(x-21, (y - 16) + (lsheadingheight - 3), (MAXSTRINGLENGTH*8+6 - 1), 1, yellowmap[3]);
|
||||||
|
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);
|
||||||
|
|
||||||
|
// get bottom...
|
||||||
|
max = dir_on[menudepthleft] + numaddonsshown + 1;
|
||||||
|
if (max > (ssize_t)sizedirmenu)
|
||||||
|
max = sizedirmenu;
|
||||||
|
|
||||||
|
// then top...
|
||||||
|
i = max - (2*numaddonsshown + 1);
|
||||||
|
|
||||||
|
// then adjust!
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
if ((max -= i) > (ssize_t)sizedirmenu)
|
||||||
|
max = sizedirmenu;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
V_DrawString(19, y+4 - (skullAnimCounter/5), V_YELLOWMAP, "\x1A");
|
||||||
|
|
||||||
|
for (; i < max; i++)
|
||||||
|
{
|
||||||
|
UINT32 flags = V_ALLOWLOWERCASE;
|
||||||
|
if (y > BASEVIDHEIGHT) break;
|
||||||
|
if (dirmenu[i])
|
||||||
|
#define type (UINT8)(dirmenu[i][DIR_TYPE])
|
||||||
|
{
|
||||||
|
if (type & EXT_LOADED)
|
||||||
|
flags |= V_TRANSLUCENT;
|
||||||
|
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, (flags & V_TRANSLUCENT), addonsp[((UINT8)(dirmenu[i][DIR_TYPE]) & ~EXT_LOADED)]);
|
||||||
|
|
||||||
|
if (type & EXT_LOADED)
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+3]);
|
||||||
|
|
||||||
|
if ((size_t)i == dir_on[menudepthleft])
|
||||||
|
{
|
||||||
|
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+1+((skullAnimCounter/4) ? 1 : 0)]);
|
||||||
|
flags = V_ALLOWLOWERCASE|V_YELLOWMAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define charsonside 14
|
||||||
|
if (dirmenu[i][DIR_LEN] > (charsonside*2 + 3))
|
||||||
|
V_DrawString(x, y+4, flags, va("%.*s...%s", charsonside, dirmenu[i]+DIR_STRING, dirmenu[i]+DIR_STRING+dirmenu[i][DIR_LEN]-(charsonside+1)));
|
||||||
|
#undef charsonside
|
||||||
|
else
|
||||||
|
V_DrawString(x, y+4, flags, dirmenu[i]+DIR_STRING);
|
||||||
|
}
|
||||||
|
#undef type
|
||||||
|
y += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max != (ssize_t)sizedirmenu)
|
||||||
|
V_DrawString(19, y-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B");
|
||||||
|
|
||||||
|
y = BASEVIDHEIGHT - currentMenu->y + offs;
|
||||||
|
|
||||||
|
M_DrawTextBox(x - (21 + 5), y, MAXSTRINGLENGTH, 1);
|
||||||
|
if (menusearch[0])
|
||||||
|
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE, menusearch+1);
|
||||||
|
else
|
||||||
|
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Type to search...");
|
||||||
|
if (skullAnimCounter < 4)
|
||||||
|
V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8,
|
||||||
|
'_' | 0x80, false);
|
||||||
|
|
||||||
|
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]);
|
||||||
|
|
||||||
|
if CANSAVE
|
||||||
|
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+3]);
|
||||||
|
#undef CANSAVE
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef offs
|
||||||
|
|
||||||
|
static void M_AddonExec(INT32 ch)
|
||||||
|
{
|
||||||
|
if (ch != 'y' && ch != KEY_ENTER)
|
||||||
|
return;
|
||||||
|
|
||||||
|
S_StartSound(NULL, sfx_zoom);
|
||||||
|
COM_BufAddText(va("exec %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define len menusearch[0]
|
||||||
|
static boolean M_ChangeStringAddons(INT32 choice)
|
||||||
|
{
|
||||||
|
if (shiftdown && choice >= 32 && choice <= 127)
|
||||||
|
choice = shiftxform[choice];
|
||||||
|
|
||||||
|
switch (choice)
|
||||||
|
{
|
||||||
|
case KEY_DEL:
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
len = menusearch[1] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
menusearch[1+--len] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (choice >= 32 && choice <= 127)
|
||||||
|
{
|
||||||
|
if (len < MAXSTRINGLENGTH - 1)
|
||||||
|
{
|
||||||
|
menusearch[1+len++] = (char)choice;
|
||||||
|
menusearch[1+len] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#undef len
|
||||||
|
|
||||||
|
static void M_HandleAddons(INT32 choice)
|
||||||
|
{
|
||||||
|
boolean exitmenu = false; // exit to previous menu
|
||||||
|
|
||||||
|
if (addonsresponselimit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (M_ChangeStringAddons(choice))
|
||||||
|
{
|
||||||
|
if (!preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (choice)
|
||||||
|
{
|
||||||
|
case KEY_DOWNARROW:
|
||||||
|
if (dir_on[menudepthleft] < sizedirmenu-1)
|
||||||
|
dir_on[menudepthleft]++;
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_UPARROW:
|
||||||
|
if (dir_on[menudepthleft])
|
||||||
|
dir_on[menudepthleft]--;
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_PGDN:
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
for (i = numaddonsshown; i && (dir_on[menudepthleft] < sizedirmenu-1); i--)
|
||||||
|
dir_on[menudepthleft]++;
|
||||||
|
}
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_PGUP:
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
for (i = numaddonsshown; i && (dir_on[menudepthleft]); i--)
|
||||||
|
dir_on[menudepthleft]--;
|
||||||
|
}
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
case KEY_ENTER:
|
||||||
|
{
|
||||||
|
boolean refresh = true;
|
||||||
|
if (!dirmenu[dir_on[menudepthleft]])
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE])
|
||||||
|
{
|
||||||
|
case EXT_FOLDER:
|
||||||
|
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING);
|
||||||
|
if (menudepthleft)
|
||||||
|
{
|
||||||
|
menupathindex[--menudepthleft] = strlen(menupath);
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_skid);
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis folder is empty.\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||||
|
menupath[menupathindex[++menudepthleft]] = 0;
|
||||||
|
|
||||||
|
if (!preparefilemenu(true))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
dir_on[menudepthleft] = 1;
|
||||||
|
}
|
||||||
|
refresh = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis folder is too deep to navigate to!\n\n(Press a key)\n", M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||||
|
menupath[menupathindex[menudepthleft]] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXT_UP:
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
menupath[menupathindex[++menudepthleft]] = 0;
|
||||||
|
if (!preparefilemenu(false))
|
||||||
|
{
|
||||||
|
UNEXIST;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXT_TXT:
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis file may not be a console script.\nAttempt to run anyways? \n\n(Press 'Y' to confirm)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING),M_AddonExec,MM_YESNO);
|
||||||
|
break;
|
||||||
|
case EXT_CFG:
|
||||||
|
M_AddonExec(KEY_ENTER);
|
||||||
|
break;
|
||||||
|
case EXT_LUA:
|
||||||
|
#ifndef HAVE_BLUA
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
M_StartMessage(va("\x82%s\x80\nThis copy of SRB2 was compiled\nwithout support for .lua files.\n\n(Press a key)\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
// else intentional fallthrough
|
||||||
|
case EXT_SOC:
|
||||||
|
case EXT_WAD:
|
||||||
|
COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
|
||||||
|
addonsresponselimit = 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
S_StartSound(NULL, sfx_lose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (refresh)
|
||||||
|
refreshdirmenu |= REFRESHDIR_NORMAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_ESCAPE:
|
||||||
|
exitmenu = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (exitmenu)
|
||||||
|
{
|
||||||
|
for (; sizedirmenu > 0; sizedirmenu--)
|
||||||
|
{
|
||||||
|
Z_Free(dirmenu[sizedirmenu-1]);
|
||||||
|
dirmenu[sizedirmenu-1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(dirmenu);
|
||||||
|
dirmenu = NULL;
|
||||||
|
|
||||||
|
// secrets disabled by addfile...
|
||||||
|
MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
|
||||||
|
|
||||||
|
if (currentMenu->prevMenu)
|
||||||
|
M_SetupNextMenu(currentMenu->prevMenu);
|
||||||
|
else
|
||||||
|
M_ClearMenus(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void M_PandorasBox(INT32 choice)
|
static void M_PandorasBox(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
|
@ -4755,7 +5307,7 @@ static void M_Options(INT32 choice)
|
||||||
OP_MainMenu[5].status = (Playing() && !(server || adminplayer == consoleplayer)) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL);
|
OP_MainMenu[5].status = (Playing() && !(server || adminplayer == consoleplayer)) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL);
|
||||||
|
|
||||||
// if the player is playing _at all_, disable the erase data options
|
// if the player is playing _at all_, disable the erase data options
|
||||||
OP_DataOptionsMenu[1].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
OP_DataOptionsMenu[2].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU);
|
||||||
|
|
||||||
OP_MainDef.prevMenu = currentMenu;
|
OP_MainDef.prevMenu = currentMenu;
|
||||||
M_SetupNextMenu(&OP_MainDef);
|
M_SetupNextMenu(&OP_MainDef);
|
||||||
|
|
@ -5188,9 +5740,7 @@ static void M_DrawChecklist(void)
|
||||||
|
|
||||||
finishchecklist:
|
finishchecklist:
|
||||||
if ((checklist_cangodown = ((y - currentMenu->y) > (scrollareaheight*2)))) // haaaaaaacks.
|
if ((checklist_cangodown = ((y - currentMenu->y) > (scrollareaheight*2)))) // haaaaaaacks.
|
||||||
{
|
|
||||||
V_DrawString(10, currentMenu->y+(scrollareaheight*2)+(skullAnimCounter/5), V_YELLOWMAP, "\x1B");
|
V_DrawString(10, currentMenu->y+(scrollareaheight*2)+(skullAnimCounter/5), V_YELLOWMAP, "\x1B");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUMHINTS 5
|
#define NUMHINTS 5
|
||||||
|
|
@ -6507,7 +7057,7 @@ void M_DrawTimeAttackMenu(void)
|
||||||
lumpnum_t lumpnum;
|
lumpnum_t lumpnum;
|
||||||
char beststr[40];
|
char beststr[40];
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true);
|
M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true, false);
|
||||||
|
|
||||||
// A 160x100 image of the level as entry MAPxxP
|
// A 160x100 image of the level as entry MAPxxP
|
||||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
||||||
|
|
@ -6691,7 +7241,7 @@ void M_DrawNightsAttackMenu(void)
|
||||||
UINT32 bestscore = G_GetBestNightsScore(cv_nextmap.value, cv_dummymares.value);
|
UINT32 bestscore = G_GetBestNightsScore(cv_nextmap.value, cv_dummymares.value);
|
||||||
tic_t besttime = G_GetBestNightsTime(cv_nextmap.value, cv_dummymares.value);
|
tic_t besttime = G_GetBestNightsTime(cv_nextmap.value, cv_dummymares.value);
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true);
|
M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true, false);
|
||||||
|
|
||||||
// A 160x100 image of the level as entry MAPxxP
|
// A 160x100 image of the level as entry MAPxxP
|
||||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
||||||
|
|
@ -7447,7 +7997,7 @@ static void M_DrawServerMenu(void)
|
||||||
// Room name
|
// Room name
|
||||||
if (currentMenu == &MP_ServerDef)
|
if (currentMenu == &MP_ServerDef)
|
||||||
{
|
{
|
||||||
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight/2, "Server settings", true);
|
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight/2, "Server settings", true, false);
|
||||||
if (ms_RoomId < 0)
|
if (ms_RoomId < 0)
|
||||||
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
|
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey,
|
||||||
V_YELLOWMAP, (itemOn == mp_server_room) ? "<Select to change>" : "<Offline Mode>");
|
V_YELLOWMAP, (itemOn == mp_server_room) ? "<Select to change>" : "<Offline Mode>");
|
||||||
|
|
@ -7470,7 +8020,7 @@ static void M_DrawServerMenu(void)
|
||||||
|
|
||||||
sprintf(headerstr, "%s - %s", cv_newgametype.string, cv_nextmap.string);
|
sprintf(headerstr, "%s - %s", cv_newgametype.string, cv_nextmap.string);
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(currentMenu->y + imgheight - 10 - lsheadingheight/2, (const char *)headerstr, true);
|
M_DrawLevelPlatterHeader(currentMenu->y + imgheight - 10 - lsheadingheight/2, (const char *)headerstr, true, false);
|
||||||
|
|
||||||
// A 160x100 image of the level as entry MAPxxP
|
// A 160x100 image of the level as entry MAPxxP
|
||||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
||||||
|
|
@ -7500,7 +8050,7 @@ static void M_GameTypeChange(INT32 choice)
|
||||||
void M_DrawGameTypeMenu(void)
|
void M_DrawGameTypeMenu(void)
|
||||||
{
|
{
|
||||||
M_DrawGenericMenu();
|
M_DrawGenericMenu();
|
||||||
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight, "Select Gametype", true);
|
M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight, "Select Gametype", true, false);
|
||||||
|
|
||||||
if (!char_notes)
|
if (!char_notes)
|
||||||
char_notes = V_WordWrap(0, (160 - 30) - 8, V_ALLOWLOWERCASE, gametypedesc[itemOn].notes);
|
char_notes = V_WordWrap(0, (160 - 30) - 8, V_ALLOWLOWERCASE, gametypedesc[itemOn].notes);
|
||||||
|
|
@ -7751,7 +8301,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||||
// draw title (or big pic)
|
// draw title (or big pic)
|
||||||
M_DrawMenuTitle();
|
M_DrawMenuTitle();
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Name", true);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Name", true, false);
|
||||||
if (itemOn == 0)
|
if (itemOn == 0)
|
||||||
cursory = y;
|
cursory = y;
|
||||||
y += 11;
|
y += 11;
|
||||||
|
|
@ -7765,7 +8315,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||||
|
|
||||||
y += 20;
|
y += 20;
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Character", true);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Character", true, false);
|
||||||
if (itemOn == 1)
|
if (itemOn == 1)
|
||||||
cursory = y;
|
cursory = y;
|
||||||
|
|
||||||
|
|
@ -7842,7 +8392,7 @@ colordraw:
|
||||||
x = MP_PlayerSetupDef.x;
|
x = MP_PlayerSetupDef.x;
|
||||||
y += 75;
|
y += 75;
|
||||||
|
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Color", true);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Color", true, false);
|
||||||
if (itemOn == 2)
|
if (itemOn == 2)
|
||||||
cursory = y;
|
cursory = y;
|
||||||
|
|
||||||
|
|
@ -8400,7 +8950,7 @@ static void M_DrawControl(void)
|
||||||
/*else if (currentMenu->menuitems[i].status == IT_GRAYEDOUT2)
|
/*else if (currentMenu->menuitems[i].status == IT_GRAYEDOUT2)
|
||||||
V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text);*/
|
V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text);*/
|
||||||
else if ((currentMenu->menuitems[i].status == IT_HEADER) && (i != max-1))
|
else if ((currentMenu->menuitems[i].status == IT_HEADER) && (i != max-1))
|
||||||
M_DrawLevelPlatterHeader(y, currentMenu->menuitems[i].text, true);
|
M_DrawLevelPlatterHeader(y, currentMenu->menuitems[i].text, true, false);
|
||||||
|
|
||||||
y += SMALLLINEHEIGHT;
|
y += SMALLLINEHEIGHT;
|
||||||
}
|
}
|
||||||
|
|
@ -8997,7 +9547,7 @@ static void M_DrawColorMenu(void)
|
||||||
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
//V_DrawString(x-16, y, V_YELLOWMAP, currentMenu->menuitems[i].text);
|
||||||
V_DrawFill(19, y, 281, 9, currentMenu->menuitems[i+1].alphaKey);
|
V_DrawFill(19, y, 281, 9, currentMenu->menuitems[i+1].alphaKey);
|
||||||
V_DrawFill(300, y, 1, 9, 26);
|
V_DrawFill(300, y, 1, 9, 26);
|
||||||
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, false);
|
M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), currentMenu->menuitems[i].text, false, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
src/m_menu.h
17
src/m_menu.h
|
|
@ -124,6 +124,8 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
|
||||||
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
#define IT_HEADER (IT_SPACE +IT_HEADERTEXT)
|
||||||
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
#define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS)
|
||||||
|
|
||||||
|
#define MAXSTRINGLENGTH 32
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
struct menu_s *submenu; // IT_SUBMENU
|
struct menu_s *submenu; // IT_SUBMENU
|
||||||
|
|
@ -249,6 +251,9 @@ void Nextmap_OnChange(void);
|
||||||
void Moviemode_mode_Onchange(void);
|
void Moviemode_mode_Onchange(void);
|
||||||
void Screenshot_option_Onchange(void);
|
void Screenshot_option_Onchange(void);
|
||||||
|
|
||||||
|
// Addons menu updating
|
||||||
|
void Addons_option_Onchange(void);
|
||||||
|
|
||||||
// These defines make it a little easier to make menus
|
// These defines make it a little easier to make menus
|
||||||
#define DEFAULTMENUSTYLE(header, source, prev, x, y)\
|
#define DEFAULTMENUSTYLE(header, source, prev, x, y)\
|
||||||
{\
|
{\
|
||||||
|
|
@ -262,6 +267,18 @@ void Screenshot_option_Onchange(void);
|
||||||
NULL\
|
NULL\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEFAULTSCROLLMENUSTYLE(header, source, prev, x, y)\
|
||||||
|
{\
|
||||||
|
header,\
|
||||||
|
sizeof(source)/sizeof(menuitem_t),\
|
||||||
|
prev,\
|
||||||
|
source,\
|
||||||
|
M_DrawGenericScrollMenu,\
|
||||||
|
x, y,\
|
||||||
|
0,\
|
||||||
|
NULL\
|
||||||
|
}
|
||||||
|
|
||||||
#define PAUSEMENUSTYLE(source, x, y)\
|
#define PAUSEMENUSTYLE(source, x, y)\
|
||||||
{\
|
{\
|
||||||
NULL,\
|
NULL,\
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2
|
||||||
consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
|
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
|
||||||
consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
|
||||||
|
|
@ -878,7 +878,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
|
|
||||||
if (!(mo2->flags & MF_SPECIAL) && mo2->health)
|
if (!(mo2->flags & MF_SPECIAL) && mo2->health)
|
||||||
{
|
{
|
||||||
P_SetMobjState(mo2, mo2->info->seestate);
|
mo2->flags2 &= ~MF2_DONTDRAW;
|
||||||
mo2->flags |= MF_SPECIAL;
|
mo2->flags |= MF_SPECIAL;
|
||||||
mo2->flags &= ~MF_NIGHTSITEM;
|
mo2->flags &= ~MF_NIGHTSITEM;
|
||||||
S_StartSound(toucher, sfx_hidden);
|
S_StartSound(toucher, sfx_hidden);
|
||||||
|
|
@ -887,7 +887,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
|
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
|
||||||
|| mo2->type == MT_BLUEBALL))
|
|| mo2->type == MT_BLUEBALL
|
||||||
|
|| ((mo2->type == MT_EMBLEM) && (mo2->reactiontime & GE_NIGHTSPULL))))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Yay! The thing's in reach! Pull it in!
|
// Yay! The thing's in reach! Pull it in!
|
||||||
|
|
|
||||||
|
|
@ -7627,6 +7627,10 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
if (mobj->flags2 & MF2_NIGHTSPULL)
|
if (mobj->flags2 & MF2_NIGHTSPULL)
|
||||||
P_NightsItemChase(mobj);
|
P_NightsItemChase(mobj);
|
||||||
break;
|
break;
|
||||||
|
case MT_EMBLEM:
|
||||||
|
if (mobj->flags2 & MF2_NIGHTSPULL)
|
||||||
|
P_NightsItemChase(mobj);
|
||||||
|
break;
|
||||||
case MT_SHELL:
|
case MT_SHELL:
|
||||||
if (mobj->threshold && mobj->threshold != TICRATE)
|
if (mobj->threshold && mobj->threshold != TICRATE)
|
||||||
mobj->threshold--;
|
mobj->threshold--;
|
||||||
|
|
@ -10055,7 +10059,6 @@ ML_NOCLIMB : Direction not controllable
|
||||||
// Spawn already displayed
|
// Spawn already displayed
|
||||||
mobj->flags |= MF_SPECIAL;
|
mobj->flags |= MF_SPECIAL;
|
||||||
mobj->flags &= ~MF_NIGHTSITEM;
|
mobj->flags &= ~MF_NIGHTSITEM;
|
||||||
P_SetMobjState(mobj, mobj->info->seestate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->flags & MF_PUSHABLE)
|
if (mobj->flags & MF_PUSHABLE)
|
||||||
|
|
@ -10108,6 +10111,10 @@ ML_NOCLIMB : Direction not controllable
|
||||||
mobj->flags2 |= MF2_OBJECTFLIP;
|
mobj->flags2 |= MF2_OBJECTFLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final set of not being able to draw nightsitems.
|
||||||
|
if (mobj->flags & MF_NIGHTSITEM)
|
||||||
|
mobj->flags2 |= MF2_DONTDRAW;
|
||||||
|
|
||||||
mthing->mobj = mobj;
|
mthing->mobj = mobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@
|
||||||
|
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
|
||||||
|
#include "filesrch.h" // refreshdirmenu
|
||||||
|
|
||||||
// wipes
|
// wipes
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
|
|
||||||
|
|
@ -1118,7 +1120,20 @@ static inline void P_SpawnEmblems(void)
|
||||||
P_SetThingPosition(emblemmobj);
|
P_SetThingPosition(emblemmobj);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
emblemmobj->frame &= ~FF_TRANSMASK;
|
emblemmobj->frame &= ~FF_TRANSMASK;
|
||||||
|
|
||||||
|
if (emblemlocations[i].type == ET_GLOBAL)
|
||||||
|
{
|
||||||
|
emblemmobj->reactiontime = emblemlocations[i].var;
|
||||||
|
if (emblemlocations[i].var & GE_NIGHTSITEM)
|
||||||
|
{
|
||||||
|
emblemmobj->flags |= MF_NIGHTSITEM;
|
||||||
|
emblemmobj->flags &= ~MF_SPECIAL;
|
||||||
|
emblemmobj->flags2 |= MF2_DONTDRAW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3091,6 +3106,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
|
||||||
|
|
||||||
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
|
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
|
||||||
{
|
{
|
||||||
|
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||||
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
|
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5879,10 +5879,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
}
|
}
|
||||||
else // Otherwise, set calculated offsets such that line's v1 is the apparent origin
|
else // Otherwise, set calculated offsets such that line's v1 is the apparent origin
|
||||||
{
|
{
|
||||||
fixed_t cosinecomponent = FINECOSINE(flatangle>>ANGLETOFINESHIFT);
|
xoffs = -lines[i].v1->x;
|
||||||
fixed_t sinecomponent = FINESINE(flatangle>>ANGLETOFINESHIFT);
|
yoffs = lines[i].v1->y;
|
||||||
xoffs = (-FixedMul(lines[i].v1->x, cosinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, sinecomponent) % MAXFLATSIZE); // No danger of overflow thanks to the strategically placed modulo operations.
|
|
||||||
yoffs = (FixedMul(lines[i].v1->x, sinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, cosinecomponent) % MAXFLATSIZE); // Ditto.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||||
|
|
|
||||||
|
|
@ -445,17 +445,18 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (slope); else // Don't mess with this right now if a slope is involved
|
if (slope); else // Don't mess with this right now if a slope is involved
|
||||||
#endif
|
#endif
|
||||||
if (plangle != 0)
|
|
||||||
{
|
|
||||||
// Add the view offset, rotated by the plane angle.
|
|
||||||
angle_t angle = plangle>>ANGLETOFINESHIFT;
|
|
||||||
xoff += FixedMul(viewx,FINECOSINE(angle))-FixedMul(viewy,FINESINE(angle));
|
|
||||||
yoff += -FixedMul(viewx,FINESINE(angle))-FixedMul(viewy,FINECOSINE(angle));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
xoff += viewx;
|
xoff += viewx;
|
||||||
yoff -= viewy;
|
yoff -= viewy;
|
||||||
|
if (plangle != 0)
|
||||||
|
{
|
||||||
|
// Add the view offset, rotated by the plane angle.
|
||||||
|
fixed_t cosinecomponent = FINECOSINE(plangle>>ANGLETOFINESHIFT);
|
||||||
|
fixed_t sinecomponent = FINESINE(plangle>>ANGLETOFINESHIFT);
|
||||||
|
fixed_t oldxoff = xoff;
|
||||||
|
xoff = FixedMul(xoff,cosinecomponent)+FixedMul(yoff,sinecomponent);
|
||||||
|
yoff = -FixedMul(oldxoff,sinecomponent)+FixedMul(yoff,cosinecomponent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This appears to fix the Nimbus Ruins sky bug.
|
// This appears to fix the Nimbus Ruins sky bug.
|
||||||
|
|
@ -483,6 +484,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||||
&& !pfloor && !check->ffloor
|
&& !pfloor && !check->ffloor
|
||||||
&& check->viewx == viewx && check->viewy == viewy && check->viewz == viewz
|
&& check->viewx == viewx && check->viewy == viewy && check->viewz == viewz
|
||||||
&& check->viewangle == viewangle
|
&& check->viewangle == viewangle
|
||||||
|
&& check->plangle == plangle
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
&& check->slope == slope
|
&& check->slope == slope
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -951,19 +953,57 @@ void R_DrawSinglePlane(visplane_t *pl)
|
||||||
floatv3_t p, m, n;
|
floatv3_t p, m, n;
|
||||||
float ang;
|
float ang;
|
||||||
float vx, vy, vz;
|
float vx, vy, vz;
|
||||||
float fudge;
|
|
||||||
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
||||||
// use this as a temp var to store P_GetZAt's return value each time
|
// use this as a temp var to store P_GetZAt's return value each time
|
||||||
fixed_t temp;
|
fixed_t temp;
|
||||||
|
|
||||||
xoffs &= ((1 << (32-nflatshiftup))-1);
|
|
||||||
yoffs &= ((1 << (32-nflatshiftup))-1);
|
|
||||||
|
|
||||||
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
|
|
||||||
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
|
|
||||||
|
|
||||||
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
|
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
|
||||||
fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
|
const float fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
|
||||||
|
|
||||||
|
angle_t hack = (pl->plangle & (ANGLE_90-1));
|
||||||
|
|
||||||
|
yoffs *= 1;
|
||||||
|
|
||||||
|
if (hack)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Essentially: We can't & the components along the regular axes when the plane is rotated.
|
||||||
|
This is because the distance on each regular axis in order to loop is different.
|
||||||
|
We rotate them, & the components, add them together, & them again, and then rotate them back.
|
||||||
|
These three seperate & operations are done per axis in order to prevent overflows.
|
||||||
|
toast 10/04/17
|
||||||
|
*/
|
||||||
|
const fixed_t cosinecomponent = FINECOSINE(hack>>ANGLETOFINESHIFT);
|
||||||
|
const fixed_t sinecomponent = FINESINE(hack>>ANGLETOFINESHIFT);
|
||||||
|
|
||||||
|
const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1);
|
||||||
|
|
||||||
|
fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask);
|
||||||
|
fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask);
|
||||||
|
|
||||||
|
temp = ox & modmask;
|
||||||
|
oy &= modmask;
|
||||||
|
ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction
|
||||||
|
oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent);
|
||||||
|
|
||||||
|
temp = xoffs;
|
||||||
|
xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask);
|
||||||
|
yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask);
|
||||||
|
|
||||||
|
temp = xoffs & modmask;
|
||||||
|
yoffs &= modmask;
|
||||||
|
xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto
|
||||||
|
yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent);
|
||||||
|
|
||||||
|
xoffs -= (pl->slope->o.x - ox);
|
||||||
|
yoffs += (pl->slope->o.y + oy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xoffs &= ((1 << (32-nflatshiftup))-1);
|
||||||
|
yoffs &= ((1 << (32-nflatshiftup))-1);
|
||||||
|
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
|
||||||
|
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
|
||||||
|
}
|
||||||
|
|
||||||
xoffs = (fixed_t)(xoffs*fudge);
|
xoffs = (fixed_t)(xoffs*fudge);
|
||||||
yoffs = (fixed_t)(yoffs/fudge);
|
yoffs = (fixed_t)(yoffs/fudge);
|
||||||
|
|
|
||||||
39
src/w_wad.c
39
src/w_wad.c
|
|
@ -34,6 +34,8 @@
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
|
|
||||||
|
#include "filesrch.h"
|
||||||
|
|
||||||
#include "i_video.h" // rendermode
|
#include "i_video.h" // rendermode
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
#include "dehacked.h"
|
#include "dehacked.h"
|
||||||
|
|
@ -294,12 +296,12 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
UINT32 numlumps;
|
UINT32 numlumps;
|
||||||
size_t i;
|
size_t i;
|
||||||
INT32 compressed = 0;
|
INT32 compressed = 0;
|
||||||
size_t packetsize = 0;
|
size_t packetsize;
|
||||||
serverinfo_pak *dummycheck = NULL;
|
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
boolean important;
|
||||||
|
|
||||||
// Shut the compiler up.
|
if (!(refreshdirmenu & REFRESHDIR_ADDFILE))
|
||||||
(void)dummycheck;
|
refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier
|
||||||
|
|
||||||
//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
|
//CONS_Debug(DBG_SETUP, "Loading %s\n", filename);
|
||||||
//
|
//
|
||||||
|
|
@ -308,6 +310,7 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
if (numwadfiles >= MAX_WADFILES)
|
if (numwadfiles >= MAX_WADFILES)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||||
|
refreshdirmenu |= REFRESHDIR_MAX;
|
||||||
return INT16_MAX;
|
return INT16_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,21 +320,23 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
|
|
||||||
// Check if wad files will overflow fileneededbuffer. Only the filename part
|
// Check if wad files will overflow fileneededbuffer. Only the filename part
|
||||||
// is send in the packet; cf.
|
// is send in the packet; cf.
|
||||||
for (i = 0; i < numwadfiles; i++)
|
// see PutFileNeeded in d_netfil.c
|
||||||
|
if ((important = !W_VerifyNMUSlumps(filename)))
|
||||||
{
|
{
|
||||||
packetsize += nameonlylength(wadfiles[i]->filename);
|
packetsize = packetsizetally;
|
||||||
packetsize += 22; // MD5, etc.
|
|
||||||
}
|
|
||||||
|
|
||||||
packetsize += nameonlylength(filename);
|
packetsize += nameonlylength(filename) + 22;
|
||||||
packetsize += 22;
|
|
||||||
|
|
||||||
if (packetsize > sizeof(dummycheck->fileneeded))
|
if (packetsize > MAXFILENEEDED*sizeof(UINT8))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||||
if (handle)
|
refreshdirmenu |= REFRESHDIR_MAX;
|
||||||
fclose(handle);
|
if (handle)
|
||||||
return INT16_MAX;
|
fclose(handle);
|
||||||
|
return INT16_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetsizetally = packetsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect dehacked file with the "soc" extension
|
// detect dehacked file with the "soc" extension
|
||||||
|
|
@ -470,6 +475,7 @@ UINT16 W_LoadWadFile(const char *filename)
|
||||||
wadfile->handle = handle;
|
wadfile->handle = handle;
|
||||||
wadfile->numlumps = (UINT16)numlumps;
|
wadfile->numlumps = (UINT16)numlumps;
|
||||||
wadfile->lumpinfo = lumpinfo;
|
wadfile->lumpinfo = lumpinfo;
|
||||||
|
wadfile->important = important;
|
||||||
fseek(handle, 0, SEEK_END);
|
fseek(handle, 0, SEEK_END);
|
||||||
wadfile->filesize = (unsigned)ftell(handle);
|
wadfile->filesize = (unsigned)ftell(handle);
|
||||||
|
|
||||||
|
|
@ -1239,6 +1245,7 @@ int W_VerifyNMUSlumps(const char *filename)
|
||||||
{"TNYFN", 5}, // Tiny console font changes
|
{"TNYFN", 5}, // Tiny console font changes
|
||||||
{"STT", 3}, // Acceptable HUD changes (Score Time Rings)
|
{"STT", 3}, // Acceptable HUD changes (Score Time Rings)
|
||||||
{"YB_", 3}, // Intermission graphics, goes with the above
|
{"YB_", 3}, // Intermission graphics, goes with the above
|
||||||
|
{"M_", 2}, // As does menu stuff
|
||||||
|
|
||||||
{NULL, 0},
|
{NULL, 0},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ typedef struct wadfile_s
|
||||||
FILE *handle;
|
FILE *handle;
|
||||||
UINT32 filesize; // for network
|
UINT32 filesize; // for network
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
|
boolean important; // also network - !W_VerifyNMUSlumps
|
||||||
} wadfile_t;
|
} wadfile_t;
|
||||||
|
|
||||||
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word
|
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue