Compare commits
140
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80da0fc538 | ||
|
|
014126b57d | ||
|
|
d7b150a04f | ||
|
|
5751f9b29b | ||
|
|
1a29bd1e63 | ||
|
|
e54b6a780d | ||
|
|
c1a0b97c54 | ||
|
|
b8aaf63b20 | ||
|
|
d43b60ad83 | ||
|
|
cb5d3ab4e1 | ||
|
|
eba1cfb94d | ||
|
|
f5030e6a3c | ||
|
|
3adcf608c3 | ||
|
|
9682ab59c9 | ||
|
|
51adf8869c | ||
|
|
5183baed44 | ||
|
|
e5c6cb635d | ||
|
|
1ba4fe99a7 | ||
|
|
c44d6f6aeb | ||
|
|
07427b391e | ||
|
|
2210bd4e2d | ||
|
|
f4ac08d09f | ||
|
|
090580badf | ||
|
|
0eacda7494 | ||
|
|
14df9c01fa | ||
|
|
a69fc07dcf | ||
|
|
cea97226d5 | ||
|
|
19a7a4c5c1 | ||
|
|
98d4ab3e9d | ||
|
|
1700db48b4 | ||
|
|
ba3429f497 | ||
|
|
3b98d6c44f | ||
|
|
3183ec58ab | ||
|
|
46a72bda8e | ||
|
|
156400ffc2 | ||
|
|
116fbd93d0 | ||
|
|
30affaf451 | ||
|
|
d66020e3a9 | ||
|
|
4749d1a108 | ||
|
|
36d13734f6 | ||
|
|
3fc5f572bb | ||
|
|
d65319a9fc | ||
|
|
1d8b066a64 | ||
|
|
e6033322c6 | ||
|
|
d988876bca | ||
|
|
7e92482ced | ||
|
|
fa753c3694 | ||
|
|
58403cf4a5 | ||
|
|
13241d1880 | ||
|
|
91f016fd0c | ||
|
|
5e1ae2155f | ||
|
|
dd2a227529 | ||
|
|
9521183eb3 | ||
|
|
56bb20f4e1 | ||
|
|
604fa7281b | ||
|
|
2c9a82e2d3 | ||
|
|
4f7e296885 | ||
|
|
c917708184 | ||
|
|
110e93f4ed | ||
|
|
a0d6d452a0 | ||
|
|
7fb3f7a1aa | ||
|
|
7e906074ec | ||
|
|
de35e086d3 | ||
|
|
295b35b23a | ||
|
|
a5b6dad8f3 | ||
|
|
d024992144 | ||
|
|
3df604e8b6 | ||
|
|
080f586c19 | ||
|
|
0e62afd348 | ||
|
|
648d3c439b | ||
|
|
1dd3e90363 | ||
|
|
c78c0d1657 | ||
|
|
838d05eef7 | ||
|
|
3c3e8dd986 | ||
|
|
2d79ff9606 | ||
|
|
70f4207e02 | ||
|
|
242754f811 | ||
|
|
521544f6ba | ||
|
|
efc0681e01 | ||
|
|
4c3fa7d826 | ||
|
|
ac87678708 | ||
|
|
a6e5edabd2 | ||
|
|
24e5b1d84b | ||
|
|
ade7db9004 | ||
|
|
819b171d90 | ||
|
|
882716e911 | ||
|
|
5644036d25 | ||
|
|
de74c9251f | ||
|
|
1552b1808f | ||
|
|
fd349e2b37 | ||
|
|
0cf1cabcc2 | ||
|
|
bcbe765b9d | ||
|
|
eca3effb3b | ||
|
|
f1380a276e | ||
|
|
8ffeab1646 | ||
|
|
2eb175c356 | ||
|
|
4e606fc7de | ||
|
|
c5116dea1a | ||
|
|
924f9c2151 | ||
|
|
e0fa53e4df | ||
|
|
eeb7d48a6f | ||
|
|
df291710d8 | ||
|
|
16577877d3 | ||
|
|
309d459a70 | ||
|
|
e1430f7bc7 | ||
|
|
bf70beb88a | ||
|
|
a951622f6a | ||
|
|
d7db0d68dc | ||
|
|
2b9224cc3f | ||
|
|
0a750cd3bc | ||
|
|
0e8a32612f | ||
|
|
3c6882203b | ||
|
|
0464a8b0c7 | ||
|
|
599eda96aa | ||
|
|
421d735052 | ||
|
|
73bc64f9da | ||
|
|
5d807d65e5 | ||
|
|
88d86a6e60 | ||
|
|
b2cdbaae60 | ||
|
|
9160431556 | ||
|
|
2f9a400cf3 | ||
|
|
c39073dd9e | ||
|
|
f03692b840 | ||
|
|
617e8fdd55 | ||
|
|
d5252bd3b3 | ||
|
|
94f46c3ce6 | ||
|
|
c3e709231d | ||
|
|
7878e01e3f | ||
|
|
4631844c9f | ||
|
|
0c440d240c | ||
|
|
5c7be85977 | ||
|
|
c401926c0b | ||
|
|
e0e8be8d46 | ||
|
|
957d3f7229 | ||
|
|
7e47b9b6ba | ||
|
|
6e91e00289 | ||
|
|
a539f38e72 | ||
|
|
4f21d8f983 | ||
|
|
38a248193e | ||
|
|
934f2d347c |
No files matched your search
@@ -246,6 +246,11 @@ set(SRB2_CONFIG_ASAN OFF CACHE BOOL
|
||||
"Compile with AddressSanitizer (libasan).")
|
||||
set(SRB2_CONFIG_UBSAN OFF CACHE BOOL
|
||||
"Compile with UndefinedBehaviorSanitizer (libubsan).")
|
||||
set(SRB2_CONFIG_TSAN OFF CACHE BOOL
|
||||
"Compile with ThreadSanitizer (libtsan).")
|
||||
|
||||
set(SRB2_CONFIG_MUMBLE ON CACHE BOOL
|
||||
"Enable Mumble support")
|
||||
|
||||
set(SRB2_CONFIG_SATURNPAK ON CACHE BOOL
|
||||
"Enable Saturn specific special packet. Required for using the newer resynch system")
|
||||
@@ -254,6 +259,9 @@ set(SRB2_CONFIG_SATURNJOIN ON CACHE BOOL
|
||||
set(SRB2_CONFIG_SCREENFBO ON CACHE BOOL
|
||||
"Enable hardware renderer (OpenGL) FBO downsampling support")
|
||||
|
||||
set(SRB2_CONFIG_PHOBOS OFF CACHE BOOL
|
||||
" Compile the Phobos client. Which contains things not compatible with vanilla, such as raised skinlimits, 32 player support, bugfixes, etc.")
|
||||
|
||||
if(${SRB2_CONFIG_DEDICATED})
|
||||
set(SRB2_CONFIG_HAVE_GME NO)
|
||||
set(SRB2_CONFIG_HAVE_OPENMPT NO)
|
||||
@@ -275,6 +283,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
||||
lua_hooklib.c
|
||||
lua_hudlib.c
|
||||
lua_hudlib_drawlist.c
|
||||
lua_profile.cpp
|
||||
lua_infolib.c
|
||||
lua_maplib.c
|
||||
lua_mathlib.c
|
||||
@@ -290,6 +299,7 @@ if(${SRB2_CONFIG_HAVE_BLUA})
|
||||
lua_hook.h
|
||||
lua_hud.h
|
||||
lua_hudlib_drawlist.h
|
||||
lua_profile.h
|
||||
lua_libs.h
|
||||
lua_script.h
|
||||
lua_udatalib.h
|
||||
@@ -578,6 +588,10 @@ if(${SRB2_CONFIG_SATURNJOIN})
|
||||
add_definitions(-DDOSATURNJOIN)
|
||||
endif()
|
||||
|
||||
if(${SRB2_CONFIG_PHOBOS})
|
||||
add_definitions(-DPHOBOS_BUILD)
|
||||
endif()
|
||||
|
||||
# Targets
|
||||
|
||||
# Compatibility flag with later versions of GCC
|
||||
|
||||
+22
-9
@@ -65,12 +65,17 @@
|
||||
# DEBUGMODE=1 - Enable various debugging capabilities.
|
||||
# Also disables optimizations.
|
||||
#
|
||||
# PHOBOS_BUILD=1 - Compile the Phobos client.
|
||||
# Contains things not compatible with vanilla.
|
||||
# such as raised skinlimits, 32 player support, bugfixes, etc.
|
||||
#
|
||||
# Development flags:
|
||||
#
|
||||
# VALGRIND=1 - Enable Valgrind memory debugging support.
|
||||
# PROFILEMODE=1 - Enable performance profiling (gprof).
|
||||
# USEASAN=1 - Enable building with Address Sanitizer.
|
||||
# USEUBSAN=1 - Enable building with Undefined Behavior Sanitizer.
|
||||
# USETSAN=1 - Enable building with Thread Sanitizer.
|
||||
# NOLIBBACKTRACE=1 - Disable using Libbacktrace for crashlog traces.
|
||||
#
|
||||
# General flags for building:
|
||||
@@ -246,10 +251,6 @@ ifdef STATIC
|
||||
libs+=-static
|
||||
endif
|
||||
|
||||
ifneq (,$(filter $(CC) $(CXX),gcc g++))
|
||||
opts+=-mno-ms-bitfields
|
||||
endif
|
||||
|
||||
# build with profiling information
|
||||
ifdef PROFILEMODE
|
||||
opts+=-pg
|
||||
@@ -261,23 +262,35 @@ debug_opts=-D_DEBUG
|
||||
else # build a normal optimized version
|
||||
debug_opts=-DNDEBUG
|
||||
opts+=-O3
|
||||
ifndef NOLTO
|
||||
# compile with LTO
|
||||
opts+=-flto=auto
|
||||
libs+=-flto=auto
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USEASAN
|
||||
# compile with asan
|
||||
opts+=-O1 -fsanitize=address -fno-omit-frame-pointer -fno-common
|
||||
libs+=-fsanitize=address
|
||||
NOLTO=1
|
||||
endif
|
||||
|
||||
ifdef USEUBSAN
|
||||
# compile with ubsan
|
||||
opts+=-O1 -fsanitize=undefined -fno-omit-frame-pointer
|
||||
libs+=-fsanitize=undefined
|
||||
NOLTO=1
|
||||
endif
|
||||
|
||||
ifdef USETSAN
|
||||
# compile with tsan
|
||||
opts+=-O1 -fsanitize=thread -fno-omit-frame-pointer
|
||||
libs+=-fsanitize=thread
|
||||
NOLTO=1
|
||||
endif
|
||||
|
||||
ifndef DEBUGMODE
|
||||
ifndef NOLTO
|
||||
# compile with LTO
|
||||
opts+=-flto=auto
|
||||
libs+=-flto=auto
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USEJEMALLOC
|
||||
|
||||
@@ -9,6 +9,7 @@ passthru_opts+=\
|
||||
HAVE_DISCORDRPC DEVELOP\
|
||||
NOHOLEPUNCH\
|
||||
HAVE_IPV6\
|
||||
PHOBOS_BUILD\
|
||||
|
||||
# build with debugging information
|
||||
ifdef DEBUGMODE
|
||||
@@ -86,7 +87,7 @@ ifdef VALGRIND
|
||||
VALGRIND_PKGCONFIG?=valgrind
|
||||
VALGRIND_LDFLAGS=
|
||||
$(eval $(call Use_pkg_config,VALGRIND))
|
||||
ZDEBUG=1
|
||||
#ZDEBUG=1 we enable this by default
|
||||
opts+=-DHAVE_VALGRIND
|
||||
endif
|
||||
|
||||
|
||||
@@ -99,3 +99,4 @@ lua_skinlib.c
|
||||
lua_thinkerlib.c
|
||||
lua_udatalib.c
|
||||
lua_glib.c
|
||||
lua_profile.cpp
|
||||
+2
-2
@@ -55,8 +55,8 @@ struct lua_longjmp {
|
||||
|
||||
void luaD_seterrorobj (lua_State *L, int lerrcode, StkId oldtop) {
|
||||
switch (lerrcode) {
|
||||
case LUA_ERRMEM: {
|
||||
setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
|
||||
case LUA_ERRMEM: { /* memory error? */
|
||||
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
|
||||
break;
|
||||
}
|
||||
case LUA_ERRERR: {
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "llimits.h"
|
||||
#include "lua.h"
|
||||
|
||||
#define MEMERRMSG "not enough memory"
|
||||
|
||||
|
||||
#define luaM_reallocv(L,b,on,n,e) \
|
||||
((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
||||
}
|
||||
case 'p': {
|
||||
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
|
||||
sprintf(buff, "%p", va_arg(argp, void *));
|
||||
snprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
|
||||
pushstr(L, buff);
|
||||
break;
|
||||
}
|
||||
|
||||
+6
-1
@@ -64,6 +64,9 @@ static void freestack (lua_State *L, lua_State *L1) {
|
||||
}
|
||||
|
||||
|
||||
#define MEMERRMSG "not enough memory"
|
||||
|
||||
|
||||
/*
|
||||
** open parts that may cause memory-allocation errors
|
||||
*/
|
||||
@@ -76,7 +79,9 @@ static void f_luaopen (lua_State *L, void *ud) {
|
||||
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
|
||||
luaT_init(L);
|
||||
luaX_init(L);
|
||||
luaS_fix(luaS_newliteral(L, MEMERRMSG));
|
||||
/* pre-create memory-error message */
|
||||
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
|
||||
luaS_fix(g->memerrmsg); /* it should never be collected */
|
||||
g->GCthreshold = 4*g->totalbytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ typedef struct global_State {
|
||||
lua_CFunction panic; /* to be called in unprotected errors */
|
||||
TValue l_registry;
|
||||
struct lua_State *mainthread;
|
||||
TString *memerrmsg; /* memory-error message */
|
||||
UpVal uvhead; /* head of double-linked list of all open upvalues */
|
||||
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
|
||||
TString *tmname[TM_N]; /* array with tag-method names */
|
||||
|
||||
+6
-6
@@ -776,23 +776,23 @@ static int str_format (lua_State *L) {
|
||||
strfrmt = scanformat(L, strfrmt, form);
|
||||
switch (*strfrmt++) {
|
||||
case 'c': {
|
||||
sprintf(buff, form, (int)luaL_checknumber(L, arg));
|
||||
snprintf(buff, sizeof(buff), form, (int)luaL_checknumber(L, arg));
|
||||
break;
|
||||
}
|
||||
case 'd': case 'i': {
|
||||
addintlen(form);
|
||||
sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
|
||||
snprintf(buff, sizeof(buff), form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
|
||||
break;
|
||||
}
|
||||
case 'o': case 'u': case 'x': case 'X': {
|
||||
addintlen(form);
|
||||
sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
|
||||
snprintf(buff, sizeof(buff), form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
|
||||
break;
|
||||
}
|
||||
case 'e': case 'E': case 'f':
|
||||
case 'g': case 'G': {
|
||||
lua_Number n = luaL_checknumber(L, arg);
|
||||
sprintf(buff, form, (double)n);
|
||||
lua_Number n = luaL_checknumber(L, arg);
|
||||
snprintf(buff, sizeof(buff), form, (double)n);
|
||||
break;
|
||||
}
|
||||
case 'q': {
|
||||
@@ -810,7 +810,7 @@ static int str_format (lua_State *L) {
|
||||
continue; /* skip the `addsize' at the end */
|
||||
}
|
||||
else {
|
||||
sprintf(buff, form, s);
|
||||
snprintf(buff, sizeof(buff), form, s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -536,7 +536,7 @@
|
||||
#define LUA_NUMBER_SCAN "%d"
|
||||
#define LUA_NUMBER_FMT "%d"
|
||||
#endif
|
||||
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
|
||||
#define lua_number2str(s,n) snprintf((s), LUAI_MAXNUMBER2STR, LUA_NUMBER_FMT, (n))
|
||||
#define LUAI_MAXNUMBER2STR 12 /* 10 digits, sign, and \0 */
|
||||
#define lua_str2number(s,p) ({ \
|
||||
long nmr = strtol((s), (p), 10); \
|
||||
|
||||
@@ -206,6 +206,15 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
|
||||
p += n; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
#define WRITESKIN(p,b) WRITEUINT16(p,b)
|
||||
#define READSKIN(p) READUINT16(p)
|
||||
#else
|
||||
#define WRITESKIN(p,b) WRITEUINT8(p,b)
|
||||
#define READSKIN(p) READUINT8(p)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
+43
-15
@@ -113,18 +113,29 @@ static vsbuf_t com_text; // variable sized buffer
|
||||
* \param ptext The text to add.
|
||||
* \sa COM_BufInsertText
|
||||
*/
|
||||
void COM_BufAddText(const char *ptext)
|
||||
void COM_BufAddTextEx(const char *ptext, size_t plen)
|
||||
{
|
||||
size_t l;
|
||||
char *text;
|
||||
|
||||
l = strlen(ptext);
|
||||
if (plen == 0)
|
||||
plen = strlen(ptext);
|
||||
|
||||
text = Z_Malloc(sizeof(char) * (plen+1), PU_STATIC, NULL);
|
||||
memcpy(text, ptext, plen);
|
||||
text[plen] = '\0';
|
||||
|
||||
l = strlen(text);
|
||||
|
||||
if (com_text.cursize + l >= com_text.maxsize)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n"));
|
||||
return;
|
||||
}
|
||||
VS_Write(&com_text, ptext, l);
|
||||
|
||||
VS_Write(&com_text, text, l);
|
||||
|
||||
Z_Free(text);
|
||||
}
|
||||
|
||||
/** Adds command text and executes it immediately.
|
||||
@@ -132,8 +143,10 @@ void COM_BufAddText(const char *ptext)
|
||||
* \param ptext The text to execute. A newline is automatically added.
|
||||
* \sa COM_BufAddText
|
||||
*/
|
||||
void COM_BufInsertText(const char *ptext)
|
||||
void COM_BufInsertTextEx(const char *ptext, size_t plen)
|
||||
{
|
||||
const INT32 old_wait = com_wait;
|
||||
|
||||
char *temp = NULL;
|
||||
size_t templen;
|
||||
|
||||
@@ -145,10 +158,14 @@ void COM_BufInsertText(const char *ptext)
|
||||
VS_Clear(&com_text);
|
||||
}
|
||||
|
||||
com_wait = 0;
|
||||
|
||||
// add the entire text of the file (or alias)
|
||||
COM_BufAddText(ptext);
|
||||
COM_BufAddTextEx(ptext, plen);
|
||||
COM_BufExecute(); // do it right away
|
||||
|
||||
com_wait += old_wait;
|
||||
|
||||
// add the copied off data
|
||||
if (templen)
|
||||
{
|
||||
@@ -159,8 +176,7 @@ void COM_BufInsertText(const char *ptext)
|
||||
|
||||
/** Progress the wait timer and flush waiting console commands when ready.
|
||||
*/
|
||||
void
|
||||
COM_BufTicker(void)
|
||||
void COM_BufTicker(void)
|
||||
{
|
||||
if (com_wait)
|
||||
{
|
||||
@@ -1596,7 +1612,9 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
|
||||
// send only changed cvars ...
|
||||
// the client will reset all netvars to default before loading
|
||||
WRITEUINT16(*p, 0x0000);
|
||||
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
{
|
||||
if (((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar)) || (isdemorecording && cvar->netid == cv_numlaps.netid))
|
||||
{
|
||||
WRITEUINT16(*p, cvar->netid);
|
||||
@@ -1614,7 +1632,7 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
|
||||
else
|
||||
{
|
||||
char buf[9];
|
||||
sprintf(buf, "%d", mapheaderinfo[gamemap - 1]->numlaps);
|
||||
snprintf(buf, sizeof(buf), "%d", mapheaderinfo[gamemap - 1]->numlaps);
|
||||
WRITESTRING(*p, buf);
|
||||
}
|
||||
}
|
||||
@@ -1626,6 +1644,8 @@ void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
|
||||
WRITEUINT8(*p, false);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
WRITEUINT16(count_p, count);
|
||||
}
|
||||
|
||||
@@ -1719,6 +1739,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
||||
// send the value of the variable
|
||||
UINT8 buf[128];
|
||||
UINT8 *p = buf;
|
||||
|
||||
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, "Only the server or admin can change: %s %s\n", var->name, var->string);
|
||||
@@ -1782,8 +1803,7 @@ void CV_StealthSet(consvar_t *var, const char *value)
|
||||
void CV_StealthSetValue(consvar_t *var, INT32 value)
|
||||
{
|
||||
char val[32];
|
||||
|
||||
sprintf(val, "%d", value);
|
||||
snprintf(val, sizeof(val), "%d", value);
|
||||
CV_SetCVar(var, val, true);
|
||||
}
|
||||
|
||||
@@ -1803,8 +1823,7 @@ void CV_Set(consvar_t *var, const char *value)
|
||||
void CV_SetValue(consvar_t *var, INT32 value)
|
||||
{
|
||||
char val[32];
|
||||
|
||||
sprintf(val, "%d", value);
|
||||
snprintf(val, sizeof(val), "%d", value);
|
||||
CV_SetCVar(var, val, false);
|
||||
}
|
||||
|
||||
@@ -2202,6 +2221,7 @@ void CV_SaveVariables(FILE *f)
|
||||
consvar_t *cvar;
|
||||
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
{
|
||||
if (cvar->flags & CV_SAVE)
|
||||
{
|
||||
char stringtowrite[MAXTEXTCMD+1];
|
||||
@@ -2210,15 +2230,23 @@ void CV_SaveVariables(FILE *f)
|
||||
if (fastcmp(cvar->string, "MAX") || fastcmp(cvar->string, "MIN"))
|
||||
{
|
||||
if (cvar->flags & CV_FLOAT)
|
||||
sprintf(stringtowrite, "%f", FixedToFloat(cvar->value));
|
||||
{
|
||||
snprintf(stringtowrite, sizeof(stringtowrite), "%f", FixedToFloat(cvar->value));
|
||||
}
|
||||
else
|
||||
sprintf(stringtowrite, "%d", cvar->value);
|
||||
{
|
||||
snprintf(stringtowrite, sizeof(stringtowrite), "%d", cvar->value);
|
||||
}
|
||||
}
|
||||
else
|
||||
strcpy(stringtowrite, cvar->string);
|
||||
{
|
||||
strncpy(stringtowrite, cvar->string, sizeof(stringtowrite)-1);
|
||||
stringtowrite[sizeof(stringtowrite)-1] = '\0';
|
||||
}
|
||||
|
||||
fprintf(f, "%s \"%s\"\n", cvar->name, stringtowrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
+4
-2
@@ -52,10 +52,12 @@ size_t COM_FirstOption(void);
|
||||
const char *COM_CompleteCommand(const char *partial, INT32 skips);
|
||||
|
||||
// insert at queu (at end of other command)
|
||||
void COM_BufAddText(const char *btext);
|
||||
#define COM_BufAddText(s) COM_BufAddTextEx(s, 0)
|
||||
void COM_BufAddTextEx(const char *ptext, size_t plen);
|
||||
|
||||
// insert in head (before other command)
|
||||
void COM_BufInsertText(const char *btext);
|
||||
#define COM_BufInsertText(s) COM_BufInsertTextEx(s, 0)
|
||||
void COM_BufInsertTextEx(const char *ptext, size_t plen);
|
||||
|
||||
// don't bother inserting, just do immediately
|
||||
void COM_ImmedExecute(const char *ptext);
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
// BLANKART
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2024 by Kart Krew
|
||||
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2024 by Kart Krew
|
||||
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2024 by Kart Krew
|
||||
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// BLANKART
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2024 by Kart Krew
|
||||
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2024 by Kart Krew
|
||||
// Copyright (C) 2025 by Ronald "Eidolon" Kinard
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
||||
+117
-75
@@ -1125,7 +1125,7 @@ static cl_mode_t cl_mode = CL_SEARCHING;
|
||||
static UINT16 cl_lastcheckedfilecount = 0; // used for full file list
|
||||
|
||||
// Player name send/load
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
static void CV_SavePlayerNames(UINT8 **p)
|
||||
{
|
||||
INT32 i = 0;
|
||||
@@ -1161,6 +1161,7 @@ static void CV_LoadPlayerNames(UINT8 **p)
|
||||
memcpy(player_names[i], tmp_name, MAXPLAYERNAME+1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void CL_DrawAddonTypes(void)
|
||||
{
|
||||
@@ -1629,8 +1630,8 @@ static boolean CL_SendJoin(void)
|
||||
netbuffer->u.clientcfg.packetversion = PACKETVERSION;
|
||||
netbuffer->u.clientcfg.version = VERSION;
|
||||
netbuffer->u.clientcfg.subversion = SUBVERSION;
|
||||
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
|
||||
sizeof(netbuffer->u.clientcfg.application));
|
||||
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, sizeof(netbuffer->u.clientcfg.application)-1);
|
||||
netbuffer->u.clientcfg.application[sizeof(netbuffer->u.clientcfg.application)-1] = '\0';
|
||||
#ifdef SATURNJOIN
|
||||
netbuffer->u.clientcfg.issaturn = ISSATURN;
|
||||
#endif
|
||||
@@ -1655,88 +1656,91 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
serverinfo_pak *serverinfo = &netbuffer->u.serverinfo;
|
||||
|
||||
netbuffer->packettype = PT_SERVERINFO;
|
||||
netbuffer->u.serverinfo._255 = 255;
|
||||
netbuffer->u.serverinfo.packetversion = PACKETVERSION;
|
||||
netbuffer->u.serverinfo.version = VERSION;
|
||||
netbuffer->u.serverinfo.subversion = SUBVERSION;
|
||||
strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION,
|
||||
sizeof netbuffer->u.serverinfo.application);
|
||||
serverinfo->_255 = 255;
|
||||
serverinfo->packetversion = PACKETVERSION;
|
||||
serverinfo->version = VERSION;
|
||||
serverinfo->subversion = SUBVERSION;
|
||||
strncpy(serverinfo->application, SRB2APPLICATION, sizeof(serverinfo->application)-1);
|
||||
serverinfo->application[sizeof(serverinfo->application)-1] = '\0';
|
||||
// return back the time value so client can compute their ping
|
||||
netbuffer->u.serverinfo.time = (tic_t)LONG(servertime);
|
||||
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
|
||||
serverinfo->time = (tic_t)LONG(servertime);
|
||||
serverinfo->leveltime = (tic_t)LONG(leveltime);
|
||||
|
||||
// force 1 player
|
||||
if (UseFakeSeed())
|
||||
netbuffer->u.serverinfo.numberofplayer = (UINT8)1;
|
||||
serverinfo->numberofplayer = (UINT8)1;
|
||||
else
|
||||
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
|
||||
serverinfo->numberofplayer = (UINT8)D_NumPlayers();
|
||||
|
||||
netbuffer->u.serverinfo.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
|
||||
serverinfo->maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
|
||||
|
||||
// SRB2Kart: Vanilla's gametype constants for MS support
|
||||
netbuffer->u.serverinfo.gametype = (UINT8)((gt == GT_MATCH) ? VANILLA_GT_MATCH : VANILLA_GT_RACE);
|
||||
serverinfo->gametype = (UINT8)((gt == GT_MATCH) ? VANILLA_GT_MATCH : VANILLA_GT_RACE);
|
||||
|
||||
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
|
||||
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
||||
serverinfo->modifiedgame = (UINT8)modifiedgame;
|
||||
serverinfo->cheatsenabled = CV_CheatsEnabled();
|
||||
|
||||
netbuffer->u.serverinfo.kartvars = (UINT8) (
|
||||
serverinfo->kartvars = (UINT8) (
|
||||
(cv_kartspeed.value & SV_SPEEDMASK) |
|
||||
(dedicated ? SV_DEDICATED : 0)
|
||||
);
|
||||
|
||||
CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string,
|
||||
MAXSERVERNAME);
|
||||
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), sizeof(netbuffer->u.serverinfo.mapname)-1);
|
||||
CopyCaretColors(serverinfo->servername, cv_servername.string, MAXSERVERNAME);
|
||||
|
||||
memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, sizeof(netbuffer->u.serverinfo.mapmd5));
|
||||
strncpy(serverinfo->mapname, G_BuildMapName(gamemap), sizeof(serverinfo->mapname)-1);
|
||||
serverinfo->mapname[sizeof(serverinfo->mapname)-1] = '\0';
|
||||
|
||||
netbuffer->u.serverinfo.iszone = 0;
|
||||
memcpy(serverinfo->mapmd5, mapmd5, sizeof(serverinfo->mapmd5));
|
||||
|
||||
memset(netbuffer->u.serverinfo.maptitle, 0, sizeof(netbuffer->u.serverinfo.maptitle));
|
||||
memset(netbuffer->u.serverinfo.httpsource, 0, MAX_MIRROR_LENGTH);
|
||||
serverinfo->iszone = 0;
|
||||
|
||||
memset(serverinfo->maptitle, 0, sizeof(serverinfo->maptitle));
|
||||
memset(serverinfo->httpsource, 0, MAX_MIRROR_LENGTH);
|
||||
|
||||
if (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) && mapheaderinfo[gamemap-1]->lvlttl[0])
|
||||
{
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->lvlttl, sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
strncpy(serverinfo->maptitle, mapheaderinfo[gamemap-1]->lvlttl, sizeof(serverinfo->maptitle)-1);
|
||||
|
||||
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
|
||||
{
|
||||
if (mapheaderinfo[gamemap-1]->zonttl[0])
|
||||
{
|
||||
strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->zonttl,
|
||||
sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
strncat(serverinfo->maptitle, " ", sizeof(serverinfo->maptitle)-1);
|
||||
strncat(serverinfo->maptitle, mapheaderinfo[gamemap-1]->zonttl, sizeof(serverinfo->maptitle)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
netbuffer->u.serverinfo.iszone = 1; // ms and clients will append this themselves
|
||||
serverinfo->iszone = 1; // ms and clients will append this themselves
|
||||
}
|
||||
}
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->actnum[0])
|
||||
{
|
||||
strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->actnum,
|
||||
sizeof(netbuffer->u.serverinfo.maptitle)-1);
|
||||
strncat(serverinfo->maptitle, " ", sizeof(serverinfo->maptitle)-1);
|
||||
strncat(serverinfo->maptitle, mapheaderinfo[gamemap-1]->actnum, sizeof(serverinfo->maptitle)-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33);
|
||||
{
|
||||
strncpy(serverinfo->maptitle, "Unknown", sizeof(serverinfo->maptitle)-1);
|
||||
}
|
||||
|
||||
netbuffer->u.serverinfo.maptitle[32] = '\0';
|
||||
serverinfo->maptitle[sizeof(serverinfo->maptitle)-1] = '\0';
|
||||
|
||||
netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum
|
||||
serverinfo->actnum = 0; //mapheaderinfo[gamemap-1]->actnum
|
||||
|
||||
mirror_length = strlen(httpurl);
|
||||
if (mirror_length > MAX_MIRROR_LENGTH)
|
||||
mirror_length = MAX_MIRROR_LENGTH;
|
||||
|
||||
if (snprintf(netbuffer->u.serverinfo.httpsource, mirror_length+1, "%s", httpurl) < 0)
|
||||
if (snprintf(serverinfo->httpsource, mirror_length+1, "%s", httpurl) < 0)
|
||||
// If there's an encoding error, send nothing, we accept that the above may be truncated
|
||||
strncpy(netbuffer->u.serverinfo.httpsource, "", mirror_length);
|
||||
strncpy(serverinfo->httpsource, "", mirror_length);
|
||||
|
||||
netbuffer->u.serverinfo.httpsource[MAX_MIRROR_LENGTH-1] = '\0';
|
||||
serverinfo->httpsource[MAX_MIRROR_LENGTH-1] = '\0';
|
||||
|
||||
p = PutFileNeeded(0);
|
||||
|
||||
@@ -1769,7 +1773,7 @@ static void SV_SendPlayerInfo(INT32 node)
|
||||
// doesent really matter what we put here lel
|
||||
netbuffer->u.playerinfo[0].score = LONG(42069);
|
||||
netbuffer->u.playerinfo[0].timeinserver = SHORT(42069);
|
||||
netbuffer->u.playerinfo[0].skin = (UINT8)1; // no clue wtf skin 1 is, tails maybe?
|
||||
netbuffer->u.playerinfo[0].skin = (skinnum_t)1; // no clue wtf skin 1 is, tails maybe?
|
||||
|
||||
netbuffer->u.playerinfo[0].data = 0;
|
||||
|
||||
@@ -1814,11 +1818,11 @@ static void SV_SendPlayerInfo(INT32 node)
|
||||
|
||||
netbuffer->u.playerinfo[i].score = LONG(players[i].score);
|
||||
netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE));
|
||||
netbuffer->u.playerinfo[i].skin = (UINT8)players[i].skin;
|
||||
netbuffer->u.playerinfo[i].skin = (skinnum_t)players[i].skin;
|
||||
|
||||
// Extra data
|
||||
// Kart has extra skincolors, so we can't use this
|
||||
//netbuffer->u.playerinfo[i].data = 0; //netbuffer->u.playerinfo[i].data = players[i].skincolor;
|
||||
//netbuffer->u.playerinfo[i].data = 0;
|
||||
|
||||
// well why not, we only got like 100 of these?
|
||||
netbuffer->u.playerinfo[i].data = players[i].skincolor;
|
||||
@@ -1924,8 +1928,10 @@ static void SV_SendMapIcon(INT32 node)
|
||||
*/
|
||||
static boolean SV_SendServerConfig(INT32 node)
|
||||
{
|
||||
#ifndef PHOBOS_BUILD
|
||||
INT32 i;
|
||||
UINT8 *p, *op;
|
||||
#endif
|
||||
boolean waspacketsent;
|
||||
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
@@ -1943,6 +1949,7 @@ static boolean SV_SendServerConfig(INT32 node)
|
||||
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
||||
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
// we fill these structs with FFs so that any players not in game get sent as 0xFFFF
|
||||
// which is nice and easy for us to detect
|
||||
memset(netbuffer->u.servercfg.playerskins, 0xFF, sizeof(netbuffer->u.servercfg.playerskins));
|
||||
@@ -1958,6 +1965,7 @@ static boolean SV_SendServerConfig(INT32 node)
|
||||
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
|
||||
netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor;
|
||||
}
|
||||
#endif
|
||||
|
||||
netbuffer->u.servercfg.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value));
|
||||
netbuffer->u.servercfg.allownewplayer = cv_allownewplayer.value;
|
||||
@@ -1965,12 +1973,16 @@ static boolean SV_SendServerConfig(INT32 node)
|
||||
|
||||
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
const size_t len = sizeof(serverconfig_pak);
|
||||
#else
|
||||
op = p = netbuffer->u.servercfg.varlengthinputs;
|
||||
|
||||
CV_SavePlayerNames(&p);
|
||||
CV_SaveNetVars(&p, false);
|
||||
|
||||
const size_t len = sizeof (serverconfig_pak) + (size_t)(p - op);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (debugfile)
|
||||
@@ -2094,7 +2106,7 @@ static void SV_SavedGame(void)
|
||||
if (!cv_dumpconsistency.value)
|
||||
return;
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
// first save it in a malloced buffer
|
||||
save.p = save.buffer = (UINT8 *)Z_Malloc(SAVEGAMESIZE, PU_STATIC, NULL);
|
||||
@@ -2132,7 +2144,7 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
||||
size_t length, decompressedlen;
|
||||
char tmpsave[264];
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
length = FIL_ReadFile(tmpsave, &save.buffer);
|
||||
|
||||
@@ -2211,7 +2223,7 @@ static void CL_ReloadReceivedSavegame(void)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
LUA_InvalidatePlayer(&players[i]);
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
snprintf(player_names[i], MAXPLAYERNAME+1, "Player %d", i + 1);
|
||||
}
|
||||
|
||||
CL_LoadReceivedSavegame(true);
|
||||
@@ -2947,7 +2959,7 @@ static void CL_ConnectToServer(void)
|
||||
tic_t asksent;
|
||||
char tmpsave[264];
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
filedownload.current = -1;
|
||||
cl_mode = CL_SEARCHING;
|
||||
@@ -3335,6 +3347,7 @@ static void Command_connect(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// StarManiaKG: allow us to join servers from anywhere at any time //
|
||||
if (Playing() || demo.title || demo.playback)
|
||||
{
|
||||
if (demo.title || demo.playback)
|
||||
@@ -3353,7 +3366,9 @@ static void Command_connect(void)
|
||||
D_StartTitle();
|
||||
}
|
||||
else
|
||||
{
|
||||
M_ClearMenus(true); // close the menus
|
||||
}
|
||||
|
||||
// modified game check: no longer handled
|
||||
// we don't request a restart unless the filelist differs
|
||||
@@ -3369,37 +3384,52 @@ static void Command_connect(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
// used in menu to connect to a server in the list
|
||||
if (netgame && fasticmp(COM_Argv(1), "node"))
|
||||
// Get the server node.
|
||||
if (netgame)
|
||||
{
|
||||
servernode = (SINT8)atoi(COM_Argv(2));
|
||||
}
|
||||
else if (netgame)
|
||||
{
|
||||
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
|
||||
return;
|
||||
}
|
||||
else if (I_NetOpenSocket)
|
||||
{
|
||||
I_NetOpenSocket();
|
||||
netgame = true;
|
||||
multiplayer = true;
|
||||
|
||||
if (fasticmp(COM_Argv(1), "any"))
|
||||
servernode = BROADCASTADDR;
|
||||
else if (I_NetMakeNodewPort && COM_Argc() >= 3)
|
||||
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
|
||||
else if (I_NetMakeNodewPort)
|
||||
servernode = I_NetMakeNode(COM_Argv(1));
|
||||
// used in menu to connect to a server in the list
|
||||
if (fasticmp(COM_Argv(1), "node"))
|
||||
{
|
||||
servernode = (SINT8)atoi(COM_Argv(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
|
||||
D_CloseConnection();
|
||||
return;
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
}
|
||||
}
|
||||
else
|
||||
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
|
||||
{
|
||||
// Standard behaviour
|
||||
if (I_NetOpenSocket)
|
||||
{
|
||||
I_NetOpenSocket();
|
||||
netgame = true;
|
||||
multiplayer = true;
|
||||
|
||||
if (fasticmp(COM_Argv(1), "any"))
|
||||
servernode = BROADCASTADDR;
|
||||
else if (I_NetMakeNodewPort)
|
||||
{
|
||||
if (COM_Argc() >= 3) // address AND port
|
||||
servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2));
|
||||
else // address only, or address:port
|
||||
servernode = I_NetMakeNode(COM_Argv(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n"));
|
||||
D_CloseConnection();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// invalid address
|
||||
if (servernode == -1)
|
||||
@@ -3446,6 +3476,7 @@ static void ResetNode(INT32 node);
|
||||
//
|
||||
void CL_ClearPlayer(INT32 playernum)
|
||||
{
|
||||
// Handle mobj_t pointers.
|
||||
if (players[playernum].mo)
|
||||
{
|
||||
// Don't leave a NiGHTS ghost!
|
||||
@@ -3454,6 +3485,7 @@ void CL_ClearPlayer(INT32 playernum)
|
||||
P_RemoveMobj(players[playernum].mo);
|
||||
}
|
||||
|
||||
// Wipe the struct.
|
||||
memset(&players[playernum], 0, sizeof(player_t));
|
||||
}
|
||||
|
||||
@@ -3510,7 +3542,7 @@ void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||
player_muted[playernum] = false;
|
||||
|
||||
// Reset the name
|
||||
sprintf(player_names[playernum], "Player %d", playernum+1);
|
||||
snprintf(player_names[playernum], MAXPLAYERNAME+1, "Player %d", playernum+1);
|
||||
|
||||
player_name_changes[playernum] = 0;
|
||||
|
||||
@@ -4472,7 +4504,7 @@ void SV_ResetServer(void)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
LUA_InvalidatePlayer(&players[i]);
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
snprintf(player_names[i], MAXPLAYERNAME+1, "Player %d", i + 1);
|
||||
}
|
||||
|
||||
memset(player_name_changes, 0, sizeof(player_name_changes));
|
||||
@@ -5162,7 +5194,7 @@ static void PT_ServerInfo(SINT8 node)
|
||||
const tic_t ticthen = (tic_t)LONG(netbuffer->u.serverinfo.time);
|
||||
const tic_t ticdiff = (ticnow - ticthen)*1000/NEWTICRATE;
|
||||
netbuffer->u.serverinfo.time = (tic_t)LONG(ticdiff);
|
||||
netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0;
|
||||
netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = '\0';
|
||||
netbuffer->u.serverinfo.application
|
||||
[sizeof netbuffer->u.serverinfo.application - 1] = '\0';
|
||||
memcpy(servername, netbuffer->u.serverinfo.servername, MAXSERVERNAME);
|
||||
@@ -5411,8 +5443,10 @@ static void PT_ServerRefuse(SINT8 node)
|
||||
// Positive response of client join request
|
||||
static void PT_ServerCFG(SINT8 node)
|
||||
{
|
||||
#ifndef PHOBOS_BUILD
|
||||
INT32 j;
|
||||
UINT8 *scp;
|
||||
#endif
|
||||
|
||||
if (server && serverrunning && node != servernode)
|
||||
{ // but wait I thought I'm the server?
|
||||
@@ -5435,8 +5469,10 @@ static void PT_ServerCFG(SINT8 node)
|
||||
if ((gametype = netbuffer->u.servercfg.gametype) >= NUMGAMETYPES)
|
||||
I_Error("Bad gametype %d in cliserv!", gametype);
|
||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||
#ifndef PHOBOS_BUILD
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];
|
||||
#endif
|
||||
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||
}
|
||||
|
||||
@@ -5462,6 +5498,7 @@ static void PT_ServerCFG(SINT8 node)
|
||||
SendSaturnInfo(node);
|
||||
#endif
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
memset(playeringame, 0, sizeof(playeringame));
|
||||
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
@@ -5478,6 +5515,7 @@ static void PT_ServerCFG(SINT8 node)
|
||||
scp = netbuffer->u.servercfg.varlengthinputs;
|
||||
CV_LoadPlayerNames(&scp);
|
||||
scp += CV_LoadNetVars(scp);
|
||||
#endif
|
||||
|
||||
/// \note Wait. What if a Lua script uses some global custom variables synched with the NetVars hook?
|
||||
/// Shouldn't them be downloaded even at intermission time?
|
||||
@@ -5531,7 +5569,7 @@ static void PT_WillResendGamestate(void)
|
||||
|
||||
CONS_Printf(M_GetText("Reloading game state...\n"));
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
snprintf(tmpsave, sizeof(tmpsave), "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
// Don't get a corrupt savegame error because tmpsave already exists
|
||||
if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1)
|
||||
@@ -6873,7 +6911,10 @@ boolean TryRunTics(tic_t realtics)
|
||||
DEBFILE(va("============ Running tic %d (local %d)\n", gametic, leveltime));
|
||||
|
||||
if (update_stats)
|
||||
{
|
||||
ps_prevtictime = ps_tictime;
|
||||
PS_START_TIMING(ps_tictime);
|
||||
}
|
||||
|
||||
G_Ticker((gametic % NEWTICRATERATIO) == 0);
|
||||
ExtraDataTicker();
|
||||
@@ -7232,6 +7273,7 @@ static void DedicatedIdleUpdate(INT32 *realtics)
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Player detected...)\n");
|
||||
}
|
||||
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -339,13 +339,17 @@ typedef struct
|
||||
UINT8 clientnode;
|
||||
UINT8 gamestate;
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
// 0xFF == not in game; else player skin num
|
||||
UINT8 playerskins[MAXPLAYERS];
|
||||
UINT8 playercolor[MAXPLAYERS];
|
||||
#endif
|
||||
|
||||
UINT8 gametype;
|
||||
UINT8 modifiedgame;
|
||||
#ifndef PHOBOS_BUILD
|
||||
SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed
|
||||
#endif
|
||||
|
||||
char server_context[8]; // Unique context id, generated at server startup.
|
||||
|
||||
@@ -354,7 +358,9 @@ typedef struct
|
||||
boolean allownewplayer;
|
||||
boolean discordinvites;
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
UINT8 varlengthinputs[0]; // Playernames and netvars
|
||||
#endif
|
||||
} ATTRPACK serverconfig_pak;
|
||||
|
||||
typedef struct {
|
||||
@@ -444,7 +450,7 @@ typedef struct
|
||||
char name[MAXPLAYERNAME+1];
|
||||
UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH
|
||||
UINT8 team;
|
||||
UINT8 skin;
|
||||
skinnum_t skin;
|
||||
UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused.
|
||||
UINT32 score;
|
||||
UINT16 timeinserver; // In seconds.
|
||||
@@ -454,7 +460,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
char name[MAXPLAYERNAME+1];
|
||||
UINT8 skin;
|
||||
skinnum_t skin;
|
||||
UINT8 color;
|
||||
UINT32 pflags;
|
||||
UINT32 score;
|
||||
|
||||
+15
-3
@@ -79,6 +79,7 @@
|
||||
#include "core/memory.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_profile.h"
|
||||
|
||||
/* Manually defined asset hashes for non-CMake builds
|
||||
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
|
||||
@@ -644,6 +645,11 @@ static boolean D_Display(void)
|
||||
|
||||
CON_Drawer(); // Ha, i LIED!
|
||||
|
||||
if (cv_lua_profile.value > 0)
|
||||
{
|
||||
LUA_RenderTimers();
|
||||
}
|
||||
|
||||
PS_START_TIMING(ps_swaptime);
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
PS_STOP_TIMING(ps_swaptime);
|
||||
@@ -1143,13 +1149,19 @@ static void D_FindAddonsToAutoload(void)
|
||||
// ok so theres still issues with players adding stuff to autoload by accident
|
||||
// sometimes this stuff contains maps
|
||||
// you can probably imagine how that goes in a netgame....
|
||||
if (W_CheckAutoLoadContainsMap(wadsToAutoload))
|
||||
int retmap = W_CheckAutoLoadContainsMap(wadsToAutoload);
|
||||
if (retmap == -1)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Autoload: file %s was not found or not valid.\n", wadsToAutoload);
|
||||
continue;
|
||||
}
|
||||
if (retmap > 0)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Autoload: file %s contains map data, this WILL cause crashes and desynchs! skipping...\n", wadsToAutoload);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!postload && W_CheckPostLoadList(wadsToAutoload))
|
||||
if (!postload && W_CheckPostLoadList(wadsToAutoload) > 0)
|
||||
{
|
||||
CONS_Printf("Autoload: forcing postload for file %s\n", wadsToAutoload);
|
||||
postload = true;
|
||||
@@ -1239,7 +1251,7 @@ static void IdentifyVersion(void)
|
||||
#endif
|
||||
|
||||
char tempsrb2path[256] = ".";
|
||||
if (getcwd(tempsrb2path, 256) == NULL)
|
||||
if (I_GetCwd(tempsrb2path, 256) == NULL)
|
||||
strcpy(tempsrb2path, ".");
|
||||
|
||||
// get the current directory (possible problem on NT with "." as current dir)
|
||||
|
||||
+3
-1
@@ -1315,7 +1315,9 @@ boolean D_CheckNetGame(void)
|
||||
while (!debugfile && k < MAXPLAYERS)
|
||||
{
|
||||
k++;
|
||||
sprintf(filename, "debug%d.txt", k);
|
||||
|
||||
snprintf(filename, sizeof(filename), "debug%d.txt", k);
|
||||
|
||||
debugfile = fopen(va("%s" PATHSEP "%s", srb2home, filename), "w");
|
||||
}
|
||||
|
||||
|
||||
+93
-14
@@ -47,6 +47,7 @@
|
||||
#include "z_zone.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "lua_profile.h"
|
||||
#include "m_cond.h"
|
||||
#include "m_anigif.h"
|
||||
#include "k_kart.h" // SRB2kart
|
||||
@@ -146,6 +147,11 @@ static void Command_Addfilelocal(void);
|
||||
static void Command_Addfile(void);
|
||||
static void Command_Addskins(void);
|
||||
static void Command_GLocalSkin(void);
|
||||
static void SetPrefcolor(int splitplayer);
|
||||
static void Command_UsePrefcolor(void);
|
||||
static void Command_UsePrefcolor2(void);
|
||||
static void Command_UsePrefcolor3(void);
|
||||
static void Command_UsePrefcolor4(void);
|
||||
static void Command_ListWADS_f(void);
|
||||
static void Command_LocateLump_f(void);
|
||||
static void Command_ListDoomednums_f(void);
|
||||
@@ -434,10 +440,18 @@ consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, point
|
||||
static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t,
|
||||
TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
#ifdef PHOBOS_BUILD
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||
#else
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}};
|
||||
#endif
|
||||
consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t,
|
||||
NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
#ifdef PHOBOS_BUILD
|
||||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
#else
|
||||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||
#endif
|
||||
consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_forceskin = {"forceskin", "Off", CV_NETVAR|CV_CALL|CV_CHEAT, Forceskin_cons_t, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -506,6 +520,9 @@ static CV_PossibleValue_t ps_descriptor_cons_t[] = {
|
||||
{1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}};
|
||||
consvar_t cv_ps_descriptor = {"ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
//consvar_t cv_lua_profile = {"lua_profile", "0").values(CV_Unsigned).onchange(lua_profile_OnChange).description("Show hook timings over an average of N tics");
|
||||
consvar_t cv_lua_profile = {"lua_profile", "0", CV_CALL, CV_Unsigned, lua_profile_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// only there to better keep track of it globally
|
||||
consvar_t cv_director = {"director", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -600,6 +617,12 @@ void D_RegisterServerCommands(void)
|
||||
Forceskin_cons_t[i].value = 0;
|
||||
Forceskin_cons_t[i].strvalue = NULL;
|
||||
}
|
||||
|
||||
// Set default player names
|
||||
// Monster Iestyn (12/08/19): not sure where else I could have actually put this, but oh well
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
snprintf(player_names[i], sizeof(player_names[i]), "Player %d", 1 + i);
|
||||
|
||||
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
|
||||
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
|
||||
RegisterNetXCmd(XD_MAP, Got_Mapcmd);
|
||||
@@ -848,6 +871,11 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
COM_AddCommand("localskin", Command_GLocalSkin);
|
||||
|
||||
COM_AddCommand("useprefcolor", Command_UsePrefcolor);
|
||||
COM_AddCommand("useprefcolor2", Command_UsePrefcolor2);
|
||||
COM_AddCommand("useprefcolor3", Command_UsePrefcolor3);
|
||||
COM_AddCommand("useprefcolor4", Command_UsePrefcolor4);
|
||||
|
||||
K_RegisterClientKartStuff(); // SRB2kart
|
||||
|
||||
CV_RegisterVar(&cv_screenshot_option);
|
||||
@@ -934,6 +962,8 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_palette);
|
||||
CV_RegisterVar(&cv_palettenum);
|
||||
|
||||
CV_RegisterVar(&cv_lua_profile);
|
||||
|
||||
// m_menu.c
|
||||
CV_RegisterVar(&cv_chatheight);
|
||||
CV_RegisterVar(&cv_chatwidth);
|
||||
@@ -1276,7 +1306,8 @@ static boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
|
||||
else if (len == 1) // Agh!
|
||||
{
|
||||
// Last ditch effort...
|
||||
sprintf(name, "%d", M_RandomKey(10));
|
||||
snprintf(name, MAXPLAYERNAME+1, "%d", M_RandomKey(10));
|
||||
|
||||
if (!EnsurePlayerNameIsGood(name, playernum))
|
||||
return false;
|
||||
}
|
||||
@@ -1668,7 +1699,8 @@ static void SendNameAndColor(UINT8 splitplayer)
|
||||
// Finally write out the complete packet and send it off.
|
||||
WRITESTRINGN(p, playername->zstring, MAXPLAYERNAME);
|
||||
WRITEUINT8(p, (UINT8)playercolor->value);
|
||||
WRITEUINT8(p, (UINT8)playerskin->value);
|
||||
WRITESKIN(p, (skinnum_t)playerskin->value);
|
||||
|
||||
SendNetXCmdForPlayer(splitplayer, XD_NAMEANDCOLOR, buf, p - buf);
|
||||
}
|
||||
|
||||
@@ -1676,7 +1708,8 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
player_t *player;
|
||||
char name[MAXPLAYERNAME+1] = {};
|
||||
UINT8 color, skin;
|
||||
UINT8 color;
|
||||
skinnum_t skin;
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (playernum < 0 || playernum > MAXPLAYERS)
|
||||
@@ -1698,7 +1731,7 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
|
||||
|
||||
READSTRINGN(*cp, name, MAXPLAYERNAME);
|
||||
color = READUINT8(*cp);
|
||||
skin = READUINT8(*cp);
|
||||
skin = READSKIN(*cp);
|
||||
|
||||
// set name
|
||||
if (player_name_changes[playernum] < MAXNAMECHANGES)
|
||||
@@ -2330,11 +2363,12 @@ static char *ConcatCommandArgv(int start, int end)
|
||||
if (!p)
|
||||
I_Error("ConcatCommandArgv: Out of memory!\n");
|
||||
|
||||
--end;/* handle the final argument separately */
|
||||
--end; /* handle the final argument separately */
|
||||
|
||||
for (i = start; i < end; ++i)
|
||||
{
|
||||
p += sprintf(p, "%s ", COM_Argv(i));
|
||||
if (size - (p - final) > 0)
|
||||
p += snprintf(p, size - (p - final), "%s ", COM_Argv(i));
|
||||
}
|
||||
|
||||
/* at this point "end" is actually the last argument's position */
|
||||
@@ -2748,11 +2782,11 @@ static void Command_ReplayMarker(void)
|
||||
|
||||
if (title)
|
||||
{
|
||||
snprintf(demo.titlename, 64, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
|
||||
snprintf(demo.titlename, sizeof(demo.titlename)-1, "%s [%i:%02d/%.5s]", title, G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
|
||||
Z_Free(title);
|
||||
}
|
||||
else
|
||||
snprintf(demo.titlename, 64, "[%i:%02d/%.5s]", G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
|
||||
snprintf(demo.titlename, sizeof(demo.titlename)-1, "[%i:%02d/%.5s]", G_TicsToMinutes(adjustedleveltime, false), G_TicsToSeconds(adjustedleveltime), modeattacking ? "Record Attack" : connectedservername);
|
||||
|
||||
CONS_Printf("Replay will be saved!\n");
|
||||
}
|
||||
@@ -4310,6 +4344,49 @@ static void Command_GLocalSkin(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void SetPrefcolor(int splitplayer)
|
||||
{
|
||||
// splitscreen
|
||||
if (splitscreen < splitplayer)
|
||||
return;
|
||||
|
||||
const INT32 pnum = P_GetLocalPlayerNumForNum(splitplayer);
|
||||
|
||||
player_t *player = &players[pnum];
|
||||
consvar_t *colorvars[] = {&cv_playercolor, &cv_playercolor2, &cv_playercolor3, &cv_playercolor4};
|
||||
consvar_t *playercolor = colorvars[splitplayer];
|
||||
|
||||
if (skins[player->skin].prefcolor)
|
||||
{
|
||||
CV_SetValue(playercolor, skins[player->skin].prefcolor);
|
||||
CONS_Printf("Set color to %s%s\n", HU_SkinColorToConsoleColor(skins[player->skin].prefcolor), KartColor_Names[skins[player->skin].prefcolor]);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf("\x86Your skin has no prefcolor set\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void Command_UsePrefcolor(void)
|
||||
{
|
||||
SetPrefcolor(0);
|
||||
}
|
||||
|
||||
static void Command_UsePrefcolor2(void)
|
||||
{
|
||||
SetPrefcolor(1);
|
||||
}
|
||||
|
||||
static void Command_UsePrefcolor3(void)
|
||||
{
|
||||
SetPrefcolor(2);
|
||||
}
|
||||
|
||||
static void Command_UsePrefcolor4(void)
|
||||
{
|
||||
SetPrefcolor(3);
|
||||
}
|
||||
|
||||
static void Got_RequestAddfilecmd(const UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
char filename[241];
|
||||
@@ -4349,15 +4426,15 @@ static void Got_RequestAddfilecmd(const UINT8 **cp, INT32 playernum)
|
||||
char message[275];
|
||||
|
||||
if (toomany)
|
||||
sprintf(message, M_GetText("Too many files loaded to add %s\n"), filename);
|
||||
snprintf(message, sizeof(message), M_GetText("Too many files loaded to add %s\n"), filename);
|
||||
else if (ncs == FS_NOTFOUND)
|
||||
sprintf(message, M_GetText("The server doesn't have %s\n"), filename);
|
||||
snprintf(message, sizeof(message), M_GetText("The server doesn't have %s\n"), filename);
|
||||
else if (ncs == FS_MD5SUMBAD)
|
||||
sprintf(message, M_GetText("Checksum mismatch on %s\n"), filename);
|
||||
snprintf(message, sizeof(message), M_GetText("Checksum mismatch on %s\n"), filename);
|
||||
else
|
||||
sprintf(message, M_GetText("Unknown error finding wad file (%s)\n"), filename);
|
||||
snprintf(message, sizeof(message), M_GetText("Unknown error finding wad file (%s)\n"), filename);
|
||||
|
||||
CONS_Printf("%s",message);
|
||||
CONS_Printf("%s", message);
|
||||
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
if (adminplayers[j])
|
||||
@@ -5189,8 +5266,10 @@ static void Command_Mapmd5_f(void)
|
||||
{
|
||||
INT32 i;
|
||||
char md5tmp[33];
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
sprintf(&md5tmp[i*2], "%02x", mapmd5[i]);
|
||||
snprintf(&md5tmp[i*2], 3, "%02x", mapmd5[i]);
|
||||
|
||||
CONS_Printf("%s: %s\n", G_BuildMapName(gamemap), md5tmp);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -189,6 +189,8 @@ extern consvar_t cv_ps_thinkframe_page;
|
||||
extern consvar_t cv_ps_samplesize;
|
||||
extern consvar_t cv_ps_descriptor;
|
||||
|
||||
extern consvar_t cv_lua_profile;
|
||||
|
||||
extern consvar_t cv_director, cv_kartdebugdirector, cv_showdirectorhud;
|
||||
|
||||
extern consvar_t cv_showtrackaddon;
|
||||
|
||||
+6
-4
@@ -299,10 +299,13 @@ boolean CL_CheckDownloadable(void)
|
||||
{
|
||||
INT32 j;
|
||||
char md5tmp[33];
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
sprintf(&md5tmp[j*2], "%02x", fileneeded[i].md5sum[j]);
|
||||
snprintf(&md5tmp[j*2], 3, "%02x", fileneeded[i].md5sum[j]);
|
||||
|
||||
CONS_Printf("%s", md5tmp);
|
||||
}
|
||||
|
||||
CONS_Printf("\n");
|
||||
}
|
||||
}
|
||||
@@ -1616,8 +1619,7 @@ static void CURLGetFile(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
HTTP_login *
|
||||
CURLGetLogin (const char *url, HTTP_login ***return_prev_next)
|
||||
HTTP_login *CURLGetLogin(const char *url, HTTP_login ***return_prev_next)
|
||||
{
|
||||
HTTP_login * login;
|
||||
HTTP_login ** prev_next;
|
||||
@@ -1627,7 +1629,7 @@ CURLGetLogin (const char *url, HTTP_login ***return_prev_next)
|
||||
( login = (*prev_next));
|
||||
prev_next = &login->next
|
||||
){
|
||||
if (fastcmp(login->url, url) != 0)
|
||||
if (fastcmp(login->url, url))
|
||||
{
|
||||
if (return_prev_next)
|
||||
(*return_prev_next) = prev_next;
|
||||
|
||||
+12
-3
@@ -361,11 +361,17 @@ typedef struct squishdance_s
|
||||
{
|
||||
tic_t countdown; // hold "custom 3" for 2 seconds to engange le dance
|
||||
tic_t time;
|
||||
fixed_t work;
|
||||
fixed_t ang;
|
||||
fixed_t bounce; // hehe squishy
|
||||
} squishdance_t;
|
||||
|
||||
typedef struct salty_s
|
||||
{
|
||||
bool ready;
|
||||
bool tapping;
|
||||
fixed_t zoffset;
|
||||
fixed_t momz;
|
||||
bool jump;
|
||||
} salty_t;
|
||||
|
||||
// ========================================================================
|
||||
// PLAYER STRUCTURE
|
||||
// ========================================================================
|
||||
@@ -561,6 +567,9 @@ typedef struct player_s
|
||||
|
||||
fixed_t spinoutrot; // When a player spins out, this value increments modulus 360.
|
||||
|
||||
// saltyhop! hardcode edition
|
||||
salty_t salty;
|
||||
|
||||
squishdance_t squishdance;
|
||||
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
|
||||
+2
-2
@@ -211,12 +211,12 @@ void D_SetupProtocol(void)
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (!fastcmp(buffer, "no"))
|
||||
if (fastcmp(buffer, "no"))
|
||||
{
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
else if (fastcmp(buffer, exe_path))
|
||||
else if (!fastcmp(buffer, exe_path))
|
||||
{
|
||||
// overwrite
|
||||
fclose(fp);
|
||||
|
||||
@@ -119,20 +119,25 @@ target_compile_definitions(SRB2SDL2 PRIVATE
|
||||
-DHAVE_THREADS
|
||||
)
|
||||
|
||||
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE)
|
||||
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE AND NOT SRB2_CONFIG_ASAN AND NOT SRB2_CONFIG_UBSAN AND NOT SRB2_CONFIG_TSAN)
|
||||
set_property(TARGET SRB2SDL2 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
|
||||
if(SRB2_CONFIG_ASAN)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=address)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=address -fno-omit-frame-pointer -fno-common)
|
||||
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
|
||||
endif()
|
||||
|
||||
if(SRB2_CONFIG_UBSAN)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=undefined -fno-omit-frame-pointer)
|
||||
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
|
||||
endif()
|
||||
|
||||
if(SRB2_CONFIG_TSAN)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=thread -fno-omit-frame-pointer)
|
||||
target_link_options(SRB2SDL2 PRIVATE -fsanitize=thread)
|
||||
endif()
|
||||
|
||||
## strip debug symbols into separate file when using gcc
|
||||
# if(CMAKE_COMPILER_IS_GNUCC)
|
||||
# if(${CMAKE_BUILD_TYPE} MATCHES Debug)
|
||||
|
||||
+49
-27
@@ -542,7 +542,7 @@ void I_OutputMsg(const char *fmt, ...)
|
||||
I_Error("I_OutputMsg: Out of memory!\n");
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(txt, fmt, argptr);
|
||||
vsnprintf(txt, len+1, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
#ifdef HAVE_TTF
|
||||
@@ -550,7 +550,7 @@ void I_OutputMsg(const char *fmt, ...)
|
||||
DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt);
|
||||
#endif
|
||||
|
||||
len = strlen(txt);
|
||||
len = strnlen(txt, len+1);
|
||||
|
||||
#ifdef LOGMESSAGES
|
||||
if (logstream)
|
||||
@@ -968,14 +968,18 @@ void I_Sleep(UINT32 ms)
|
||||
|
||||
void I_SleepDuration(precise_t duration)
|
||||
{
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) || defined(__OpenBSD__)
|
||||
UINT64 precision = I_GetPrecisePrecision();
|
||||
struct timespec ts = {
|
||||
.tv_sec = duration / precision,
|
||||
.tv_nsec = duration * 1000000000 / precision % 1000000000,
|
||||
};
|
||||
int status;
|
||||
#ifdef __OpenBSD__
|
||||
do status = nanosleep(&ts, &ts);
|
||||
#else
|
||||
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
|
||||
#endif
|
||||
while (status == EINTR);
|
||||
#elif defined (MIN_SLEEP_DURATION_MS)
|
||||
UINT64 precision = I_GetPrecisePrecision();
|
||||
@@ -1053,7 +1057,7 @@ static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_ms
|
||||
sigmsg = ("SIGABRT - SRB2Kart-Saturn was terminated by an abort signal.");
|
||||
break;
|
||||
default:
|
||||
sprintf(signal_msg, "Signal number %d", signal_num);
|
||||
snprintf(signal_msg, 512, "Signal number %d", signal_num);
|
||||
sigmsg = (core_dumped ? "Unknown signal" : signal_msg);
|
||||
break;
|
||||
}
|
||||
@@ -1061,13 +1065,17 @@ static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_ms
|
||||
if (core_dumped)
|
||||
{
|
||||
if (sigmsg)
|
||||
sprintf(signal_msg, "%s (core dumped)", sigmsg);
|
||||
{
|
||||
snprintf(signal_msg, 512, "%s (core dumped)", sigmsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(signal_msg, " (core dumped)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(signal_msg, "%s", sigmsg);
|
||||
snprintf(signal_msg, 512, "%s", sigmsg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1344,7 +1352,7 @@ FUNCNORETURN static ATTRNORETURN void newsignalhandler_Warn(const char *pr)
|
||||
{
|
||||
char text[128];
|
||||
|
||||
snprintf(text, sizeof text,
|
||||
snprintf(text, sizeof(text),
|
||||
"Error while setting up signal reporting: %s: %s",
|
||||
pr,
|
||||
strerror(errno)
|
||||
@@ -1530,7 +1538,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
|
||||
if (errorcount > 20)
|
||||
{
|
||||
va_start(argptr, error);
|
||||
vsnprintf(buffer, 8192, error, argptr);
|
||||
vsnprintf(buffer, sizeof(buffer), error, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
I_OutputMsg("SRB2Kart %s Recursive Error", buffer);
|
||||
@@ -1543,7 +1551,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
|
||||
|
||||
// Display error message in the console before we start shutting it down
|
||||
va_start(argptr, error);
|
||||
vsnprintf(buffer, 8192, error, argptr);
|
||||
vsnprintf(buffer, sizeof(buffer), error, argptr);
|
||||
va_end(argptr);
|
||||
I_OutputMsg("\nI_Error(): %s\n", buffer);
|
||||
|
||||
@@ -1764,7 +1772,8 @@ char *I_GetUserName(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
strncpy(username, p, MAXPLAYERNAME);
|
||||
|
||||
snprintf(username, sizeof(username), "%s", p);
|
||||
}
|
||||
|
||||
if (!fastcmp(username, ""))
|
||||
@@ -1788,6 +1797,24 @@ INT32 I_mkdir(const char *dirname, INT32 unixright)
|
||||
#endif
|
||||
}
|
||||
|
||||
INT32 I_ChDir(const char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (SetCurrentDirectoryA(path) ? 0 : -1);
|
||||
#else
|
||||
return chdir(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *I_GetCwd(char *buf, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (GetCurrentDirectoryA((DWORD)size, buf) ? buf : NULL);
|
||||
#else
|
||||
return getcwd(buf, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *I_GetEnv(const char *name)
|
||||
{
|
||||
return getenv(name);
|
||||
@@ -1820,28 +1847,23 @@ const char *I_ClipboardPaste(void)
|
||||
*/
|
||||
static boolean isWadPathOk(const char *path)
|
||||
{
|
||||
char *wad3path = (char*)(malloc(256));
|
||||
char wad3path[256];
|
||||
|
||||
if (!wad3path)
|
||||
return false;
|
||||
|
||||
sprintf(wad3path, pandf, path, WADKEYWORD);
|
||||
snprintf(wad3path, sizeof(wad3path), pandf, path, WADKEYWORD);
|
||||
|
||||
if (FIL_ReadFileOK(wad3path))
|
||||
{
|
||||
free(wad3path);
|
||||
return true;
|
||||
}
|
||||
|
||||
free(wad3path);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void pathonly(char *s)
|
||||
static void pathonly(char *s, size_t size)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
for (j = strlen(s); j != (size_t)-1; j--)
|
||||
for (j = strnlen(s, size); j != (size_t)-1; j--)
|
||||
{
|
||||
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
|
||||
{
|
||||
@@ -1868,11 +1890,12 @@ static const char *searchWad(const char *searchDir)
|
||||
static char tempsw[256] = "";
|
||||
filestatus_t fstemp;
|
||||
|
||||
strcpy(tempsw, WADKEYWORD);
|
||||
snprintf(tempsw, sizeof(tempsw), "%s", WADKEYWORD);
|
||||
fstemp = filesearch(tempsw, searchDir, NULL, true, 20);
|
||||
|
||||
if (fstemp == FS_FOUND)
|
||||
{
|
||||
pathonly(tempsw);
|
||||
pathonly(tempsw, sizeof(tempsw));
|
||||
return tempsw;
|
||||
}
|
||||
|
||||
@@ -1910,7 +1933,7 @@ static const char *locateWad(void)
|
||||
|
||||
#ifndef NOCWD
|
||||
// examine current dir
|
||||
strcpy(returnWadPath, ".");
|
||||
snprintf(returnWadPath, sizeof(returnWadPath), "%s", ".");
|
||||
I_OutputMsg(",%s", returnWadPath);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return NULL;
|
||||
@@ -1922,7 +1945,7 @@ static const char *locateWad(void)
|
||||
// examine user jart directory
|
||||
if ((envstr = I_GetEnv("HOME")) != NULL)
|
||||
{
|
||||
sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr);
|
||||
snprintf(returnWadPath, sizeof(returnWadPath), "%s" PATHSEP DEFAULTDIR, envstr);
|
||||
CHECKWADPATH(returnWadPath);
|
||||
}
|
||||
#endif
|
||||
@@ -1936,7 +1959,7 @@ static const char *locateWad(void)
|
||||
// examine default dirs
|
||||
for (i = 0; wadDefaultPaths[i]; i++)
|
||||
{
|
||||
strcpy(returnWadPath, wadDefaultPaths[i]);
|
||||
snprintf(returnWadPath, sizeof(returnWadPath), "%s", wadDefaultPaths[i]);
|
||||
CHECKWADPATH(returnWadPath);
|
||||
}
|
||||
|
||||
@@ -1964,12 +1987,11 @@ const char *I_LocateWad(void)
|
||||
// change to the directory where we found srb2.srb
|
||||
#if defined (_WIN32)
|
||||
waddir = _fullpath(NULL, waddir, MAX_PATH);
|
||||
SetCurrentDirectoryA(waddir);
|
||||
#else
|
||||
waddir = realpath(waddir, NULL);
|
||||
if (waddir == NULL || chdir(waddir) == -1)
|
||||
I_OutputMsg("Couldn't change working directory\n");
|
||||
#endif
|
||||
if (waddir == NULL || I_ChDir(waddir) == -1)
|
||||
I_OutputMsg("Couldn't change working directory\n");
|
||||
}
|
||||
|
||||
return waddir;
|
||||
|
||||
+5
-2
@@ -402,7 +402,7 @@ static void Discordrp_OnChange(void)
|
||||
static void DRPC_GotServerIP(UINT32 address)
|
||||
{
|
||||
const unsigned char * p = (const unsigned char *)&address;
|
||||
sprintf(self_ip, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port);
|
||||
snprintf(self_ip, IP_SIZE+1, "%u.%u.%u.%u:%u", p[0], p[1], p[2], p[3], current_port);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
@@ -474,6 +474,7 @@ void DRPC_UpdatePresence(void)
|
||||
char charname[11+SKINNAMESIZE+1];
|
||||
|
||||
boolean joinSecretSet = false;
|
||||
char *clientJoinSecret = NULL;
|
||||
|
||||
DiscordRichPresence discordPresence;
|
||||
memset(&discordPresence, 0, sizeof(discordPresence));
|
||||
@@ -530,7 +531,8 @@ void DRPC_UpdatePresence(void)
|
||||
// Grab the host's IP for joining.
|
||||
if ((join = DRPC_GetServerIP()) != NULL)
|
||||
{
|
||||
discordPresence.joinSecret = DRPC_XORIPString(join);
|
||||
clientJoinSecret = DRPC_XORIPString(join);
|
||||
discordPresence.joinSecret = clientJoinSecret;
|
||||
joinSecretSet = true;
|
||||
}
|
||||
}
|
||||
@@ -712,6 +714,7 @@ void DRPC_UpdatePresence(void)
|
||||
}
|
||||
|
||||
Discord_UpdatePresence(&discordPresence);
|
||||
free(clientJoinSecret);
|
||||
}
|
||||
|
||||
#endif // HAVE_DISCORDRPC
|
||||
+29
-14
@@ -128,10 +128,24 @@ extern char logfilename[1024];
|
||||
// most interface strings are ignored in development mode.
|
||||
// we use comprevision and compbranch instead.
|
||||
#else
|
||||
#ifdef PHOBOS_BUILD
|
||||
#define VERSION 1 // Game version
|
||||
#define SUBVERSION 69 // more precise version number
|
||||
#else
|
||||
#define VERSION 1 // Game version
|
||||
#define SUBVERSION 6 // more precise version number
|
||||
#define VERSIONSTRING "Saturn v9.3"
|
||||
#define VERSIONSTRINGW L"Saturn v9.3"
|
||||
#endif
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
#define CLIENTNAME "Phobos"
|
||||
#define CLIENTNAMEW L"Phobos"
|
||||
#else
|
||||
#define CLIENTNAME "Saturn"
|
||||
#define CLIENTNAMEW L"Saturn"
|
||||
#endif
|
||||
|
||||
#define VERSIONSTRING CLIENTNAME " v10.1"
|
||||
#define VERSIONSTRINGW CLIENTNAMEW L" v10.1"
|
||||
|
||||
#define SATURN_TESTING // comment out for saturn release builds!
|
||||
|
||||
@@ -602,11 +616,19 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
// None of these that are disabled in the normal build are guaranteed to work perfectly
|
||||
// Compile them at your own risk!
|
||||
|
||||
// undefine to enable fixes and features that are not vanilla compatible
|
||||
#define COMPAT_VANILLA
|
||||
// if we build with 32 player (or more!) support we dont need to care vanilla compat
|
||||
#if MAXPLAYERS > 16
|
||||
#undef COMPAT_VANILLA
|
||||
#ifdef PHOBOS_BUILD
|
||||
// we want 32 players yesss
|
||||
#undef MAXPLAYERS
|
||||
#define MAXPLAYERS 32
|
||||
|
||||
// raise skinlimit to 1024
|
||||
#undef MAXSKINS
|
||||
#define MAXSKINS 1024
|
||||
|
||||
// overwrite some of those
|
||||
// when not compiling in vanilla compat mode
|
||||
#define SATURNJOIN
|
||||
#define SATURNPAK
|
||||
#endif
|
||||
|
||||
//-- SATURN __
|
||||
@@ -673,13 +695,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
#undef UPDATE_ALERT
|
||||
#endif
|
||||
|
||||
// overwrite some of those
|
||||
// when not compiling in vanilla compat mode
|
||||
#ifndef COMPAT_VANILLA
|
||||
#define SATURNJOIN
|
||||
#define SATURNPAK
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,12 @@ extern "C" {
|
||||
#define INT64 int64_t
|
||||
#define UINT64 uint64_t
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
typedef uint16_t skinnum_t;
|
||||
#else
|
||||
typedef uint8_t skinnum_t;
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE_CC__
|
||||
#define DEBUG_LOG
|
||||
#define NOIPX
|
||||
|
||||
+2
-1
@@ -111,7 +111,8 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum)
|
||||
goto freemask;
|
||||
|
||||
// SRB2Kart: This suddenly triggers ERRORMODE now
|
||||
//sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
|
||||
//snprintf(&lumpname[4], 3, "%.2hu%.2hu", (UINT16)masknum, (UINT16)scrnnum);
|
||||
//lumpname[8] = 0;
|
||||
|
||||
lumpname[4] = '0'+(masknum/10);
|
||||
lumpname[5] = '0'+(masknum%10);
|
||||
|
||||
+60
-89
@@ -63,7 +63,6 @@
|
||||
|
||||
// for replay dates
|
||||
#include <time.h>
|
||||
#include <locale.h>
|
||||
|
||||
// menu demo things
|
||||
UINT32 demoDelayTime = 15*TICRATE;
|
||||
@@ -1723,11 +1722,11 @@ void G_BeginRecording(void)
|
||||
// Print to a separate temp buffer instead of demo.titlename, so we can use it in M_TextInputSetString
|
||||
if (title)
|
||||
{
|
||||
snprintf(demotitlename, 64, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
|
||||
snprintf(demotitlename, sizeof(demotitlename)-1, "%s - %s", title, modeattacking ? "Time Attack" : connectedservername);
|
||||
Z_Free(title);
|
||||
}
|
||||
else
|
||||
snprintf(demotitlename, 64, "%s", modeattacking ? "Time Attack" : connectedservername);
|
||||
snprintf(demotitlename, sizeof(demotitlename)-1, "%s", modeattacking ? "Time Attack" : connectedservername);
|
||||
|
||||
// Init just in case it isn't initialized already
|
||||
M_TextInputInit(&demo.titlenameinput, demo.titlename, sizeof(demo.titlename));
|
||||
@@ -2212,7 +2211,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), pdemo->filepath);
|
||||
pdemo->type = MD_INVALID;
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2222,7 +2221,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath);
|
||||
pdemo->type = MD_INVALID;
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2247,14 +2246,14 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
pdemo->type = MD_OUTDATED;
|
||||
sprintf(pdemo->title, "Legacy Replay");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "Legacy Replay");
|
||||
break;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
|
||||
pdemo->type = MD_INVALID;
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2267,7 +2266,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemo->filepath);
|
||||
pdemo->type = MD_INVALID;
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2288,7 +2287,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is a legacy multiplayer replay and cannot be played.\n"), pdemo->filepath);
|
||||
pdemo->type = MD_INVALID;
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -2335,7 +2334,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
while (READUINT8(extrainfo_p) == DW_STANDING) // Assume standings are always first in the extrainfo
|
||||
{
|
||||
INT32 i;
|
||||
char temp[16];
|
||||
char temp[17];
|
||||
|
||||
pdemo->standings[count].ranking = READUINT8(extrainfo_p);
|
||||
|
||||
@@ -2345,6 +2344,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
|
||||
// Skin
|
||||
memcpy(temp, extrainfo_p, 16);
|
||||
temp[16] = '\0';
|
||||
extrainfo_p += 16;
|
||||
pdemo->standings[count].skin = UINT8_MAX;
|
||||
|
||||
@@ -2359,6 +2359,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
|
||||
// Color
|
||||
memcpy(temp, extrainfo_p, 16);
|
||||
temp[16] = '\0';
|
||||
extrainfo_p += 16;
|
||||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
@@ -2385,7 +2386,9 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
#if defined (_WIN32)
|
||||
// return the file creation time
|
||||
// useful for demos that were renamed
|
||||
static long G_GetCreationTime(char *filepath)
|
||||
// windows only, as file creation times are
|
||||
// very unreliable (or non existant depending on fs) on linux
|
||||
static time_t G_GetCreationTime(char *filepath)
|
||||
{
|
||||
struct stat fileinfo;
|
||||
|
||||
@@ -2396,35 +2399,24 @@ static long G_GetCreationTime(char *filepath)
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *G_GetDemoDate(menudemo_t *pdemo)
|
||||
static char *G_GetDemoDate(menudemo_t *pdemo, const char *dateformat)
|
||||
{
|
||||
char *endPos = NULL;
|
||||
static char datetime[11];
|
||||
char *datetime;
|
||||
time_t file_time = 0;
|
||||
const char *format = NULL;
|
||||
struct tm *tm_buf = NULL;
|
||||
struct tm tm_buf;
|
||||
CLEANUP(pfree) char *filename = NULL;
|
||||
|
||||
// get le filepath
|
||||
filename = strdup(pdemo->filepath);
|
||||
|
||||
if (!filename)
|
||||
{
|
||||
#if defined (_WIN32)
|
||||
// if we cant get a filename try just getting the file creation time
|
||||
file_time = G_GetCreationTime(pdemo->filepath);
|
||||
goto skipfilenametime;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// get the actual filename Zzz...
|
||||
nameonly(filename);
|
||||
|
||||
// the first 10 characters of a replay name usually is a unix timestamp
|
||||
|
||||
// not long enough to contain a valid timestamp
|
||||
// the first 10 characters of a replay name is a unix timestamp
|
||||
if (strlen(filename) < 10)
|
||||
{
|
||||
#if defined (_WIN32)
|
||||
@@ -2456,73 +2448,55 @@ static char *G_GetDemoDate(menudemo_t *pdemo)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (_WIN32)
|
||||
skipfilenametime:
|
||||
#endif
|
||||
|
||||
// then throw it into localtime to get an actual human readable format lmao
|
||||
tm_buf = localtime(&file_time);
|
||||
|
||||
// cant believe we ended up in 1970
|
||||
if (tm_buf == NULL || tm_buf->tm_year <= 110)
|
||||
#if defined(_WIN32)
|
||||
skipfilenametime:
|
||||
if ((localtime_s(&tm_buf, &file_time) != 0) ||
|
||||
(tm_buf.tm_year <= 110)) // cant believe we ended up in 1970
|
||||
{
|
||||
#if defined (_WIN32)
|
||||
// uh ohh, we got an invalid time
|
||||
// try one more time getting the creation time
|
||||
file_time = G_GetCreationTime(pdemo->filepath);
|
||||
tm_buf = localtime(&file_time);
|
||||
|
||||
if (tm_buf == NULL || tm_buf->tm_year <= 110)
|
||||
if ((localtime_s(&tm_buf, &file_time) != 0) ||
|
||||
(tm_buf.tm_year <= 110))
|
||||
return NULL;
|
||||
|
||||
goto gotcreationtime;
|
||||
}
|
||||
#else
|
||||
if ((localtime_r(&file_time, &tm_buf) == NULL) ||
|
||||
(tm_buf.tm_year <= 110)) // cant believe we ended up in 1970
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (_WIN32)
|
||||
gotcreationtime:
|
||||
#endif
|
||||
datetime = malloc(sizeof(pdemo->date)); // mallocma balls
|
||||
|
||||
// US ppl are special (:
|
||||
if (cv_demodateformat.value == 2)
|
||||
format = "%m.%d.%Y";
|
||||
else if (cv_demodateformat.value == 1)
|
||||
format = "%d.%m.%Y";
|
||||
else
|
||||
{
|
||||
const char *locale = setlocale(LC_TIME, NULL);
|
||||
// no mallocma balls... :c
|
||||
if (!datetime)
|
||||
return NULL;
|
||||
|
||||
if (locale == NULL)
|
||||
format = "%d.%m.%Y"; // fallback to non US format
|
||||
else if (strstr(locale, "en_US"))
|
||||
format = "%m.%d.%Y";
|
||||
else
|
||||
format = "%d.%m.%Y";
|
||||
}
|
||||
|
||||
if (strftime(datetime, sizeof(datetime), format, tm_buf) == 0)
|
||||
if (strftime(datetime, sizeof(pdemo->date), dateformat, &tm_buf) == 0)
|
||||
{
|
||||
free(datetime);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return datetime;
|
||||
}
|
||||
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo)
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo, const char *dateformat)
|
||||
{
|
||||
UINT8 infobuffer[96], *info_p;
|
||||
UINT16 pdemoversion;
|
||||
char *demodate = NULL;
|
||||
size_t count;
|
||||
|
||||
memset(pdemo->date, 0, sizeof(pdemo->date));
|
||||
|
||||
FILE *handle = fopen(pdemo->filepath, "rb");
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Failed to read file '%s'.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2534,7 +2508,7 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
|
||||
if (count < 96 || memcmp(info_p, DEMOHEADER, 12))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2544,8 +2518,6 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
|
||||
|
||||
pdemoversion = READUINT16(info_p);
|
||||
|
||||
memset(pdemo->date, 0, sizeof(pdemo->date));
|
||||
|
||||
switch (pdemoversion)
|
||||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
@@ -2553,23 +2525,22 @@ void G_LoadDemoTitle(menudemo_t *pdemo)
|
||||
memcpy(pdemo->title, info_p, 64);
|
||||
|
||||
// demo date
|
||||
demodate = G_GetDemoDate(pdemo);
|
||||
|
||||
char *demodate = G_GetDemoDate(pdemo, dateformat);
|
||||
if (demodate)
|
||||
{
|
||||
strlcpy(pdemo->date, demodate, sizeof(pdemo->date));
|
||||
free(demodate);
|
||||
}
|
||||
|
||||
break;
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
sprintf(pdemo->title, "Legacy Replay");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "Legacy Replay");
|
||||
break;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
snprintf(pdemo->title, sizeof(pdemo->title), "INVALID REPLAY");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2633,7 +2604,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
//FIL_DefaultExtension(defdemoname, ".lmp");
|
||||
if (!FIL_ReadFile(defdemoname, &demobuf.buffer))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("Failed to read file '%s'.\n"), defdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("Failed to read file '%s'.\n"), defdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
gameaction = ga_nothing;
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
@@ -2645,7 +2616,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// load demo resource from WAD
|
||||
else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("Failed to read lump '%s'.\n"), defdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
gameaction = ga_nothing;
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
@@ -2666,7 +2637,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
|
||||
if (memcmp(demobuf.p, DEMOHEADER, 12))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2692,7 +2663,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2703,7 +2674,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
|
||||
if (memcmp(demobuf.p, "PLAY", 4))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s is the wrong type of recording and cannot be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2720,7 +2691,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
{
|
||||
if (demoflags & DF_MULTIPLAYER)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2747,31 +2718,31 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
switch (error)
|
||||
{
|
||||
case DFILE_ERROR_NOTLOADED:
|
||||
snprintf(msg, 1024,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Required files for this demo are not loaded.\n\nUse\n\"playdemo %s -addfiles\"\nto load them and play the demo.\n",
|
||||
pdemoname);
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_OUTOFORDER:
|
||||
snprintf(msg, 1024,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Required files for this demo are loaded out of order.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
|
||||
pdemoname);
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_INCOMPLETEOUTOFORDER:
|
||||
snprintf(msg, 1024,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Required files for this demo are not loaded, and some are out of order.\n\nUse\n\"playdemo %s -addfiles\"\nto load needed files and play the demo.\n",
|
||||
pdemoname);
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_CANNOTLOAD:
|
||||
snprintf(msg, 1024,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Required files for this demo cannot be loaded.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
|
||||
pdemoname);
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_EXTRAFILES:
|
||||
snprintf(msg, 1024,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"You have additional files loaded beyond the demo's file list.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n",
|
||||
pdemoname);
|
||||
break;
|
||||
@@ -2821,7 +2792,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// ...*map* not loaded?
|
||||
if (!gamemap || (gamemap > NUMMAPS) || (W_CheckNumForName(G_BuildMapName(gamemap)) == LUMPERROR))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2853,7 +2824,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// Skin not loaded?
|
||||
if (!SetPlayerSkin(0, skin))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2863,7 +2834,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// ...*map* not loaded?
|
||||
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2886,7 +2857,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// Sigh ... it's an empty demo.
|
||||
if (*demobuf.p == DEMOMARKER)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s contains no data to be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2924,7 +2895,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// Sigh ... it's an empty demo.
|
||||
if (*demobuf.p == DEMOMARKER)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s contains no data to be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2973,7 +2944,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
|
||||
if (modeattacking)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
@@ -2985,7 +2956,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
|
||||
if (modeattacking && numslots > 1)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname);
|
||||
snprintf(msg, sizeof(msg), M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, M_ReturnToTitleFromError, MM_EVENTHANDLER);
|
||||
G_ResetDemoPlayback();
|
||||
|
||||
+3
-2
@@ -82,7 +82,8 @@ typedef struct menudemo_s {
|
||||
struct {
|
||||
UINT8 ranking;
|
||||
char name[17];
|
||||
UINT8 skin, color;
|
||||
skinnum_t skin;
|
||||
UINT8 color;
|
||||
UINT32 timeorscore;
|
||||
} standings[MAXPLAYERS];
|
||||
} menudemo_t;
|
||||
@@ -97,7 +98,7 @@ void G_SetDemoTime(UINT32 ptime, UINT32 plap);
|
||||
UINT8 G_CmpDemoTime(char *oldname, char *newname);
|
||||
|
||||
void G_LoadDemoInfo(menudemo_t *pdemo);
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo); // For use in replay search feature
|
||||
void G_LoadDemoTitle(menudemo_t *pdemo, const char *dateformat); // For use in replay search feature
|
||||
void G_DeferedPlayDemo(const char *demo);
|
||||
|
||||
typedef enum
|
||||
|
||||
+24
-35
@@ -63,7 +63,7 @@ gameaction_t gameaction = 0;
|
||||
gamestate_t gamestate = GS_NULL;
|
||||
|
||||
boolean botingame = false;
|
||||
UINT8 botskin = 0;
|
||||
skinnum_t botskin = 0;
|
||||
UINT8 botcolor = 0;
|
||||
|
||||
// SRB2kart
|
||||
@@ -453,34 +453,13 @@ consvar_t cv_driftsparkpulse = {"driftsparkpulse", "1.4", CV_FLOAT | CV_SAVE, dr
|
||||
static CV_PossibleValue_t cechotoggle_t[] = {{0, "Off"}, {1, "On"}, {2, "Console"}, {0, NULL}};
|
||||
consvar_t cv_cechotoggle = {"show_cecho", "On", CV_SAVE, cechotoggle_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#if MAXPLAYERS > 16
|
||||
#error "please update player_name table using the new value for MAXPLAYERS"
|
||||
#endif
|
||||
|
||||
#ifdef SEENAMES
|
||||
player_t *seenplayer = NULL; // player we're aiming at right now
|
||||
#endif
|
||||
|
||||
char player_names[MAXPLAYERS][MAXPLAYERNAME+1] =
|
||||
{
|
||||
"Player 1",
|
||||
"Player 2",
|
||||
"Player 3",
|
||||
"Player 4",
|
||||
"Player 5",
|
||||
"Player 6",
|
||||
"Player 7",
|
||||
"Player 8",
|
||||
"Player 9",
|
||||
"Player 10",
|
||||
"Player 11",
|
||||
"Player 12",
|
||||
"Player 13",
|
||||
"Player 14",
|
||||
"Player 15",
|
||||
"Player 16"
|
||||
}; // SRB2kart - removed Players 17 through 32
|
||||
|
||||
// now automatically allocated in D_RegisterServerCommands
|
||||
// so that it doesn't have to be updated depending on the value of MAXPLAYERS
|
||||
char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
||||
INT32 player_name_changes[MAXPLAYERS] = {};
|
||||
|
||||
INT16 rw_maximums[NUM_WEAPONS] =
|
||||
@@ -625,14 +604,18 @@ const char *G_BuildMapName(INT32 map)
|
||||
}
|
||||
|
||||
if (map < 100 && map >= 0) // ...but why use signed integer in first place? idk but this prevents warning (and potential buffer overflow lol)
|
||||
sprintf(&mapname[3], "%.2d", map);
|
||||
{
|
||||
snprintf(&mapname[3], sizeof(mapname)-3, "%.2d", map);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapname[3] = (char)('A' + (char)((map - 100) / 36));
|
||||
|
||||
if ((map - 100) % 36 < 10)
|
||||
mapname[4] = (char)('0' + (char)((map - 100) % 36));
|
||||
else
|
||||
mapname[4] = (char)('A' + (char)((map - 100) % 36) - 10);
|
||||
|
||||
mapname[5] = '\0';
|
||||
}
|
||||
|
||||
@@ -2647,12 +2630,18 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
|
||||
// Just spawn there.
|
||||
//return playerstarts[0];
|
||||
|
||||
#if MAXPLAYERS > 16
|
||||
//this section courtesy of fickle - v1.1 battle royale
|
||||
// screw collision chex
|
||||
return playerstarts[pos % numcoopstarts];
|
||||
#else
|
||||
if (P_IsLocalPlayerNum(playernum))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Could not spawn at any Race starts!\n");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (P_IsLocalPlayerNum(playernum))
|
||||
@@ -3787,7 +3776,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
||||
startonmapnum = mapoverride;
|
||||
#endif
|
||||
|
||||
sprintf(savename, savegamename, slot);
|
||||
snprintf(savename, sizeof(savename), savegamename, slot);
|
||||
|
||||
length = FIL_ReadFile(savename, &save.buffer);
|
||||
if (!length)
|
||||
@@ -3799,7 +3788,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
||||
save.p = save.buffer;
|
||||
|
||||
memset(vcheck, 0, sizeof (vcheck));
|
||||
sprintf(vcheck, "version %d", VERSION);
|
||||
snprintf(vcheck, sizeof(vcheck), "version %d", VERSION);
|
||||
|
||||
if (!fastcmp((const char *)save.p, (const char *)vcheck))
|
||||
{
|
||||
@@ -3865,8 +3854,8 @@ void G_SaveGame(UINT32 savegameslot)
|
||||
const char *backup;
|
||||
savebuffer_t save = {};
|
||||
|
||||
sprintf(savename, savegamename, savegameslot);
|
||||
backup = va("%s",savename);
|
||||
snprintf(savename, sizeof(savename), savegamename, savegameslot);
|
||||
backup = va("%s", savename);
|
||||
|
||||
// save during evaluation or credits? game's over, folks!
|
||||
if (gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
|
||||
@@ -3884,8 +3873,8 @@ void G_SaveGame(UINT32 savegameslot)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(name, 0, sizeof (name));
|
||||
sprintf(name, "version %d", VERSION);
|
||||
memset(name, 0, sizeof(name));
|
||||
snprintf(name, sizeof(name), "version %d", VERSION);
|
||||
WRITEMEM(save.p, name, VERSIONSIZE);
|
||||
|
||||
P_SaveGame(&save);
|
||||
@@ -4114,12 +4103,12 @@ char *G_BuildMapTitle(INT32 mapnum)
|
||||
if (!title)
|
||||
return NULL;
|
||||
|
||||
sprintf(title, "%s", mapheaderinfo[mapnum-1]->lvlttl);
|
||||
snprintf(title, len, "%s", mapheaderinfo[mapnum-1]->lvlttl);
|
||||
|
||||
if (zonetext)
|
||||
sprintf(title + strlen(title), " %s", zonetext);
|
||||
snprintf(title + strlen(title), len - strlen(title), " %s", zonetext);
|
||||
if (actnum)
|
||||
sprintf(title + strlen(title), " %s", actnum);
|
||||
snprintf(title + strlen(title), len - strlen(title), " %s", actnum);
|
||||
}
|
||||
|
||||
return title;
|
||||
|
||||
+2
-1
@@ -1250,7 +1250,8 @@ const char *G_KeynumToString(INT32 keynum)
|
||||
return keynames[j].name;
|
||||
|
||||
// create a name for unknown keys
|
||||
sprintf(keynamestr, "KEY%d", keynum);
|
||||
snprintf(keynamestr, sizeof(keynamestr), "KEY%d", keynum);
|
||||
|
||||
return keynamestr;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -55,6 +55,7 @@ extern gamestate_t gamestate;
|
||||
extern gameaction_t gameaction;
|
||||
|
||||
extern boolean botingame;
|
||||
extern UINT8 botskin, botcolor;
|
||||
extern skinnum_t botskin;
|
||||
extern UINT8 botcolor;
|
||||
|
||||
#endif //__G_STATE__
|
||||
@@ -35,7 +35,7 @@ static int finalVertexArrayAllocSize = 65536;
|
||||
// not gonna use this for now, just sort by color and change state when it changes
|
||||
// later maybe when using vertex attributes if it's needed
|
||||
|
||||
static PolygonArrayEntry* polygonArray = NULL ;// contains the polygon data from DrawPolygon, waiting to be processed
|
||||
static PolygonArrayEntry* polygonArray = NULL; // contains the polygon data from DrawPolygon, waiting to be processed
|
||||
static PolygonArrayEntry **polygonArraySorted = NULL; // contains sorted pointers to polygonArray
|
||||
static int polygonArraySize = 0;
|
||||
static int polygonArrayAllocSize = 65536;
|
||||
@@ -171,8 +171,8 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||
|
||||
// special case with signedness to prevent overflowing
|
||||
// FIXME: check for prediction slowdowns!
|
||||
const int shader1 = poly1->hash & 0x80000000 ? -1 : poly1->shader;
|
||||
const int shader2 = poly2->hash & 0x80000000 ? -1 : poly2->shader;
|
||||
const int shader1 = (poly1->hash & 0x80000000) ? -1 : poly1->shader;
|
||||
const int shader2 = (poly2->hash & 0x80000000) ? -1 : poly2->shader;
|
||||
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (shader1 == -1 && shader2 == -1)
|
||||
@@ -214,8 +214,8 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
const PolygonArrayEntry *poly1 = *(PolygonArrayEntry *const *)p1;
|
||||
const PolygonArrayEntry *poly2 = *(PolygonArrayEntry *const *)p2;
|
||||
|
||||
const GLMipmap_t *texture1 = poly1->hash & 0x80000000 ? NULL : poly1->texture;
|
||||
const GLMipmap_t *texture2 = poly2->hash & 0x80000000 ? NULL : poly2->texture;
|
||||
const GLMipmap_t *texture1 = (poly1->hash & 0x80000000) ? NULL : poly1->texture;
|
||||
const GLMipmap_t *texture2 = (poly2->hash & 0x80000000) ? NULL : poly2->texture;
|
||||
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (!texture1 && !texture2)
|
||||
|
||||
+106
-21
@@ -96,7 +96,7 @@ static void HWR_FreePoly(poly_t *poly)
|
||||
// divfrac = how far along partline vector is crossing pt
|
||||
static boolean fracdivline(fdivline_t *partline, polyvertex_t *v1, polyvertex_t *v2)
|
||||
{
|
||||
double frac1, frac2;
|
||||
double frac;
|
||||
double num; // numerator
|
||||
double den; // denominator
|
||||
double v1x, v1y, v1dx, v1dy; // polygon side vector, v1->v2
|
||||
@@ -122,24 +122,23 @@ static boolean fracdivline(fdivline_t *partline, polyvertex_t *v1, polyvertex_t
|
||||
// first check the frac along the polygon segment,
|
||||
// (do not accept hit with the extensions)
|
||||
num = (v3x - v1x)*v3dy + (v1y - v3y)*v3dx;
|
||||
frac1 = num / den;
|
||||
frac = num / den;
|
||||
|
||||
// 0= cross at v1, 1.0= cross at v2
|
||||
if (frac1 < 0.0 || frac1 > 1.0) // double
|
||||
if (frac < 0.0 || frac > 1.0) // double
|
||||
return false; // not within the polygon side
|
||||
|
||||
// now get the frac along the BSP line
|
||||
// which is useful to determine what is left, what is right
|
||||
num = (v3x - v1x)*v1dy + (v1y - v3y)*v1dx;
|
||||
frac2 = num / den;
|
||||
|
||||
partline->divfrac = frac2; // how far along partline vector
|
||||
partline->divfrac = num / den; // how far along partline vector
|
||||
|
||||
// [WDJ] find the interception point along the segment.
|
||||
// It should be slightly more accurate because it is always closer to the
|
||||
// crossing point than arbitrary positions on the partition line.
|
||||
partline->divpt.x = v1x + v1dx*frac1;
|
||||
partline->divpt.y = v1y + v1dy*frac1;
|
||||
partline->divpt.x = v1x + v1dx*frac;
|
||||
partline->divpt.y = v1y + v1dy*frac;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -161,6 +160,71 @@ static boolean SameVertex(polyvertex_t *p1, polyvertex_t *p2)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adapted from function in prboom.
|
||||
// Point is to rightside of divline when result > 0,
|
||||
// but result is multiplied by length of divline.
|
||||
// Returns near 0, when point is on, or nearly on, the divline.
|
||||
static inline double point_rightside(fdivline_t *dl, polyvertex_t *v4)
|
||||
{
|
||||
// Cross product of dl and vector dl->(x,y) to v4,
|
||||
// is > 0 when v4 is to right side of divline.
|
||||
// Viewed along divline from vertex, looking towards positive dx,dy.
|
||||
// If divline is rotated until dy>0 and dx = 0, then true when rotated
|
||||
// vertex position is to the right of the divline (v4->x > dl->x).
|
||||
return ((((double)(v4->x) - (double)(dl->x)) * (double)(dl->dy))
|
||||
- (((double)(v4->y) - (double)(dl->y)) * (double)(dl->dx)));
|
||||
}
|
||||
|
||||
// [WDJ] The front and back MUST match the BSP determination, else it will assign
|
||||
// this poly to the wrong sector.
|
||||
// May have 1 point on the line, and other points might be very close to the line.
|
||||
// Can only trust a test of a point that is NOT on the line.
|
||||
// Using a tstdist = 0.5f worked, but it might break on very small poly.
|
||||
// Avactor.wad had polys with d = 9.09, 5552, 1.64, 1011, 14252, 0.0136, 0.00634, 14655, 3,
|
||||
// -0.3044, 7, 1.53, etc..,
|
||||
// and one poly with d = -0.023 with the rest of the points d > 0.
|
||||
// One 14 point poly with divline len=8, had to test 9 points to find d = 36.
|
||||
// Typical: divline len=70 d=6828, divline len=1.0 d=35, divline len=1.414 d=5.
|
||||
// The result of point_rightside is proportional to the length of divline.
|
||||
// The divline length can be from 1.414 to 14000.
|
||||
static void UnsplitPoly(fdivline_t *dlnp, poly_t *poly,
|
||||
poly_t **frontpoly, poly_t **backpoly)
|
||||
{
|
||||
int32_t i;
|
||||
double d;
|
||||
const double tstd = hypot((double)dlnp->dx, (double)dlnp->dy) / 2.0;
|
||||
double sumd = 0; // accumulated left or rightness.
|
||||
|
||||
for (i = 0; i < poly->numpts; i++)
|
||||
{
|
||||
// Look for a point that is obviously to the left or right.
|
||||
d = point_rightside(dlnp, &poly->pts[i]); // d > 0 is right
|
||||
sumd += d;
|
||||
|
||||
if (d > tstd)
|
||||
goto poly_rightside;
|
||||
|
||||
if (d < -tstd)
|
||||
goto poly_leftside;
|
||||
}
|
||||
|
||||
// Did not find an obvious left or right point, then
|
||||
if (sumd < 0)
|
||||
goto poly_leftside;
|
||||
|
||||
poly_rightside:
|
||||
// poly is to rightside of divline.
|
||||
*frontpoly = poly;
|
||||
*backpoly = NULL;
|
||||
return;
|
||||
|
||||
poly_leftside:
|
||||
// poly is to leftside of divline.
|
||||
*frontpoly = NULL;
|
||||
*backpoly = poly;
|
||||
return;
|
||||
}
|
||||
|
||||
// split a _CONVEX_ polygon in two convex polygons
|
||||
// outputs:
|
||||
// frontpoly : polygon on right side of bsp line
|
||||
@@ -263,10 +327,7 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
|
||||
// linedefs where each side point the same sector, that is:
|
||||
// the deep water effect with the original Doom
|
||||
|
||||
//TODO: make sure front poly is to front of partition line?
|
||||
|
||||
*frontpoly = poly;
|
||||
*backpoly = NULL;
|
||||
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -274,16 +335,14 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
|
||||
if (pe < 0)
|
||||
{
|
||||
//I_Error("SplitPoly: only one point for split line (%d %d)", ps, pe);
|
||||
*frontpoly = poly;
|
||||
*backpoly = NULL;
|
||||
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pe <= ps)
|
||||
{
|
||||
//I_Error("SplitPoly: invalid splitting line (%d %d)", ps, pe);
|
||||
*frontpoly = poly;
|
||||
*backpoly = NULL;
|
||||
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -346,15 +405,15 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
|
||||
}
|
||||
|
||||
// checks if any line is a portal or horizonline, for optimization
|
||||
static inline void CheckForPortalsAndHorizonLines(seg_t *lseg, const line_t *line)
|
||||
static inline void CheckForPortalsAndHorizonLines(boolean firstside, const line_t *line)
|
||||
{
|
||||
// portal check
|
||||
if (!gl_maphasportals && lseg->side == 0 && line->special == PORTALSPECIAL)
|
||||
if (!gl_maphasportals && firstside && line->special == PORTALSPECIAL)
|
||||
{
|
||||
// Find the other side!
|
||||
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, -1);
|
||||
|
||||
if (line == &lines[line2])
|
||||
if (line2 >= 0 && line == &lines[line2])
|
||||
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, line2);
|
||||
|
||||
if (line2 >= 0) // found it!
|
||||
@@ -388,6 +447,10 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly)
|
||||
vertex_t *v1, *v2;
|
||||
fdivline_t cutseg; // x, y, dx, dy as start of node_t struct
|
||||
|
||||
// empty poly? just save us some time then
|
||||
if (poly->numpts <= 0)
|
||||
return frontpoly;
|
||||
|
||||
// for each seg of the subsector
|
||||
for (; segcount--; lseg++)
|
||||
{
|
||||
@@ -397,7 +460,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly)
|
||||
if (!line)
|
||||
continue;
|
||||
|
||||
CheckForPortalsAndHorizonLines(lseg, line);
|
||||
CheckForPortalsAndHorizonLines(lseg->side == 0, line);
|
||||
|
||||
if (line->sidenum[1] != NO_INDEX)
|
||||
{
|
||||
@@ -489,6 +552,23 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly)
|
||||
// need 2 points
|
||||
if (pe >= 0)
|
||||
{
|
||||
// Cuts that miss the polygon.
|
||||
if (ps_frac < 0.0 && cutseg.divfrac < 0.0)
|
||||
continue;
|
||||
|
||||
if (ps_frac > 1.0 && cutseg.divfrac > 1.0)
|
||||
continue;
|
||||
#define FRAC_EP 0.01f
|
||||
// Reject cuts that could make the polygon non-convex.
|
||||
|
||||
// Cannot make normal cut, ps_frac end is loose.
|
||||
if ((ps_frac < (0.0 - FRAC_EP)) || (ps_frac > (1.0f + FRAC_EP)))
|
||||
continue;
|
||||
|
||||
// Cannot make normal cut, cutseg.divfrac end is loose.
|
||||
if ((cutseg.divfrac < (0.0 - FRAC_EP)) || (cutseg.divfrac > (1.0f + FRAC_EP)))
|
||||
continue;
|
||||
#undef FRAC_EP
|
||||
// generate FRONT poly
|
||||
frontpoly = HWR_AllocPoly(poly_num_pts);
|
||||
|
||||
@@ -581,7 +661,8 @@ static void loading_status(void)
|
||||
|
||||
I_OsPolling();
|
||||
CON_Drawer();
|
||||
sprintf(s, "%d%%", (++ls_percent)<<1);
|
||||
snprintf(s, sizeof(s), "%d%%", (++ls_percent)<<1);
|
||||
|
||||
x = BASEVIDWIDTH/2;
|
||||
y = BASEVIDHEIGHT/2;
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); // Black background to match fade in effect
|
||||
@@ -679,7 +760,11 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
|
||||
memcpy(bbox, bsp->bbox[0], 4*sizeof (fixed_t));
|
||||
}
|
||||
else
|
||||
I_Error("WalkBSPNode: no front poly?");
|
||||
{
|
||||
// [WDJ] Having no front poly is as likely as no back poly, since
|
||||
// logic in Split Poly was changed to check poly direction.
|
||||
// I_Error("HWR_WalkBSPNode: no front poly, bspnum= %d\n", bspnum);
|
||||
}
|
||||
|
||||
// Recursively divide back space.
|
||||
if (backpoly)
|
||||
|
||||
+35
-37
@@ -555,7 +555,8 @@ static void HWR_FreePatchCache(boolean freeall)
|
||||
callback = FreeColormapsCallback;
|
||||
|
||||
//Z_IterateTags(PU_PATCH, PU_PATCH_ROTATED, callback);
|
||||
Z_IterateTags(PU_PATCH, PU_PATCH, callback);
|
||||
//Z_IterateTags(PU_PATCH, PU_PATCH_LOWPRIORITY, callback); // we dont really need to free low priority patches here as P_FreeLevelState takes care of them
|
||||
Z_IterateTag(PU_PATCH, callback);
|
||||
Z_IterateTags(PU_SPRITE, PU_HUDGFX, callback);
|
||||
}
|
||||
|
||||
@@ -613,29 +614,28 @@ void HWR_FreeMapTextures(void)
|
||||
gl_numtextures = 0;
|
||||
}
|
||||
|
||||
#define NAME flatcheck
|
||||
#define KEY_TY UINT32
|
||||
#define HASH_FN vt_hash_integer
|
||||
#define CMPR_FN vt_cmpr_integer
|
||||
#include "../verstable.h"
|
||||
|
||||
static void HWR_PrecacheLevelFlats(void)
|
||||
{
|
||||
// lookup for flats that may´ve been already loaded
|
||||
flatcheck flatpresent;
|
||||
size_t i, j;
|
||||
size_t i;
|
||||
INT32 k;
|
||||
|
||||
flatcheck_init(&flatpresent);
|
||||
flatcheck_reserve(&flatpresent, numlevelflats);
|
||||
// FIXME: this needs to account for FOFs to properly work
|
||||
#ifdef GLENCORE
|
||||
if (encoremap)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// special case for encore
|
||||
#if 0
|
||||
#ifdef GLENCORE
|
||||
if (encoremap)
|
||||
{
|
||||
// go through all sectors to determine if it should be remapped for encore
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
size_t j;
|
||||
sector_t *sec = §ors[i];
|
||||
|
||||
// gotta check sector floor and ceiling
|
||||
@@ -669,6 +669,7 @@ static void HWR_PrecacheLevelFlats(void)
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
// on non encore we have it simple
|
||||
@@ -677,11 +678,7 @@ static void HWR_PrecacheLevelFlats(void)
|
||||
{
|
||||
const levelflat_t *levelflat = &levelflats[i];
|
||||
|
||||
if (flatcheck_is_end(flatcheck_get(&flatpresent, levelflat->lumpnum)))
|
||||
{
|
||||
HWR_GetFlat(levelflat->lumpnum, false);
|
||||
flatcheck_insert(&flatpresent, levelflat->lumpnum);
|
||||
}
|
||||
HWR_GetFlat(levelflat->lumpnum, false);
|
||||
|
||||
if (levelflat->speed) // is it an animated flat ?
|
||||
{
|
||||
@@ -689,17 +686,11 @@ static void HWR_PrecacheLevelFlats(void)
|
||||
for (k = 0; k < levelflat->numpics; k++)
|
||||
{
|
||||
lumpnum_t lump = levelflat->baselumpnum + k;
|
||||
if (flatcheck_is_end(flatcheck_get(&flatpresent, lump)))
|
||||
{
|
||||
HWR_GetFlat(lump, false);
|
||||
flatcheck_insert(&flatpresent, lump);
|
||||
}
|
||||
HWR_GetFlat(lump, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flatcheck_cleanup(&flatpresent);
|
||||
}
|
||||
|
||||
static void HWR_PrecacheLevelTextures(void)
|
||||
@@ -723,7 +714,7 @@ static void HWR_PrecacheLevelTextures(void)
|
||||
{
|
||||
const line_t *line = &lines[i];
|
||||
#ifdef GLENCORE
|
||||
const int noencoremap = ((encoremap && (line->flags & ML_TFERLINE)) ? 2 : 1);
|
||||
const boolean noencoremap = (encoremap && (line->flags & ML_TFERLINE));
|
||||
#endif
|
||||
// two sides
|
||||
for (j = 0; j < 2; j++)
|
||||
@@ -740,25 +731,27 @@ static void HWR_PrecacheLevelTextures(void)
|
||||
{
|
||||
const INT32 texnum = sidetex[f];
|
||||
|
||||
if (texnum < 0 || texnum >= (signed)gl_numtextures)
|
||||
if (texnum <= 0 || (unsigned)texnum >= gl_numtextures)
|
||||
continue;
|
||||
|
||||
if (texturepresent[texnum])
|
||||
continue;
|
||||
if (!(texturepresent[texnum] & 1))
|
||||
{
|
||||
texturepresent[texnum] |= 1;
|
||||
HWR_GetTexture(texnum, false);
|
||||
}
|
||||
#ifdef GLENCORE
|
||||
texturepresent[texnum] = 1|noencoremap;
|
||||
#else
|
||||
texturepresent[texnum] = 1;
|
||||
#endif
|
||||
HWR_GetTexture(texnum, false);
|
||||
#ifdef GLENCORE
|
||||
if (noencoremap & 2)
|
||||
if (noencoremap
|
||||
&& !(texturepresent[texnum] & 2))
|
||||
{
|
||||
texturepresent[texnum] |= 2;
|
||||
HWR_GetTexture(texnum, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for animated textures
|
||||
for (anim = anims; anim < lastanim; anim++)
|
||||
{
|
||||
if (!anim->istexture)
|
||||
@@ -777,6 +770,7 @@ static void HWR_PrecacheLevelTextures(void)
|
||||
{
|
||||
HWR_GetTexture(animtexnum, false);
|
||||
}
|
||||
|
||||
#ifdef GLENCORE
|
||||
if (texpresent & 2)
|
||||
{
|
||||
@@ -898,7 +892,7 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore)
|
||||
GLMapTexture_t *gltex;
|
||||
GLMipmap_t *glMipmap;
|
||||
|
||||
if (tex < 0 || tex >= (signed)gl_numtextures)
|
||||
if (tex < 0 || (unsigned)tex >= gl_numtextures)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
I_Error("HWR_GetTexture: Invalid texture ID %d", tex);
|
||||
@@ -998,7 +992,7 @@ static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum)
|
||||
const char *flatname = W_CheckNameForNum(flatlumpnum);
|
||||
|
||||
// hack for gba rainbow roads cyan floors
|
||||
if (UNLIKELY(memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
|
||||
if (UNLIKELY(flatname && memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
|
||||
{
|
||||
glMipmap->flags &= ~TF_CHROMAKEYED;
|
||||
}
|
||||
@@ -1314,6 +1308,7 @@ void HWR_SetPalette(RGBA_t *palette)
|
||||
crushed_palette[i].s.blue = (UINT8)(fblue / 31.0f * 255.0f);
|
||||
crushed_palette[i].s.alpha = 255;
|
||||
}
|
||||
|
||||
GL_SetScreenPalette(crushed_palette);
|
||||
}
|
||||
else
|
||||
@@ -1391,6 +1386,7 @@ void HWR_SetMapPalette(void)
|
||||
I_Error("HWR_SetMapPalette: A programmer assumed palette lumps are at least 768 bytes long, but apparently this was a wrong assumption!\n");
|
||||
|
||||
RGB_data = (UINT8 *)(W_CacheLumpNum(lumpnum, PU_CACHE));
|
||||
|
||||
// we got the RGB palette now, but we need it in RGBA format.
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
@@ -1399,6 +1395,7 @@ void HWR_SetMapPalette(void)
|
||||
RGBA_converted[i].s.blue = *(RGB_data++);
|
||||
RGBA_converted[i].s.alpha = 255;
|
||||
}
|
||||
|
||||
palette = RGBA_converted;
|
||||
}
|
||||
|
||||
@@ -1406,6 +1403,7 @@ void HWR_SetMapPalette(void)
|
||||
if (memcmp(mapPalette, palette, sizeof(mapPalette)))
|
||||
{
|
||||
memcpy(mapPalette, palette, sizeof(mapPalette));
|
||||
|
||||
// in palette rendering mode, this means that all rgba textures now have wrong colors
|
||||
// and the lookup table is outdated
|
||||
HWR_SetPaletteLookup(mapPalette);
|
||||
|
||||
+121
-81
@@ -514,7 +514,7 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg, extracolormap_t *colo
|
||||
const INT16 offset = (cv_glfakecontrast.value == 2) ? seg->hwLightOffset : ((INT16)seg->lightOffset * 8);
|
||||
|
||||
finallight += offset;
|
||||
finallight = CLAMP(finallight, 0 , 255);
|
||||
finallight = CLAMP(finallight, 0, 255);
|
||||
}
|
||||
|
||||
return (FUINT)finallight;
|
||||
@@ -532,7 +532,7 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope, const sector_t
|
||||
const INT16 offset = (cv_glfakecontrast.value == 2) ? slope->hwLightOffset : ((INT16)slope->lightOffset * 8);
|
||||
|
||||
finallight += (fof ? -offset : offset);
|
||||
finallight = CLAMP(finallight, 0 , 255);
|
||||
finallight = CLAMP(finallight, 0, 255);
|
||||
}
|
||||
|
||||
return (FUINT)finallight;
|
||||
@@ -610,7 +610,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
||||
fflatsize = 1024.0f;
|
||||
flatflag = 1023;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
case 262144: // 512x512 lump
|
||||
fflatsize = 512.0f;
|
||||
flatflag = 511;
|
||||
break;
|
||||
@@ -721,7 +721,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
||||
|
||||
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false);
|
||||
|
||||
if (gl_maphashorizonlines && subsector && cv_glhorizonlines.value)
|
||||
if (gl_maphashorizonlines && subsector && !FOFsector && cv_glhorizonlines.value)
|
||||
{
|
||||
// Horizon lines
|
||||
FOutVector horizonpts[6];
|
||||
@@ -742,7 +742,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
||||
|
||||
line_t* ld = line->linedef;
|
||||
|
||||
// this check sucks and is a hotspot lel
|
||||
if (LIKELY(ld->special != HORIZONSPECIAL))
|
||||
continue;
|
||||
|
||||
@@ -1101,8 +1100,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
|
||||
// Found a break
|
||||
// The heights are clamped to ensure the polygon doesn't cross itself.
|
||||
bot = std::clamp(bheight, realbot, top);
|
||||
endbot = std::clamp(endbheight, endrealbot, endtop);
|
||||
bot = std::min(std::max(bheight, realbot), top);
|
||||
endbot = std::min(std::max(endbheight, endrealbot), endtop);
|
||||
|
||||
Surf->PolyColor.s.alpha = alpha;
|
||||
|
||||
@@ -1236,50 +1235,48 @@ static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf)
|
||||
// Returns true if the midtexture is visible, and false if... it isn't...
|
||||
static inline boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
|
||||
{
|
||||
FUINT blendmode = PF_Masked | PF_Translucent;
|
||||
FUINT blendmode = PF_Masked;
|
||||
|
||||
pSurf->PolyColor.s.alpha = 0xFF;
|
||||
|
||||
if (LIKELY(!gl_curline->polyseg))
|
||||
{
|
||||
// check if linedef alpha is within range
|
||||
const boolean linealpha = (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT);
|
||||
// check if linedef alpha is within range
|
||||
const boolean linealpha = (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT);
|
||||
|
||||
// set alpha for transparent walls
|
||||
switch (gl_linedef->special)
|
||||
{
|
||||
// Translucent linedef types
|
||||
case 102:
|
||||
case 121 ... 125:
|
||||
case 141 ... 145:
|
||||
case 174:
|
||||
case 175:
|
||||
case 192:
|
||||
case 195:
|
||||
case 221:
|
||||
case 253:
|
||||
case 256:
|
||||
if (gl_linedef->blendmode && linealpha)
|
||||
// set alpha for transparent walls
|
||||
switch (gl_linedef->special)
|
||||
{
|
||||
// Translucent linedef types
|
||||
case 102:
|
||||
case 121 ... 125:
|
||||
case 141 ... 145:
|
||||
case 174:
|
||||
case 175:
|
||||
case 192:
|
||||
case 195:
|
||||
case 221:
|
||||
case 253:
|
||||
case 256:
|
||||
if (gl_linedef->blendmode && linealpha)
|
||||
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
|
||||
else
|
||||
blendmode = PF_Translucent;
|
||||
break;
|
||||
default:
|
||||
if (gl_linedef->blendmode)
|
||||
{
|
||||
if (linealpha)
|
||||
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
|
||||
else
|
||||
blendmode = PF_Translucent;
|
||||
break;
|
||||
default:
|
||||
if (gl_linedef->blendmode)
|
||||
{
|
||||
if (linealpha)
|
||||
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
|
||||
else
|
||||
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
|
||||
}
|
||||
else if (linealpha)
|
||||
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
|
||||
else
|
||||
blendmode = PF_Masked;
|
||||
break;
|
||||
}
|
||||
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
|
||||
}
|
||||
else if (linealpha)
|
||||
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
|
||||
else
|
||||
blendmode = PF_Masked;
|
||||
break;
|
||||
}
|
||||
else if (gl_curline->polyseg->translucency > 0)
|
||||
|
||||
if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0)
|
||||
{
|
||||
// Polyobject translucency is shared between all of its lines
|
||||
if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
|
||||
@@ -1386,7 +1383,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
// two sided line
|
||||
if (gl_backsector)
|
||||
{
|
||||
INT32 gl_toptexture = 0, gl_bottomtexture = 0;
|
||||
const INT32 gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture);
|
||||
const INT32 gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
|
||||
|
||||
fixed_t texturevpeg;
|
||||
|
||||
@@ -1397,7 +1395,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
if (!gl_curline->polyseg) // Don't do it for polyobjects
|
||||
{
|
||||
// Sky Ceilings
|
||||
wallVerts[3].y = wallVerts[2].y = FLOATMAX;
|
||||
wallVerts[2].y = wallVerts[3].y = FLOATMAX; // draw to top of map space
|
||||
|
||||
auto draw_sky_walls = []
|
||||
(int vert1, int vert2, fixed_t world, fixed_t worldslope, auto& wwallVerts, auto& sSurf) FUNCINLINE
|
||||
@@ -1407,6 +1405,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
HWR_DrawSkyWall(wwallVerts, &sSurf);
|
||||
};
|
||||
|
||||
// worldtop = front ceiling
|
||||
// worldhigh = back ceiling
|
||||
|
||||
if (gl_frontsector->ceilingpic == skyflatnum)
|
||||
{
|
||||
if (gl_backsector->ceilingpic == skyflatnum)
|
||||
@@ -1425,6 +1426,17 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
worldtop = worldhigh;
|
||||
worldtopslope = worldhighslope;
|
||||
}
|
||||
else if (!gl_toptexture &&
|
||||
(worldhigh <= worldtop && worldhighslope <= worldtopslope) && // Assuming ESLOPE is always on with my changes
|
||||
(worldhigh != worldtop || worldhighslope != worldtopslope))
|
||||
{
|
||||
// Only the frontsector is sky.
|
||||
// If there's no upper texture, extend the sky wall
|
||||
// down to the lower of the two ceilings.
|
||||
fixed_t top = std::min(worldtop, worldhigh);
|
||||
fixed_t topslope = std::min(worldtopslope, worldhighslope);
|
||||
draw_sky_walls(0, 1, top, topslope, wallVerts, Surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only the frontsector is sky, just draw a skywall from the front ceiling
|
||||
@@ -1437,8 +1449,11 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
draw_sky_walls(0, 1, worldtop, worldtopslope, wallVerts, Surf);
|
||||
}
|
||||
|
||||
// worldbottom = front floor
|
||||
// worldlow = back floor
|
||||
|
||||
// Sky Floors
|
||||
wallVerts[0].y = wallVerts[1].y = FLOATMIN;
|
||||
wallVerts[0].y = wallVerts[1].y = FLOATMIN; // draw to bottom of map space
|
||||
|
||||
if (gl_frontsector->floorpic == skyflatnum)
|
||||
{
|
||||
@@ -1450,7 +1465,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
if ((worldlow >= worldbottom && worldlowslope >= worldbottomslope)
|
||||
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
|
||||
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
|
||||
&& !(gl_sidedef->bottomtexture))
|
||||
&& !(gl_bottomtexture))
|
||||
{
|
||||
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
|
||||
}
|
||||
@@ -1461,15 +1476,25 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
draw_sky_walls(3, 2, worldbottom, worldbottomslope, wallVerts, Surf);
|
||||
}
|
||||
}
|
||||
else if ((gl_backsector->floorpic == skyflatnum) && !(gl_sidedef->bottomtexture))
|
||||
else if ((gl_backsector->floorpic == skyflatnum) && !(gl_bottomtexture))
|
||||
{
|
||||
// Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture
|
||||
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
|
||||
}
|
||||
else if (gl_frontsector->ceilingpic == skyflatnum &&
|
||||
gl_backsector->ceilingpic == skyflatnum &&
|
||||
(worldlow >= worldbottom && worldlowslope >= worldbottomslope)
|
||||
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
|
||||
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
|
||||
&& !(gl_bottomtexture))
|
||||
{
|
||||
// Both ceilings are sky, but neither floor is sky.
|
||||
// If there's a lower wall gap without a bottom texture,
|
||||
// draw a skywall from the backsector's higher floor.
|
||||
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
|
||||
}
|
||||
}
|
||||
|
||||
gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture);
|
||||
|
||||
// check TOP TEXTURE
|
||||
if (gl_toptexture && (worldhighslope < worldtopslope || worldhigh < worldtop))
|
||||
{
|
||||
@@ -1533,8 +1558,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
||||
}
|
||||
|
||||
gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
|
||||
|
||||
// check BOTTOM TEXTURE
|
||||
if (gl_bottomtexture && (worldlowslope > worldbottomslope || worldlow > worldbottom))
|
||||
{
|
||||
@@ -2306,7 +2329,7 @@ static inline void DoAddLine(seg_t* line, angle_t angle1, angle_t angle2)
|
||||
// Find the other side!
|
||||
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, -1);
|
||||
|
||||
if (line->linedef == &lines[line2])
|
||||
if (line2 >= 0 && line->linedef == &lines[line2])
|
||||
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, line2);
|
||||
|
||||
if (line2 >= 0) // found it!
|
||||
@@ -2662,11 +2685,13 @@ static void HWR_AddPolyObjectPlanes(void)
|
||||
|
||||
polyobjsector = po_ptrs[i]->lines[0]->backsector; // the in-level polyobject sector
|
||||
|
||||
if (polyobjsector->floorheight <= gl_frontsector->ceilingheight
|
||||
&& polyobjsector->floorheight >= gl_frontsector->floorheight
|
||||
&& (viewz < polyobjsector->floorheight))
|
||||
if (polyobjsector->floorheight <= gl_frontsector->ceilingheight &&
|
||||
polyobjsector->floorheight >= gl_frontsector->floorheight &&
|
||||
(viewz < polyobjsector->floorheight))
|
||||
{
|
||||
light = R_GetPlaneLight(gl_frontsector, polyobjsector->floorheight, true);
|
||||
const INT16 llevel = (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel);
|
||||
extracolormap_t *colmap = (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap);
|
||||
|
||||
if (po_ptrs[i]->translucency > 0)
|
||||
{
|
||||
@@ -2674,22 +2699,24 @@ static void HWR_AddPolyObjectPlanes(void)
|
||||
FBITFIELD blendmode;
|
||||
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
|
||||
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight,
|
||||
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap));
|
||||
llevel, Surf.PolyColor.s.alpha, polyobjsector, blendmode, colmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum, R_NoEncore(polyobjsector, false));
|
||||
HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude,
|
||||
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum,
|
||||
polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap));
|
||||
llevel, levelflats[polyobjsector->floorpic].lumpnum,
|
||||
polyobjsector, 255, colmap);
|
||||
}
|
||||
}
|
||||
|
||||
if (polyobjsector->ceilingheight >= gl_frontsector->floorheight
|
||||
&& polyobjsector->ceilingheight <= gl_frontsector->ceilingheight
|
||||
&& (viewz > polyobjsector->ceilingheight))
|
||||
if (polyobjsector->ceilingheight >= gl_frontsector->floorheight &&
|
||||
polyobjsector->ceilingheight <= gl_frontsector->ceilingheight &&
|
||||
(viewz > polyobjsector->ceilingheight))
|
||||
{
|
||||
light = R_GetPlaneLight(gl_frontsector, polyobjsector->ceilingheight, true);
|
||||
const INT16 llevel = (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel);
|
||||
extracolormap_t *colmap = (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap);
|
||||
|
||||
if (po_ptrs[i]->translucency > 0)
|
||||
{
|
||||
@@ -2697,14 +2724,14 @@ static void HWR_AddPolyObjectPlanes(void)
|
||||
FBITFIELD blendmode;
|
||||
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
|
||||
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], true, polyobjsector->ceilingheight,
|
||||
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap));
|
||||
llevel, Surf.PolyColor.s.alpha, polyobjsector, blendmode, colmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum, R_NoEncore(polyobjsector, true));
|
||||
HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
|
||||
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->ceilingpic].lumpnum,
|
||||
polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap));
|
||||
llevel, levelflats[polyobjsector->ceilingpic].lumpnum,
|
||||
polyobjsector, 255, colmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2958,7 +2985,7 @@ static void HWR_Subsector(size_t num)
|
||||
}
|
||||
else
|
||||
{
|
||||
HWR_GetFlat(flatlump, R_NoEncore(gl_frontsector, !bottom));
|
||||
HWR_GetFlat(flatlump, R_NoEncore(rover->master->frontsector, bottom));
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, underside);
|
||||
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], !bottom, roverheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, flatlump,
|
||||
@@ -3235,6 +3262,18 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
|
||||
if (!spr->mobj)
|
||||
return;
|
||||
|
||||
// Ceiling scenery have no shadow.
|
||||
if ((spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) == (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY))
|
||||
return;
|
||||
|
||||
// Debris have no corona or shadow.
|
||||
if (spr->mobj->flags2 & MF2_DEBRIS)
|
||||
return;
|
||||
|
||||
// Without this, your shadow shows on the floor, even after you die and fall through the ground.
|
||||
if (spr->mobj->z < spr->mobj->floorz)
|
||||
return;
|
||||
|
||||
R_GetShadowZ(spr->mobj, &floorslope);
|
||||
|
||||
mobjfloor = HWR_OpaqueFloorAtPos(
|
||||
@@ -3444,8 +3483,12 @@ static inline void HWR_ApplyDispoffset(gl_vissprite_t *spr, FOutVector *wallVert
|
||||
{
|
||||
HWR_RotateSpritePolyToAim(spr, wallVerts, false, papersprite);
|
||||
|
||||
const float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
|
||||
const float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
|
||||
const float f_xdiff = (spr->x1 - gl_viewx);
|
||||
const float f_ydiff = (spr->z1 - gl_viewy);
|
||||
const float f_zdiff = (spr->gzt - gl_viewz);
|
||||
|
||||
const float sprdist = sqrtf((f_xdiff*f_xdiff) + (f_ydiff*f_ydiff) + (f_zdiff*f_zdiff));
|
||||
const float distfact = ((2.0f * spr->dispoffset) + 20.0f) / sprdist;
|
||||
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -3495,10 +3538,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
hwrpatch = static_cast<GLPatch_t *>(gpatch->hardware);
|
||||
|
||||
// Draw shadow BEFORE sprite
|
||||
if (UNLIKELY(cv_shadow.value // Shadows enabled
|
||||
&& (sprmo->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
|
||||
&& !(sprmo->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
|
||||
&& (sprmo->z >= sprmo->floorz))) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
|
||||
if (UNLIKELY(cv_shadow.value))
|
||||
{
|
||||
////////////////////
|
||||
// SHADOW SPRITE! //
|
||||
@@ -3708,7 +3748,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
|
||||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false); // sprite shader
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
|
||||
|
||||
top = bot;
|
||||
endtop = endbot;
|
||||
@@ -3735,7 +3775,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
|
||||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false); // sprite shader
|
||||
HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
@@ -3824,10 +3864,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||
}
|
||||
|
||||
// Draw shadow BEFORE sprite
|
||||
if (UNLIKELY(cv_shadow.value // Shadows enabled
|
||||
&& (sprmo->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
|
||||
&& !(sprmo->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
|
||||
&& (sprmo->z >= sprmo->floorz))) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
|
||||
if (UNLIKELY(cv_shadow.value))
|
||||
{
|
||||
////////////////////
|
||||
// SHADOW SPRITE! //
|
||||
@@ -4277,7 +4314,10 @@ static void HWR_RenderDrawNodes(void)
|
||||
gl_frontsector = NULL;
|
||||
|
||||
if (!(plane->blend & PF_NoTexture))
|
||||
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, plane->isceiling));
|
||||
{
|
||||
const boolean ceiling = plane->FOFSector ? !plane->isceiling : plane->isceiling; // match software!
|
||||
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, ceiling));
|
||||
}
|
||||
|
||||
HWR_RenderPlane(NULL, plane->xsub, plane->isceiling, plane->fixedheight, plane->blend, plane->lightlevel,
|
||||
plane->lumpnum, plane->FOFSector, plane->alpha, plane->planecolormap);
|
||||
@@ -6115,7 +6155,7 @@ static boolean HWR_WipeCheck(UINT8 wipenum, UINT8 scrnnum)
|
||||
}
|
||||
|
||||
// puts the numbers into the lumpname
|
||||
sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
|
||||
snprintf(&lumpname[4], sizeof(lumpname) - 4, "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
|
||||
wipelumpnum = W_CheckNumForName(lumpname);
|
||||
|
||||
// again, shouldn't be here really
|
||||
|
||||
@@ -1146,8 +1146,8 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
|
||||
// Look at HWR_ProjectSprite for more
|
||||
{
|
||||
md2_t *md2s;
|
||||
int skinnum;
|
||||
md2_t *md2s = NULL;
|
||||
int skinnum = 0;
|
||||
patch_t *gpatch, *blendgpatch;
|
||||
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
|
||||
INT32 durs = spr->mobj->state->tics;
|
||||
@@ -1221,7 +1221,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
skinnum = (skin_t *)spr->mobj->localskin - skins;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (spr->mobj->skin)
|
||||
{
|
||||
md2s = md2_playermodels;
|
||||
skinnum = (skin_t *)spr->mobj->skin - skins;
|
||||
@@ -1247,7 +1247,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
if (!md2->model)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "Loading model... (%s, %s)", sprnames[spr->mobj->sprite], md2->filename);
|
||||
sprintf(filename, "mdls/%s", md2->filename);
|
||||
snprintf(filename, sizeof(filename), "mdls/%s", md2->filename);
|
||||
md2->model = md2_readModel(filename);
|
||||
|
||||
if (md2->model)
|
||||
@@ -1483,7 +1483,7 @@ void HWR_Draw2DModel(md2_t *md2, INT32 x, INT32 y, INT32 skinnum, skincolors_t c
|
||||
{
|
||||
char filename[64];
|
||||
CONS_Debug(DBG_RENDER, "Loading model... (%s)\n", md2->filename);
|
||||
sprintf(filename, "mdls/%s", md2->filename);
|
||||
snprintf(filename, sizeof(filename), "mdls/%s", md2->filename);
|
||||
md2->model = md2_readModel(filename);
|
||||
|
||||
if (md2->model)
|
||||
|
||||
@@ -275,13 +275,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
return NULL;
|
||||
|
||||
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, NULL);
|
||||
|
||||
//size_t fileLen;
|
||||
|
||||
//int i, j;
|
||||
|
||||
//size_t namelen;
|
||||
//char *texturefilename;
|
||||
texPos = strchr(fileName, '/');
|
||||
|
||||
if (texPos)
|
||||
@@ -318,8 +311,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
retModel->numMeshes = 1; // MD2 only has one mesh
|
||||
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, NULL);
|
||||
retModel->meshes[0].numFrames = header->numFrames;
|
||||
// const float WUNITS = 1.0f;
|
||||
// float dataScale = WUNITS;
|
||||
|
||||
// Tris and ST are simple structures that can be straight-copied
|
||||
tris = (md2triangle_t*)&buffer[header->offsetTris];
|
||||
@@ -355,47 +346,6 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
retModel->materials[t].specular[3] = 1.0f;
|
||||
retModel->materials[t].shininess = 0.0f;
|
||||
retModel->materials[t].spheremap = false;
|
||||
|
||||
/* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE);
|
||||
|
||||
if (!systemSucks)
|
||||
{
|
||||
// Check for a normal map...??
|
||||
char openfilename[1024];
|
||||
char normalMapName[1024];
|
||||
strcpy(normalMapName, texturefilename);
|
||||
size_t len = strlen(normalMapName);
|
||||
char *ptr = &normalMapName[len];
|
||||
ptr--; // z
|
||||
ptr--; // u
|
||||
ptr--; // b
|
||||
ptr--; // .
|
||||
*ptr++ = '_';
|
||||
*ptr++ = 'n';
|
||||
*ptr++ = '.';
|
||||
*ptr++ = 'b';
|
||||
*ptr++ = 'u';
|
||||
*ptr++ = 'z';
|
||||
*ptr++ = '\0';
|
||||
|
||||
sprintf(openfilename, "%s/%s", "textures", normalMapName);
|
||||
// Convert backslashes to forward slashes
|
||||
for (int k = 0; k < 1024; k++)
|
||||
{
|
||||
if (openfilename[k] == '\0')
|
||||
break;
|
||||
|
||||
if (openfilename[k] == '\\')
|
||||
openfilename[k] = '/';
|
||||
}
|
||||
|
||||
Resource::resource_t *res = Resource::Open(openfilename);
|
||||
if (res)
|
||||
{
|
||||
Resource::Close(res);
|
||||
retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
retModel->meshes[0].numTriangles = header->numTris;
|
||||
@@ -425,15 +375,11 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
md2frame_t *framePtr = (md2frame_t*)ptr;
|
||||
retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short) * 3 * header->numXYZ, ztag, NULL);
|
||||
retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char) * 3 * header->numXYZ, ztag, NULL);
|
||||
|
||||
// if (retModel->materials[0].lightmap)
|
||||
// retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag);
|
||||
retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, NULL);
|
||||
|
||||
vertptr = retModel->meshes[0].tinyframes[i].vertices;
|
||||
normptr = retModel->meshes[0].tinyframes[i].normals;
|
||||
|
||||
// tanptr = retModel->meshes[0].tinyframes[i].tangents;
|
||||
retModel->meshes[0].tinyframes[i].material = &retModel->materials[0];
|
||||
|
||||
framePtr++; // Advance to vertex list
|
||||
@@ -509,9 +455,7 @@ model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
md2frame_t *framePtr = (md2frame_t*)ptr;
|
||||
retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, NULL);
|
||||
retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, NULL);
|
||||
// if (retModel->materials[0].lightmap)
|
||||
// retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag);
|
||||
//float *vertptr, *normptr;
|
||||
|
||||
normptr = (float*)retModel->meshes[0].frames[i].normals;
|
||||
vertptr = (float*)retModel->meshes[0].frames[i].vertices;
|
||||
trisPtr = tris;
|
||||
|
||||
@@ -243,48 +243,6 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
mdShader[j].name[len-1] = 'z';
|
||||
mdShader[j].name[len-2] = 'u';
|
||||
mdShader[j].name[len-3] = 'b';
|
||||
|
||||
// Load material
|
||||
/* retModel->materials[matCount].texture = Texture::ReadTexture(mdShader[j].name, ZT_TEXTURE);
|
||||
|
||||
if (!systemSucks)
|
||||
{
|
||||
// Check for a normal map...??
|
||||
char openfilename[1024];
|
||||
char normalMapName[1024];
|
||||
strcpy(normalMapName, mdShader[j].name);
|
||||
len = strlen(normalMapName);
|
||||
char *ptr = &normalMapName[len];
|
||||
ptr--; // z
|
||||
ptr--; // u
|
||||
ptr--; // b
|
||||
ptr--; // .
|
||||
*ptr++ = '_';
|
||||
*ptr++ = 'n';
|
||||
*ptr++ = '.';
|
||||
*ptr++ = 'b';
|
||||
*ptr++ = 'u';
|
||||
*ptr++ = 'z';
|
||||
*ptr++ = '\0';
|
||||
|
||||
sprintf(openfilename, "%s/%s", "textures", normalMapName);
|
||||
// Convert backslashes to forward slashes
|
||||
for (int k = 0; k < 1024; k++)
|
||||
{
|
||||
if (openfilename[k] == '\0')
|
||||
break;
|
||||
|
||||
if (openfilename[k] == '\\')
|
||||
openfilename[k] = '/';
|
||||
}
|
||||
|
||||
Resource::resource_t *res = Resource::Open(openfilename);
|
||||
if (res)
|
||||
{
|
||||
Resource::Close(res);
|
||||
retModel->materials[matCount].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
retModel->meshes[i].numFrames = mdS->numFrames;
|
||||
@@ -305,19 +263,15 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
{
|
||||
short *vertptr;
|
||||
char *normptr;
|
||||
// char *tanptr;
|
||||
int k;
|
||||
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
|
||||
retModel->meshes[i].tinyframes[j].vertices = (short*)Z_Malloc(sizeof(short)*3*mdS->numVerts, ztag, NULL);
|
||||
retModel->meshes[i].tinyframes[j].normals = (char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag, NULL);
|
||||
|
||||
// if (retModel->materials[0].lightmap)
|
||||
// retModel->meshes[i].tinyframes[j].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag);
|
||||
retModel->meshes[i].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * mdS->numTriangles, ztag, NULL);
|
||||
vertptr = retModel->meshes[i].tinyframes[j].vertices;
|
||||
normptr = retModel->meshes[i].tinyframes[j].normals;
|
||||
|
||||
// tanptr = retModel->meshes[i].tinyframes[j].tangents;
|
||||
retModel->meshes[i].tinyframes[j].material = &retModel->materials[i];
|
||||
|
||||
for (k = 0; k < mdS->numVerts; k++)
|
||||
@@ -384,8 +338,7 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
|
||||
retModel->meshes[i].frames[j].vertices = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, NULL);
|
||||
retModel->meshes[i].frames[j].normals = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, NULL);
|
||||
// if (retModel->materials[i].lightmap)
|
||||
// retModel->meshes[i].frames[j].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag);
|
||||
|
||||
vertptr = retModel->meshes[i].frames[j].vertices;
|
||||
normptr = retModel->meshes[i].frames[j].normals;
|
||||
retModel->meshes[i].frames[j].material = &retModel->materials[i];
|
||||
@@ -471,37 +424,6 @@ model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
// Tags?
|
||||
retModel->numTags = mdh->numTags;
|
||||
retModel->maxNumFrames = mdh->numFrames;
|
||||
retModel->tags = (tag_t*)Z_Calloc(sizeof(tag_t) * retModel->numTags * mdh->numFrames, ztag);
|
||||
md3Tag *mdTag = (md3Tag*)&buffer[mdh->offsetTags];
|
||||
tag_t *curTag = retModel->tags;
|
||||
for (i = 0; i < mdh->numFrames; i++)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < retModel->numTags; j++, mdTag++)
|
||||
{
|
||||
strcpys(curTag->name, mdTag->name, sizeof(curTag->name) / sizeof(char));
|
||||
curTag->transform.m[0][0] = mdTag->axis[0];
|
||||
curTag->transform.m[0][1] = mdTag->axis[1];
|
||||
curTag->transform.m[0][2] = mdTag->axis[2];
|
||||
curTag->transform.m[1][0] = mdTag->axis[3];
|
||||
curTag->transform.m[1][1] = mdTag->axis[4];
|
||||
curTag->transform.m[1][2] = mdTag->axis[5];
|
||||
curTag->transform.m[2][0] = mdTag->axis[6];
|
||||
curTag->transform.m[2][1] = mdTag->axis[7];
|
||||
curTag->transform.m[2][2] = mdTag->axis[8];
|
||||
curTag->transform.m[3][0] = mdTag->origin[0] * WUNITS;
|
||||
curTag->transform.m[3][1] = mdTag->origin[1] * WUNITS;
|
||||
curTag->transform.m[3][2] = mdTag->origin[2] * WUNITS;
|
||||
curTag->transform.m[3][3] = 1.0f;
|
||||
|
||||
Matrix::Rotate(&curTag->transform, 90.0f, &Vector::Xaxis);
|
||||
curTag++;
|
||||
}
|
||||
}*/
|
||||
|
||||
free(buffer);
|
||||
|
||||
|
||||
@@ -1931,6 +1931,7 @@ static void GenerateMipmaps(INT32 w, INT32 h, RGBA_t *tex, INT32 maxLOD, UINT32
|
||||
{
|
||||
if (samplePoint[p].s.alpha == 0)
|
||||
continue;
|
||||
|
||||
sumR += samplePoint[p].s.red;
|
||||
sumG += samplePoint[p].s.green;
|
||||
sumB += samplePoint[p].s.blue;
|
||||
@@ -3282,7 +3283,7 @@ static void GL_Framebuffer_Generate(void)
|
||||
{
|
||||
pglGenTextures(1, &framebufferobject.tex);
|
||||
pglBindTexture(GL_TEXTURE_2D, framebufferobject.tex);
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
Clamp2D(GL_TEXTURE_WRAP_S);
|
||||
|
||||
+10
-8
@@ -135,8 +135,7 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
|
||||
return n;
|
||||
}
|
||||
|
||||
static struct HMS_buffer *
|
||||
HMS_connect (const char *format, ...)
|
||||
static struct HMS_buffer *HMS_connect(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
CURL *curl;
|
||||
@@ -174,7 +173,7 @@ HMS_connect (const char *format, ...)
|
||||
if (cv_masterserver_token.string && cv_masterserver_token.string[0])
|
||||
{
|
||||
quack_token = curl_easy_escape(curl, cv_masterserver_token.string, 0);
|
||||
token_length = ( sizeof "&token="-1 )+ strlen(quack_token);
|
||||
token_length = ( sizeof "&token="-1 ) + strlen(quack_token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -186,27 +185,30 @@ HMS_connect (const char *format, ...)
|
||||
I_lock_mutex(&hms_api_mutex);
|
||||
#endif
|
||||
|
||||
seek = strlen(hms_api) + 1;/* + '/' */
|
||||
seek = strlen(hms_api) + 1; /* + '/' */
|
||||
|
||||
va_start (ap, format);
|
||||
url = malloc(seek + vsnprintf(NULL, 0, format, ap) + sizeof HMS_QUERY_VERSION - 1 + token_length + 1);
|
||||
size_t url_size = (seek + vsnprintf(NULL, 0, format, ap) +
|
||||
sizeof HMS_QUERY_VERSION - 1 +
|
||||
token_length + 1);
|
||||
url = malloc(url_size);
|
||||
va_end (ap);
|
||||
|
||||
sprintf(url, "%s/", hms_api);
|
||||
snprintf(url, seek + 1, "%s/", hms_api);
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(hms_api_mutex);
|
||||
#endif
|
||||
|
||||
va_start (ap, format);
|
||||
seek += vsprintf(&url[seek], format, ap);
|
||||
seek += vsnprintf(&url[seek], url_size - seek, format, ap);
|
||||
va_end (ap);
|
||||
|
||||
strcpy(&url[seek], HMS_QUERY_VERSION);
|
||||
seek += sizeof HMS_QUERY_VERSION - 1;
|
||||
|
||||
if (quack_token)
|
||||
sprintf(&url[seek], "&token=%s", quack_token);
|
||||
snprintf(&url[seek], url_size - seek, "&token=%s", quack_token);
|
||||
|
||||
Printf_url(url);
|
||||
|
||||
|
||||
+17
-19
@@ -154,14 +154,14 @@ void HU_LoadGraphics(void)
|
||||
for (i = 0; i < HU_FONTSIZE; i++, j++)
|
||||
{
|
||||
// cache the heads-up font for entire game execution
|
||||
sprintf(buffer, "STCFN%.3d", j);
|
||||
snprintf(buffer, sizeof(buffer), "STCFN%.3d", j);
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
hu_font[i] = NULL;
|
||||
else
|
||||
hu_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
|
||||
// tiny version of the heads-up font
|
||||
sprintf(buffer, "TNYFN%.3d", j);
|
||||
snprintf(buffer, sizeof(buffer), "TNYFN%.3d", j);
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
tny_font[i] = NULL;
|
||||
else
|
||||
@@ -188,7 +188,7 @@ void HU_LoadGraphics(void)
|
||||
for (i = 0; i < KART_FONTSIZE; i++, j++)
|
||||
{
|
||||
// cache the heads-up font for entire game execution
|
||||
sprintf(buffer, "MKFNT%.3d", j);
|
||||
snprintf(buffer, sizeof(buffer), "MKFNT%.3d", j);
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
kart_font[i] = NULL;
|
||||
else
|
||||
@@ -199,7 +199,7 @@ void HU_LoadGraphics(void)
|
||||
j = LT_FONTSTART;
|
||||
for (i = 0; i < LT_FONTSIZE; i++)
|
||||
{
|
||||
sprintf(buffer, "LTFNT%.3d", j);
|
||||
snprintf(buffer, sizeof(buffer), "LTFNT%.3d", j);
|
||||
j++;
|
||||
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
@@ -212,7 +212,7 @@ void HU_LoadGraphics(void)
|
||||
j = CRED_FONTSTART;
|
||||
for (i = 0; i < CRED_FONTSIZE; i++)
|
||||
{
|
||||
sprintf(buffer, "CRFNT%.3d", j);
|
||||
snprintf(buffer, sizeof(buffer), "CRFNT%.3d", j);
|
||||
j++;
|
||||
|
||||
if (W_CheckNumForName(buffer) == LUMPERROR)
|
||||
@@ -224,11 +224,11 @@ void HU_LoadGraphics(void)
|
||||
// cache numbers too!
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
sprintf(buffer, "STTNUM%d", i);
|
||||
snprintf(buffer, sizeof(buffer), "STTNUM%d", i);
|
||||
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
sprintf(buffer, "PINGN%d", i);
|
||||
snprintf(buffer, sizeof(buffer), "PINGN%d", i);
|
||||
pingnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
sprintf(buffer, "OPPRNK0%d", i);
|
||||
snprintf(buffer, sizeof(buffer), "OPPRNK0%d", i);
|
||||
ranknum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ void HU_LoadGraphics(void)
|
||||
// cache ping gfx:
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
sprintf(buffer, "PINGGFX%d", i+1);
|
||||
snprintf(buffer, sizeof(buffer), "PINGGFX%d", i+1);
|
||||
pinggfx[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
@@ -472,9 +472,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
||||
strlcat(msg, COM_Argv(ix + usedargs), msgspace);
|
||||
}
|
||||
|
||||
const size_t msglength = strlen(msg);
|
||||
|
||||
if (msglength > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
|
||||
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
|
||||
{
|
||||
// what we're gonna do now is check if the node exists
|
||||
// with that logic, characters 4 and 5 are our numbers:
|
||||
@@ -528,7 +526,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
||||
strlcpy(msg, newmsg, HU_MAXMSGLEN + 1);
|
||||
}
|
||||
|
||||
SendNetXCmd(XD_SAY, buf, msglength + 1 + msg-buf);
|
||||
SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf);
|
||||
}
|
||||
|
||||
/** Send a message to everyone.
|
||||
@@ -779,12 +777,11 @@ static void Got_Saycmd(const UINT8 **p, INT32 playernum)
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t msglength = strlen(msg);
|
||||
|
||||
//check for invalid characters (0x80 or above)
|
||||
{
|
||||
size_t i;
|
||||
const size_t j = msglength;
|
||||
const size_t j = strlen(msg);
|
||||
|
||||
for (i = 0; i < j; i++)
|
||||
{
|
||||
if (msg[i] & 0x80)
|
||||
@@ -831,7 +828,7 @@ static void Got_Saycmd(const UINT8 **p, INT32 playernum)
|
||||
}
|
||||
|
||||
// Handle "/me" actions, but only in messages to everyone.
|
||||
if (target == 0 && msglength > 4 && strnicmp(msg, "/me ", 4) == 0)
|
||||
if (target == 0 && strlen(msg) > 4 && strnicmp(msg, "/me ", 4) == 0)
|
||||
{
|
||||
msg += 4;
|
||||
action = true;
|
||||
@@ -2830,8 +2827,9 @@ static void HU_DrawRankings(void)
|
||||
scorelines++;
|
||||
|
||||
#if MAXPLAYERS > 16
|
||||
if (scorelines > 16)
|
||||
break; //dont draw past bottom of screen, show the best only
|
||||
// 32 Player TODO: port over and cleanup scoreboard from sat-32p/blankart
|
||||
if (scorelines >= 16)
|
||||
break; // dont draw past bottom of screen, show the best only
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,21 @@ char *I_GetUserName(void);
|
||||
*/
|
||||
INT32 I_mkdir(const char *dirname, INT32 unixright);
|
||||
|
||||
/** \brief Change current working directory
|
||||
|
||||
\param path directory path
|
||||
\return 0 on success, -1 on error
|
||||
*/
|
||||
INT32 I_ChDir(const char *path);
|
||||
|
||||
/** \brief Get current working directory
|
||||
|
||||
\param buf buffer to store path
|
||||
\param size size of buffer
|
||||
\return buf on success, NULL on error
|
||||
*/
|
||||
char *I_GetCwd(char *buf, size_t size);
|
||||
|
||||
/** \brief Find main WAD
|
||||
\return path to main WAD
|
||||
*/
|
||||
|
||||
+4
-5
@@ -213,7 +213,7 @@ static char *get_WSAErrorStr(int e)
|
||||
NULL);
|
||||
|
||||
if (!buf[0]) // provide a fallback error message if no message is available for some reason
|
||||
sprintf(buf, "Unknown error");
|
||||
snprintf(buf, sizeof(buf), "Unknown error");
|
||||
|
||||
return buf;
|
||||
}
|
||||
@@ -364,12 +364,12 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||
|
||||
if (addr == NULL)
|
||||
{
|
||||
sprintf(s, "No address");
|
||||
snprintf(s, sizeof(s), "No address");
|
||||
}
|
||||
else if (inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
|
||||
{
|
||||
e = errno;
|
||||
sprintf(s, "Unknown family type, error #%u: %s", e, strerror(e));
|
||||
snprintf(s, sizeof(s), "Unknown family type, error #%u: %s", e, strerror(e));
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if(sk->any.sa_family == AF_INET6)
|
||||
@@ -416,7 +416,7 @@ static const char *SOCK_GetBanMask(size_t ban)
|
||||
if (ban >= numbans)
|
||||
return NULL;
|
||||
|
||||
if (sprintf(s,"%d",banned[ban].mask) > 0)
|
||||
if (snprintf(s, sizeof(s), "%d",banned[ban].mask) > 0)
|
||||
return s;
|
||||
|
||||
return NULL;
|
||||
@@ -622,7 +622,6 @@ static boolean hole_punch(ssize_t c)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
#endif //ifdef HOLEPUNCH
|
||||
|
||||
|
||||
+3
-3
@@ -452,10 +452,10 @@ void A_SpawnFreshCopy(void *actor);
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#ifdef COMPAT_VANILLA
|
||||
#define NUMMOBJFREESLOTS 1024
|
||||
#else
|
||||
#ifdef PHOBOS_BUILD
|
||||
#define NUMMOBJFREESLOTS 4096 // should be sufficient
|
||||
#else
|
||||
#define NUMMOBJFREESLOTS 1024
|
||||
#endif
|
||||
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
|
||||
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
|
||||
|
||||
+41
-22
@@ -388,7 +388,7 @@ static void K_LoadSaturnHUDGraphics(void)
|
||||
skp_speedpatchesdial[3] = (patch_t *)W_CachePatchName("SP_DFRAC", PU_HUDGFX);
|
||||
skp_speedpatchesdial[4] = (patch_t *)W_CachePatchName("SP_DPERC", PU_HUDGFX);
|
||||
|
||||
sprintf(buffer, "K_DSPNMx");
|
||||
snprintf(buffer, sizeof(buffer), "K_DSPNMx");
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
buffer[7] = '0'+(i%10);
|
||||
@@ -507,7 +507,7 @@ static void K_LoadSaturnHUDGraphics(void)
|
||||
skp_speedpatchesdialclr[3] = (patch_t *)W_CachePatchName("SC_DFRAC", PU_HUDGFX);
|
||||
skp_speedpatchesdialclr[4] = (patch_t *)W_CachePatchName("SC_DPERC", PU_HUDGFX);
|
||||
|
||||
sprintf(buffer, "K_DSPNCx");
|
||||
snprintf(buffer, sizeof(buffer), "K_DSPNCx");
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
buffer[7] = '0'+(i%10);
|
||||
@@ -677,7 +677,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
kp_racefinish[5] = (patch_t *)W_CachePatchName("K_2PFINB", PU_HUDGFX);
|
||||
|
||||
// Position numbers
|
||||
sprintf(buffer, "K_POSNxx");
|
||||
snprintf(buffer, sizeof(buffer), "K_POSNxx");
|
||||
for (i = 0; i < NUMPOSNUMS; i++)
|
||||
{
|
||||
buffer[6] = '0'+i;
|
||||
@@ -688,14 +688,17 @@ void K_LoadKartHUDGraphics(void)
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buffer, "K_POSNWx");
|
||||
snprintf(buffer, sizeof(buffer), "K_POSNWx");
|
||||
for (i = 0; i < NUMWINFRAMES; i++)
|
||||
{
|
||||
buffer[7] = '0'+i;
|
||||
kp_winnernum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
sprintf(buffer, "OPPRNKxx");
|
||||
// 32 player note: there are only 16 of those!
|
||||
// so slots after this will just be missing patches!
|
||||
// but keeping like this incase of missed adjustments which might cause crashes otherwise
|
||||
snprintf(buffer, sizeof(buffer), "OPPRNKxx");
|
||||
for (i = 0; i <= MAXPLAYERS; i++)
|
||||
{
|
||||
buffer[6] = '0'+(i/10);
|
||||
@@ -703,7 +706,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
kp_facenum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
sprintf(buffer, "K_CHILIx");
|
||||
snprintf(buffer, sizeof(buffer), "K_CHILIx");
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
buffer[7] = '0'+(i+1);
|
||||
@@ -772,21 +775,21 @@ void K_LoadKartHUDGraphics(void)
|
||||
kp_kitchensink[1] = (patch_t *)W_CachePatchName("K_ISSINK", PU_HUDGFX);
|
||||
kp_sadface[1] = (patch_t *)W_CachePatchName("K_ISSAD", PU_HUDGFX);
|
||||
|
||||
sprintf(buffer, "K_ITINVx");
|
||||
snprintf(buffer, sizeof(buffer), "K_ITINVx");
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
buffer[7] = '1'+i;
|
||||
kp_invincibility[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
sprintf(buffer, "K_ITORBx");
|
||||
snprintf(buffer, sizeof(buffer), "K_ITORBx");
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
buffer[7] = '1'+i;
|
||||
kp_orbinaut[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
sprintf(buffer, "K_ISINVx");
|
||||
snprintf(buffer, sizeof(buffer), "K_ISINVx");
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
buffer[7] = '1'+i;
|
||||
@@ -794,7 +797,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
}
|
||||
|
||||
// CHECK indicators
|
||||
sprintf(buffer, "K_CHECKx");
|
||||
snprintf(buffer, sizeof(buffer), "K_CHECKx");
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
buffer[7] = '1'+i;
|
||||
@@ -802,7 +805,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
}
|
||||
|
||||
// Eggman warning numbers
|
||||
sprintf(buffer, "K_EGGNx");
|
||||
snprintf(buffer, sizeof(buffer), "K_EGGNx");
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
buffer[6] = '0'+i;
|
||||
@@ -815,7 +818,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
kp_fpview[2] = (patch_t *)W_CachePatchName("VIEWC0E0", PU_HUDGFX);
|
||||
|
||||
// Input UI Wheel
|
||||
sprintf(buffer, "K_WHEELx");
|
||||
snprintf(buffer, sizeof(buffer), "K_WHEELx");
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
buffer[7] = '0'+i;
|
||||
@@ -823,7 +826,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
}
|
||||
|
||||
// HERE COMES A NEW CHALLENGER
|
||||
sprintf(buffer, "K_CHALxx");
|
||||
snprintf(buffer, sizeof(buffer), "K_CHALxx");
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
buffer[6] = '0'+((i+1)/10);
|
||||
@@ -832,14 +835,14 @@ void K_LoadKartHUDGraphics(void)
|
||||
}
|
||||
|
||||
// Lap start animation
|
||||
sprintf(buffer, "K_LAP0x");
|
||||
snprintf(buffer, sizeof(buffer), "K_LAP0x");
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
buffer[6] = '0'+(i+1);
|
||||
kp_lapanim_lap[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
sprintf(buffer, "K_LAPFxx");
|
||||
snprintf(buffer, sizeof(buffer), "K_LAPFxx");
|
||||
for (i = 0; i < 11; i++)
|
||||
{
|
||||
buffer[6] = '0'+((i+1)/10);
|
||||
@@ -847,7 +850,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
kp_lapanim_final[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
sprintf(buffer, "K_LAPNxx");
|
||||
snprintf(buffer, sizeof(buffer), "K_LAPNxx");
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
buffer[6] = '0'+i;
|
||||
@@ -858,14 +861,14 @@ void K_LoadKartHUDGraphics(void)
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buffer, "K_LAPE0x");
|
||||
snprintf(buffer, sizeof(buffer), "K_LAPE0x");
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
buffer[7] = '0'+(i+1);
|
||||
kp_lapanim_emblem[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
|
||||
}
|
||||
|
||||
sprintf(buffer, "K_LAPH0x");
|
||||
snprintf(buffer, sizeof(buffer), "K_LAPH0x");
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
buffer[7] = '0'+(i+1);
|
||||
@@ -1974,7 +1977,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
||||
goto bademblem;
|
||||
}
|
||||
|
||||
snprintf(targettext, 9, "%i'%02i\"%02i",
|
||||
snprintf(targettext, sizeof(targettext), "%i'%02i\"%02i",
|
||||
G_TicsToMinutes(timetoreach, false),
|
||||
G_TicsToSeconds(timetoreach),
|
||||
G_TicsToCentiseconds(timetoreach));
|
||||
@@ -2294,6 +2297,11 @@ static boolean K_drawKartPositionFaces(void)
|
||||
if (pos < 0 || pos > MAXPLAYERS)
|
||||
pos = 0;
|
||||
|
||||
#if MAXPLAYERS > 16
|
||||
if (pos > 16)
|
||||
V_DrawPingNum(FACE_X+2, Y+10, V_HUDTRANS|V_SNAPTOLEFT, pos, NULL);
|
||||
else
|
||||
#endif
|
||||
// Draws the little number over the face
|
||||
V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_facenum[pos]);
|
||||
}
|
||||
@@ -2385,6 +2393,12 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
||||
INT32 pos = player->kartstuff[k_position];
|
||||
if (pos < 0 || pos > MAXPLAYERS)
|
||||
pos = 0;
|
||||
|
||||
#if MAXPLAYERS > 16
|
||||
if (pos > 16)
|
||||
V_DrawPingNum(x+2, y+10, 0, pos, NULL);
|
||||
else
|
||||
#endif
|
||||
// Draws the little number over the face
|
||||
V_DrawScaledPatch(x-5, y+6, 0, kp_facenum[pos]);
|
||||
}
|
||||
@@ -3581,6 +3595,10 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags)
|
||||
#endif
|
||||
|
||||
skin = K_GetMobjSkin(mo);
|
||||
|
||||
if (!skin)
|
||||
return;
|
||||
|
||||
minimaphead = (skinlocal ? localfacemmapprefix : facemmapprefix)[K_GetMobjSkinNum(skin, skinlocal)];
|
||||
|
||||
if (minimaphead == NULL)
|
||||
@@ -3784,6 +3802,9 @@ static void K_drawKartMinimap(void)
|
||||
|
||||
mobj_t *mobj = players[localplayers[i]].mo;
|
||||
|
||||
if (!mobj)
|
||||
continue;
|
||||
|
||||
// dont draw for no contestants
|
||||
boolean playertimedout = (mobj->health <= 0 && players[localplayers[i]].pflags & PF_TIMEOVER);
|
||||
|
||||
@@ -3808,10 +3829,8 @@ static void K_drawKartMinimap(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
const INT32 skinnum = K_GetMobjLocalSkinNum(mobj->skin, mobj->localskin, mobj->skinlocal);
|
||||
|
||||
// special case if startcolor is not the default (160 / Green)
|
||||
if (skinnum && skins[skinnum].starttranscolor != skins[0].starttranscolor)
|
||||
if (K_GetMobjSkin(mobj)->starttranscolor != skins[0].starttranscolor)
|
||||
{
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
|
||||
}
|
||||
|
||||
+201
-104
@@ -71,12 +71,11 @@ consvar_t cv_stairjank = {"stairjank", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistor
|
||||
consvar_t cv_stairjanksfx = {"stairjanksfx", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
//hardcode saltyhop mhhm
|
||||
static void saltyhop_onchange(void);
|
||||
consvar_t cv_saltyhop = {"hardcodehop", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, saltyhop_onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_saltyhop = {"hardcodehop", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_saltyhopsfx = {"hardcodehopsfx", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_saltysquish = {"hardcodehopsquish", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t saltyheight_t[] = {{FRACUNIT/4, "MIN"}, {2*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_saltyheight = {"hardcodehopheight", "1", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, saltyheight_t, saltyhop_onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_saltyheight = {"hardcodehopheight", "1", CV_FLOAT|CV_SAVE, saltyheight_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_saltyroll = {"hardcodehoproll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_squishdance = {"squishdance", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -84,23 +83,6 @@ consvar_t cv_squishdance = {"squishdance", "On", CV_SAVE, CV_OnOff, NULL, 0, NUL
|
||||
static CV_PossibleValue_t squishdancespeed_cons_t[] = {{20, "MIN"}, {280, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_squishdancespeed = {"squishdance_speed", "140", CV_SAVE, squishdancespeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static void saltyhop_onchange(void)
|
||||
{
|
||||
// reset everything when toggling saltyhop
|
||||
if (gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *player = &players[i];
|
||||
|
||||
if (!player || P_MobjWasRemoved(player->mo))
|
||||
continue;
|
||||
|
||||
memset(&player->mo->salty, 0, sizeof(player->mo->salty));
|
||||
}
|
||||
}
|
||||
|
||||
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
|
||||
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
|
||||
// franticitems is Frantic Mode items, bool
|
||||
@@ -1033,6 +1015,12 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush)
|
||||
}
|
||||
}
|
||||
|
||||
#if MAXPLAYERS > 16
|
||||
// courtesy of fickle from 1.1 battleroyale
|
||||
// battleroyale: limit how much items will scale to try to prevent shit-tier items in shit-huge netames
|
||||
pingame = min(pingame, 12);
|
||||
#endif
|
||||
|
||||
if (first != -1 && second != -1) // calculate 2nd's distance from 1st, for SPB
|
||||
{
|
||||
secondist = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x,
|
||||
@@ -1821,25 +1809,56 @@ void K_RespawnChecker(player_t *player)
|
||||
mobj_t *mo;
|
||||
angle_t newangle;
|
||||
fixed_t newx, newy, newz;
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
const fixed_t fscale = player->mo->scale;
|
||||
#else
|
||||
static const fixed_t fscale = FRACUNIT; // does NOT use scale, since this effect doesn't scale properly
|
||||
#endif
|
||||
newangle = FixedAngle(((360/8)*i)*FRACUNIT);
|
||||
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31<<FRACBITS); // does NOT use scale, since this effect doesn't scale properly
|
||||
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31<<FRACBITS);
|
||||
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * fscale);
|
||||
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * fscale);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
newz = player->mo->z + player->mo->height;
|
||||
else
|
||||
newz = player->mo->z;
|
||||
|
||||
mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
|
||||
if (mo)
|
||||
if (!P_MobjWasRemovedCompat(mo))
|
||||
{
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
mo->eflags |= MFE_VERTICALFLIP;
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
mo->angle = newangle+ANGLE_90;
|
||||
mo->momz = (8<<FRACBITS) * P_MobjFlip(player->mo);
|
||||
P_SetScale(mo, (mo->destscale = FRACUNIT));
|
||||
mo->momz = (8 * fscale) * P_MobjFlip(player->mo);
|
||||
P_SetScale(mo, (mo->destscale = fscale));
|
||||
}
|
||||
#ifndef PHOBOS_BUILD
|
||||
// vanilla compat really is annoying.......
|
||||
// but this stuff is messed up on mobjscaled maps
|
||||
// and we gotta respawn it locally to avoid desynchs...
|
||||
if (mapobjectscale != FRACUNIT)
|
||||
{
|
||||
// hide the normal lazers!
|
||||
mo->flags2 |= MF2_DONTDRAW;
|
||||
|
||||
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * player->mo->scale);
|
||||
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * player->mo->scale);
|
||||
|
||||
// now spawn our local lazers
|
||||
mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
|
||||
if (!P_MobjWasRemovedCompat(mo))
|
||||
{
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
mo->eflags |= MFE_VERTICALFLIP;
|
||||
P_SetTarget(&mo->target, player->mo);
|
||||
mo->angle = newangle+ANGLE_90;
|
||||
mo->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo);
|
||||
P_SetScale(mo, (mo->destscale = player->mo->scale));
|
||||
|
||||
mo->islocal = true; // Keep this local!
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2188,7 +2207,7 @@ static void K_GetKartBoostPower(player_t *player)
|
||||
|
||||
// Technically, all mobjs that think can cause desynchs if they are spawned conditionally, so best we can do
|
||||
// is to hide them if you are in saltyhop jump
|
||||
if (dust && player->mo->salty.jump)
|
||||
if (dust && player->salty.jump)
|
||||
dust->flags2 |= MF2_DONTDRAW;
|
||||
|
||||
if (leveltime % 6 == 0)
|
||||
@@ -3217,10 +3236,8 @@ static void K_SpawnDriftSparks(player_t *player)
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
fixed_t driftExtraScale = 0;
|
||||
|
||||
angle_t thrustangle = (travelangle + ((i&1) ? -1 : 1)*ANGLE_135);
|
||||
fixed_t smolscale = FixedMul(32*FRACUNIT, player->mo->scale);
|
||||
const angle_t thrustangle = (travelangle + ((i&1) ? -1 : 1)*ANGLE_135);
|
||||
const fixed_t smolscale = FixedMul(32*FRACUNIT, player->mo->scale);
|
||||
|
||||
newx = player->mo->x + P_ReturnThrustX(player->mo, thrustangle, smolscale);
|
||||
newy = player->mo->y + P_ReturnThrustY(player->mo, thrustangle, smolscale);
|
||||
@@ -3232,9 +3249,9 @@ static void K_SpawnDriftSparks(player_t *player)
|
||||
spark->angle = travelangle-(ANGLE_45/5)*player->kartstuff[k_drift];
|
||||
|
||||
// scale increase while driftspark level gained timer is running
|
||||
driftExtraScale = FixedDiv(player->driftsparkGrowTimer, DRIFTSPARKGROWTICS);
|
||||
const fixed_t driftExtraScale = FixedDiv(player->driftsparkGrowTimer, DRIFTSPARKGROWTICS);
|
||||
spark->destscale = FixedMul(player->mo->scale, FRACUNIT + FixedMul(driftExtraScale, cv_driftsparkpulse.value));
|
||||
P_SetScale(spark, spark->destscale); // why not use what we calculated above?
|
||||
P_SetScale(spark, spark->destscale);
|
||||
|
||||
spark->momx = player->mo->momx/2;
|
||||
spark->momy = player->mo->momy/2;
|
||||
@@ -3326,10 +3343,10 @@ static void K_StretchPlayerGravity(player_t *player)
|
||||
|
||||
mobj_t *pmo = player->mo;
|
||||
|
||||
fixed_t tempxscale = pmo->realxscale;
|
||||
fixed_t tempyscale = pmo->realyscale;
|
||||
const fixed_t tempxscale = pmo->realxscale;
|
||||
const fixed_t tempyscale = pmo->realyscale;
|
||||
|
||||
stretchScaleFactor = FixedDiv(FRACUNIT*60, cv_gravstretch.value);
|
||||
stretchScaleFactor = FixedDiv(mapobjectscale*60, cv_gravstretch.value);
|
||||
stretchScaleFactor = min(stretchScaleFactor, MAXSTRETCHDIV);
|
||||
|
||||
if (pmo->slamsoundtimer)
|
||||
@@ -3337,26 +3354,26 @@ static void K_StretchPlayerGravity(player_t *player)
|
||||
|
||||
if (!P_IsObjectOnGround(pmo))
|
||||
{
|
||||
fixed_t pzmom = abs(pmo->momz);
|
||||
const fixed_t pzmom = abs(pmo->momz);
|
||||
const fixed_t stretchDiv = FixedDiv(pzmom, stretchScaleFactor);
|
||||
|
||||
if (abs(pzmom/FRACUNIT) != 0)
|
||||
if (abs(pzmom/mapobjectscale) != 0)
|
||||
{
|
||||
if (((tempxscale-(stretchDiv))) > (tempxscale/5))
|
||||
if ((tempxscale - stretchDiv) > (tempxscale / 5))
|
||||
{
|
||||
pmo->spritexscale = (tempxscale - stretchDiv);
|
||||
pmo->stretchslam = pzmom;
|
||||
}
|
||||
else
|
||||
pmo->spritexscale = (tempxscale/5);
|
||||
pmo->spritexscale = (tempxscale / 5);
|
||||
|
||||
pmo->spriteyscale = (tempyscale + ((stretchDiv*2)/3));
|
||||
pmo->spriteyscale = (tempyscale + ((stretchDiv * 2) / 3));
|
||||
}
|
||||
}
|
||||
else if (pmo->stretchslam > 0)
|
||||
{
|
||||
// Funni slam sound when landing
|
||||
if (cv_slamsound.value && (pmo->eflags & MFE_JUSTHITFLOOR) && !pmo->slamsoundtimer && (pmo->stretchslam > 4*FRACUNIT))
|
||||
if (cv_slamsound.value && (pmo->eflags & MFE_JUSTHITFLOOR) && !pmo->slamsoundtimer && (pmo->stretchslam > 4*mapobjectscale))
|
||||
{
|
||||
S_StartSound(pmo, sfx_s3k4c);
|
||||
pmo->slamsoundtimer = TICRATE;
|
||||
@@ -3364,9 +3381,9 @@ static void K_StretchPlayerGravity(player_t *player)
|
||||
|
||||
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, stretchScaleFactor);
|
||||
|
||||
pmo->spritexscale = (tempxscale + (((slamDiv*2)/3)*2));
|
||||
pmo->spritexscale = (tempxscale + (((slamDiv * 2) / 3 ) * 2));
|
||||
pmo->spriteyscale = (tempyscale - slamDiv);
|
||||
pmo->stretchslam -= (4*FRACUNIT);
|
||||
pmo->stretchslam -= (4*mapobjectscale);
|
||||
}
|
||||
else
|
||||
pmo->stretchslam = 0;
|
||||
@@ -3381,16 +3398,16 @@ static void K_SaltySquish(player_t *player)
|
||||
|
||||
mobj_t *pmo = player->mo;
|
||||
|
||||
fixed_t tempxscale = pmo->realxscale;
|
||||
fixed_t tempyscale = pmo->realyscale;
|
||||
const fixed_t tempxscale = pmo->realxscale;
|
||||
const fixed_t tempyscale = pmo->realyscale;
|
||||
|
||||
if (pmo->stretchslam > 0)
|
||||
{
|
||||
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, FRACUNIT*60); // stretchScaleFactor = FixedDiv(FRACUNIT*60, FRACUNIT)
|
||||
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, mapobjectscale*60); // stretchScaleFactor = FixedDiv(mapobjectscale*60, FRACUNIT)
|
||||
|
||||
pmo->spritexscale = (tempxscale + (((slamDiv*2)/3)*2));
|
||||
pmo->spritexscale = (tempxscale + (((slamDiv * 2) / 3) * 2));
|
||||
pmo->spriteyscale = (tempyscale - slamDiv);
|
||||
pmo->stretchslam -= (4*FRACUNIT);
|
||||
pmo->stretchslam -= (4*mapobjectscale);
|
||||
}
|
||||
else
|
||||
pmo->stretchslam = 0;
|
||||
@@ -3398,88 +3415,92 @@ static void K_SaltySquish(player_t *player)
|
||||
|
||||
static void K_QuiteSaltyHop(player_t *player)
|
||||
{
|
||||
if (!cv_saltyhop.value)
|
||||
return;
|
||||
I_Assert(player != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(player->mo));
|
||||
|
||||
// what the fuck is this haya
|
||||
mobj_t *pmo = player->mo;
|
||||
salty_t *psalt = &pmo->salty;
|
||||
salty_t *psalty = &player->salty;
|
||||
|
||||
if (!cv_saltyhop.value)
|
||||
{
|
||||
// reset before we leave
|
||||
psalty->jump = psalty->ready = psalty->tapping = false;
|
||||
psalty->momz = psalty->zoffset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const boolean onground = P_IsObjectOnGround(pmo);
|
||||
|
||||
// ready?
|
||||
if (!player->kartstuff[k_jmp])
|
||||
{
|
||||
psalt->ready = true;
|
||||
psalt->tapping = false;
|
||||
psalty->ready = true;
|
||||
psalty->tapping = false;
|
||||
}
|
||||
else if (psalt->ready)
|
||||
else if (psalty->ready)
|
||||
{
|
||||
psalt->ready = false;
|
||||
psalt->tapping = true;
|
||||
psalty->ready = false;
|
||||
psalty->tapping = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
psalt->tapping = false;
|
||||
psalty->tapping = false;
|
||||
}
|
||||
|
||||
// GO!
|
||||
if (!psalt->init)
|
||||
{
|
||||
psalt->jump = false;
|
||||
psalt->zoffset = 0;
|
||||
psalt->momz = 0;
|
||||
psalt->init = true;
|
||||
}
|
||||
else if (psalt->jump)
|
||||
if (psalty->jump)
|
||||
{
|
||||
if (pmo->eflags & MFE_JUSTHITFLOOR)
|
||||
{
|
||||
psalt->zoffset = 0;
|
||||
psalty->zoffset = 0;
|
||||
}
|
||||
else if (onground)
|
||||
{
|
||||
psalt->zoffset += psalt->momz;
|
||||
psalt->momz -= (FRACUNIT*3/2);
|
||||
psalty->zoffset += psalty->momz;
|
||||
psalty->momz -= (FRACUNIT*3/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
psalt->zoffset *= (49/50)*FRACUNIT;
|
||||
psalt->momz = 0;
|
||||
//psalty->zoffset *= (49/50)*FRACUNIT; // this just rounds down to 0 lol
|
||||
psalty->zoffset = 0;
|
||||
psalty->momz = 0;
|
||||
}
|
||||
|
||||
if (psalt->zoffset <= 0)
|
||||
if (psalty->zoffset <= 0)
|
||||
{
|
||||
if (cv_saltyhopsfx.value && !(pmo->eflags & MFE_JUSTHITFLOOR) && onground)
|
||||
S_StartSound(pmo, sfx_s268);
|
||||
psalt->jump = false;
|
||||
psalt->zoffset = 0;
|
||||
psalt->momz = 0;
|
||||
psalty->jump = false;
|
||||
psalty->zoffset = 0;
|
||||
psalty->momz = 0;
|
||||
// shlamma damma
|
||||
if (cv_saltysquish.value)
|
||||
pmo->stretchslam += 8*FRACUNIT;
|
||||
pmo->stretchslam += 8*mapobjectscale;
|
||||
}
|
||||
else if (cv_saltysquish.value && psalt->zoffset >= 0)
|
||||
else if (psalty->zoffset > 0)
|
||||
{
|
||||
// goofy ahh hack
|
||||
pmo->spriteyscale += (FRACUNIT/8);
|
||||
pmo->spritexscale -= (FRACUNIT/8);
|
||||
if (cv_saltysquish.value)
|
||||
{
|
||||
// goofy ahh hack
|
||||
pmo->spriteyscale += (FRACUNIT/8);
|
||||
pmo->spritexscale -= (FRACUNIT/8);
|
||||
}
|
||||
}
|
||||
|
||||
pmo->spriteyoffset += FixedMul(psalt->zoffset, cv_saltyheight.value);
|
||||
pmo->spriteyoffset += FixedMul(psalty->zoffset, cv_saltyheight.value);
|
||||
|
||||
if (cv_saltyhopsfx.value)
|
||||
{
|
||||
if (S_SoundPlaying(pmo, sfx_screec))
|
||||
S_StopSoundByID(pmo, sfx_screec);
|
||||
if (S_SoundPlaying(pmo, sfx_drift))
|
||||
S_StopSoundByID(pmo, sfx_drift);
|
||||
}
|
||||
// Stop any and all drift sounds when hopping.
|
||||
if (S_SoundPlaying(pmo, sfx_screec))
|
||||
S_StopSoundByID(pmo, sfx_screec);
|
||||
if (S_SoundPlaying(pmo, sfx_drift))
|
||||
S_StopSoundByID(pmo, sfx_drift);
|
||||
}
|
||||
else if (psalt->tapping && onground && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer])
|
||||
else if (psalty->tapping && onground && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer])
|
||||
{
|
||||
psalt->jump = true;
|
||||
psalt->zoffset = 0;
|
||||
psalt->momz = 6*FRACUNIT;
|
||||
psalty->jump = true;
|
||||
psalty->zoffset = 0;
|
||||
psalty->momz = 6*FRACUNIT;
|
||||
if (cv_saltyhopsfx.value)
|
||||
S_StartSound(pmo, sfx_s25a);
|
||||
}
|
||||
@@ -3506,7 +3527,7 @@ boolean K_ShouldSlopeRoll(mobj_t *mobj)
|
||||
return false;
|
||||
|
||||
// seeing a character rotate mid-hop looks really janky
|
||||
if (!cv_saltyroll.value && mobj->player && mobj->player->mo->salty.jump)
|
||||
if (!cv_saltyroll.value && mobj->player && mobj->player->salty.jump)
|
||||
return false;
|
||||
|
||||
return K_CheckSlopeRollDist(mobj);
|
||||
@@ -3718,7 +3739,7 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
|
||||
dust = P_SpawnMobj(rand_x, rand_y, mo->z, MT_WIPEOUTTRAIL);
|
||||
|
||||
P_SetTarget(&dust->target, mo);
|
||||
dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy);
|
||||
dust->angle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
dust->destscale = mo->scale;
|
||||
P_SetScale(dust, mo->scale);
|
||||
K_FlipFromObject(dust, mo);
|
||||
@@ -3744,6 +3765,11 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
|
||||
void K_DriftDustHandling(mobj_t *spawner)
|
||||
{
|
||||
angle_t anglediff;
|
||||
#ifdef PHOBOS_BUILD
|
||||
const fixed_t fscale = spawner->scale;
|
||||
#else
|
||||
static const fixed_t fscale = FRACUNIT; // should be spawner->scale but the below calls P_Random!
|
||||
#endif
|
||||
|
||||
if (leveltime % 2 != 0 || !P_IsObjectOnGround(spawner))
|
||||
return;
|
||||
@@ -3760,7 +3786,7 @@ void K_DriftDustHandling(mobj_t *spawner)
|
||||
{
|
||||
angle_t playerangle = spawner->angle;
|
||||
|
||||
if (spawner->player->speed < 5<<FRACBITS)
|
||||
if (spawner->player->speed < (5 * fscale))
|
||||
return;
|
||||
|
||||
if (spawner->player->cmd.forwardmove < 0)
|
||||
@@ -3771,7 +3797,7 @@ void K_DriftDustHandling(mobj_t *spawner)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (P_AproxDistance(spawner->momx, spawner->momy) < 5<<FRACBITS)
|
||||
if (P_AproxDistance(spawner->momx, spawner->momy) < (5 * fscale))
|
||||
return;
|
||||
|
||||
anglediff = abs((signed)(spawner->angle - R_PointToAngle2(0, 0, spawner->momx, spawner->momy)));
|
||||
@@ -3784,13 +3810,29 @@ void K_DriftDustHandling(mobj_t *spawner)
|
||||
|
||||
if (anglediff > ANG10*4) // Trying to turn further than 40 degrees
|
||||
{
|
||||
mobj_t *dust = NULL;
|
||||
|
||||
fixed_t spawnx = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
|
||||
fixed_t spawny = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
|
||||
INT32 speedrange = 2;
|
||||
mobj_t *dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
|
||||
dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
|
||||
dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
|
||||
dust->momz = P_MobjFlip(spawner) * (P_RandomRange(1, 4) * (spawner->scale));
|
||||
|
||||
dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
|
||||
|
||||
const INT32 momxrand = P_RandomRange(-speedrange, speedrange);
|
||||
const INT32 momyrand = P_RandomRange(-speedrange, speedrange);
|
||||
const INT32 momzrand = P_RandomRange(1, 4);
|
||||
|
||||
if (P_MobjWasRemovedCompat(dust))
|
||||
return;
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
dust->momx = FixedMul(spawner->momx + (momxrand * spawner->scale), 3*FRACUNIT/4);
|
||||
dust->momy = FixedMul(spawner->momy + (momyrand * spawner->scale), 3*FRACUNIT/4);
|
||||
#else
|
||||
dust->momx = FixedMul(spawner->momx + (momxrand<<FRACBITS), 3*(spawner->scale)/4);
|
||||
dust->momy = FixedMul(spawner->momy + (momyrand<<FRACBITS), 3*(spawner->scale)/4);
|
||||
#endif
|
||||
dust->momz = P_MobjFlip(spawner) * (momzrand * (spawner->scale));
|
||||
P_SetScale(dust, spawner->scale/2);
|
||||
dust->destscale = spawner->scale * 3;
|
||||
dust->scalespeed = spawner->scale/12;
|
||||
@@ -3799,6 +3841,33 @@ void K_DriftDustHandling(mobj_t *spawner)
|
||||
S_StartSound(spawner, sfx_screec);
|
||||
|
||||
K_MatchGenericExtraFlags(dust, spawner);
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
// vanilla compat really is annoying.......
|
||||
// but this stuff is messed up on mobjscaled maps
|
||||
// and we gotta respawn it locally to avoid desynchs...
|
||||
if (mapobjectscale != FRACUNIT)
|
||||
{
|
||||
// hide the normal dust!
|
||||
dust->flags2 |= MF2_DONTDRAW;
|
||||
|
||||
// now spawn our dust locally
|
||||
dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
|
||||
|
||||
if (P_MobjWasRemovedCompat(dust))
|
||||
return;
|
||||
|
||||
dust->momx = FixedMul(spawner->momx + (momxrand * spawner->scale), 3*FRACUNIT/4);
|
||||
dust->momy = FixedMul(spawner->momy + (momyrand * spawner->scale), 3*FRACUNIT/4);
|
||||
dust->momz = P_MobjFlip(spawner) * (momzrand * (spawner->scale));
|
||||
P_SetScale(dust, spawner->scale/2);
|
||||
dust->destscale = spawner->scale * 3;
|
||||
dust->scalespeed = spawner->scale/12;
|
||||
dust->islocal = true; // Keep this local!
|
||||
|
||||
K_MatchGenericExtraFlags(dust, spawner);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4331,7 +4400,6 @@ static void K_DoShrink(player_t *user)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
|
||||
{
|
||||
if (mo->player && mo->player->spectator)
|
||||
@@ -4394,8 +4462,7 @@ void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source)
|
||||
mobj_t *cachenext;
|
||||
|
||||
killnext:
|
||||
|
||||
if (!banana)
|
||||
if (P_MobjWasRemovedCompat(banana))
|
||||
return;
|
||||
|
||||
cachenext = banana->hnext;
|
||||
@@ -4434,10 +4501,21 @@ void K_UpdateHnextList(player_t *player, boolean clean)
|
||||
nextwork = work->hnext;
|
||||
|
||||
if (!clean && (!work->movedir || work->movedir <= (UINT16)player->kartstuff[k_itemamount]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
P_RemoveMobj(work);
|
||||
}
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
if (P_MobjWasRemoved(player->mo->hnext))
|
||||
{
|
||||
// Like below, try to clean up the pointer if it's NULL.
|
||||
// Maybe this was a cause of the shrink/eggbox fails?
|
||||
P_SetTarget(&player->mo->hnext, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// For getting hit!
|
||||
@@ -4502,7 +4580,9 @@ void K_DropHnextList(player_t *player)
|
||||
}
|
||||
|
||||
dropwork = P_SpawnMobj(work->x, work->y, work->z, type);
|
||||
|
||||
P_SetTarget(&dropwork->target, player->mo);
|
||||
|
||||
dropwork->angle = work->angle;
|
||||
dropwork->flags2 = work->flags2;
|
||||
dropwork->flags |= MF_NOCLIPTHING;
|
||||
@@ -4570,10 +4650,13 @@ void K_DropHnextList(player_t *player)
|
||||
|
||||
// we need this here too because this is done in afterthink - pointers are cleaned up at the START of each tic...
|
||||
P_SetTarget(&player->mo->hnext, NULL);
|
||||
|
||||
player->kartstuff[k_bananadrag] = 0;
|
||||
|
||||
if (player->kartstuff[k_eggmanheld])
|
||||
{
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
}
|
||||
else if (player->kartstuff[k_itemheld]
|
||||
&& (dropall || (--player->kartstuff[k_itemamount] <= 0)))
|
||||
{
|
||||
@@ -4874,7 +4957,9 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
player->kartstuff[k_bananadrag] = 0;
|
||||
|
||||
if (player->kartstuff[k_eggmanheld])
|
||||
{
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
}
|
||||
else if (player->kartstuff[k_itemheld])
|
||||
{
|
||||
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
|
||||
@@ -4891,7 +4976,9 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
player->kartstuff[k_bananadrag] = 0;
|
||||
|
||||
if (player->kartstuff[k_eggmanheld])
|
||||
{
|
||||
player->kartstuff[k_eggmanheld] = 0;
|
||||
}
|
||||
else if (player->kartstuff[k_itemheld])
|
||||
{
|
||||
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
|
||||
@@ -4907,7 +4994,12 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
case MT_JAWZ_SHIELD:
|
||||
{
|
||||
mobj_t *cur = player->mo->hnext;
|
||||
fixed_t speed = ((8 - min(4, player->kartstuff[k_itemamount])) * cur->info->speed) / 7;
|
||||
fixed_t speed = 0;
|
||||
|
||||
if (cur == NULL)
|
||||
return;
|
||||
|
||||
speed = ((8 - min(4, player->kartstuff[k_itemamount])) * cur->info->speed) / 7;
|
||||
|
||||
player->kartstuff[k_bananadrag] = 0; // Just to make sure
|
||||
|
||||
@@ -4954,8 +5046,13 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
cur->flags &= ~MF_NOCLIPTHING;
|
||||
|
||||
if (!P_TryMove(cur, player->mo->x + cur->momx, player->mo->y + cur->momy, true))
|
||||
{
|
||||
P_SlideMove(cur, true);
|
||||
|
||||
if (P_MobjWasRemovedCompat(cur))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (P_MobjFlip(cur) > 0)
|
||||
|
||||
@@ -3087,6 +3087,8 @@ static int lib_gPlayerDeviceRumble(lua_State *L)
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
if (demo.playback) return 0;
|
||||
|
||||
pnum = P_GetLocalPlayerNumForPlayer(player);
|
||||
|
||||
// Not a local player
|
||||
|
||||
@@ -182,14 +182,19 @@ void COM_Lua_f(void)
|
||||
len = (argc+1)*256;
|
||||
|
||||
buf = malloc(len);
|
||||
if (buf == NULL)
|
||||
I_Error("Failed to allocate buffer for COM_Lua_f");
|
||||
|
||||
p = buf;
|
||||
WRITEUINT8(p, argc);
|
||||
for (i = 0; i < argc; i++)
|
||||
WRITESTRINGN(p, COM_Argv(i), 255);
|
||||
if (flags & 2)
|
||||
|
||||
if (flags & COM_SPLITSCREEN)
|
||||
SendNetXCmdForPlayer(1, XD_LUACMD, buf, p-buf);
|
||||
else
|
||||
SendNetXCmd(XD_LUACMD, buf, p-buf);
|
||||
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
+56
-11
@@ -25,6 +25,7 @@
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hook.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_profile.h"
|
||||
|
||||
/* =========================================================================
|
||||
ABSTRACTION
|
||||
@@ -445,11 +446,54 @@ FUNCINLINE static ATTRINLINE void get_hook_from_table(Hook_State *hook, int n)
|
||||
lua_getref(gL, hookRefs[hook->id]);
|
||||
}
|
||||
|
||||
static int pcall(Hook_State *hook)
|
||||
{
|
||||
return lua_pcall(gL, hook->values, hook->results, EINDEX);
|
||||
}
|
||||
|
||||
static const char *hook_name(Hook_State *hook)
|
||||
{
|
||||
if (hud_running)
|
||||
{
|
||||
return hudHookNames[hook->hook_type];
|
||||
}
|
||||
else if (hook->string)
|
||||
{
|
||||
return stringHookNames[hook->hook_type];
|
||||
}
|
||||
//else if (hook->mobj_type > 0)
|
||||
else if (hook->mobj_type != NONMOHOOK)
|
||||
{
|
||||
return mobjHookNames[hook->hook_type];
|
||||
}
|
||||
else
|
||||
{
|
||||
return hookNames[hook->hook_type];
|
||||
}
|
||||
}
|
||||
|
||||
static int pcall_timed_or_untimed(Hook_State *hook)
|
||||
{
|
||||
if (!hud_running && cv_lua_profile.value > 0)
|
||||
{
|
||||
lua_timer_t *timer = LUA_BeginFunctionTimer(gL, -1 - hook->values, hook_name(hook));
|
||||
int k = pcall(hook);
|
||||
LUA_EndFunctionTimer(timer);
|
||||
|
||||
return k;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pcall(hook);
|
||||
}
|
||||
}
|
||||
|
||||
static int call_single_hook_no_copy(Hook_State *hook)
|
||||
{
|
||||
hook_important = hook->important;
|
||||
|
||||
if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0)
|
||||
//if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0)
|
||||
if (pcall_timed_or_untimed(hook) == 0)
|
||||
{
|
||||
if (hook->results > 0)
|
||||
{
|
||||
@@ -535,16 +579,16 @@ FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype
|
||||
static UINT8 seen = 0; // so we dont have to check all this shit constantly
|
||||
int numCalls = call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
|
||||
|
||||
if (!seen && numCalls > 0 && mobj_type == MT_NULL && (
|
||||
hook->hook_type == MOBJ_HOOK(MobjThinker )
|
||||
if (!seen && numCalls > 0 && mobj_type == MT_NULL &&
|
||||
( hook->hook_type == MOBJ_HOOK(MobjThinker )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjCollide )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjMoveCollide)
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjFuse )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjThinker )
|
||||
|| hook->hook_type == MOBJ_HOOK(BossThinker )
|
||||
))
|
||||
{
|
||||
seen = 1;
|
||||
|
||||
CONS_Alert(
|
||||
CONS_WARNING, "%s\n", va(
|
||||
"%s hooks not attached to a specific mobj type may cause performance issues!",
|
||||
@@ -566,12 +610,10 @@ FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype
|
||||
return numCalls;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
|
||||
/*FUNCINLINE static ATTRINLINE int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
|
||||
{
|
||||
return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
|
||||
}
|
||||
*/
|
||||
}*/
|
||||
|
||||
static int call_hooks
|
||||
(
|
||||
@@ -760,7 +802,7 @@ static void hook_think_frame(int type)
|
||||
const hook_t * map = &hookIds[type];
|
||||
int k;
|
||||
|
||||
const boolean perfstats = (cv_perfstats.value >= 3);
|
||||
const boolean perfstats = (cv_perfstats.value >= PS_THINKFRAME);
|
||||
|
||||
if (prepare_hook(&hook, 0, type))
|
||||
{
|
||||
@@ -856,7 +898,7 @@ int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT3
|
||||
int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
{
|
||||
return damage_hook(target, inflictor, source, damage,
|
||||
MOBJ_HOOK(MobjDamage), res_true);
|
||||
MOBJ_HOOK(MobjDamage), res_true);
|
||||
}
|
||||
|
||||
int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
@@ -945,7 +987,7 @@ void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
|
||||
{
|
||||
Hook_State hook = {};
|
||||
if (prepare_string_hook
|
||||
(&hook, 0, STRING_HOOK(LinedefExecute), line->text))
|
||||
(&hook, 0, STRING_HOOK(LinedefExecute), line->text))
|
||||
{
|
||||
LUA_PushUserdata(gL, line, META_LINE);
|
||||
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||
@@ -1018,6 +1060,9 @@ void LUA_HookNetArchive(lua_CFunction archFunc, savebuffer_t *save)
|
||||
lua_pushcclosure(gL, archFunc, 2);
|
||||
// stack: tables, savebuffer_t, archFunc
|
||||
|
||||
// Manually set the hook's variables here since we don't call prepare_hook
|
||||
hook.hook_type = HOOK(NetVars);
|
||||
hook.mobj_type = NONMOHOOK; // Force mobj_type to be NONMOHOOK so the mobj_type check get skipped
|
||||
init_hook_call(&hook, 0, res_none);
|
||||
call_mapped(&hook, map);
|
||||
|
||||
|
||||
+5
-1
@@ -22,7 +22,8 @@
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // cmd errors
|
||||
#include "lua_hook.h" // hook_cmd_running errors
|
||||
#include "lua_profile.h"
|
||||
|
||||
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
|
||||
state_t *astate = NULL;
|
||||
@@ -110,7 +111,10 @@ static void A_Lua(mobj_t *actor)
|
||||
LUA_PushUserdata(gL, actor, META_MOBJ);
|
||||
lua_pushinteger(gL, var1);
|
||||
lua_pushinteger(gL, var2);
|
||||
|
||||
lua_timer_t *timer = LUA_BeginFunctionTimer(gL, -4, "A_Lua");
|
||||
LUA_Call(gL, 3, 0, 1);
|
||||
LUA_EndFunctionTimer(timer);
|
||||
|
||||
lua_pop(gL, 1); // pop error handler
|
||||
|
||||
|
||||
@@ -0,0 +1,264 @@
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by James Robert Roman
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "screen.h"
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
#include "blua/lua.h"
|
||||
};
|
||||
|
||||
#include "v_video.h"
|
||||
|
||||
#include "command.h"
|
||||
#include "doomtype.h"
|
||||
#include "i_system.h"
|
||||
#include "lua_profile.h"
|
||||
#include "m_perfstats.h"
|
||||
|
||||
extern "C" consvar_t cv_lua_profile;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
precise_t g_time_reference;
|
||||
int g_tics_counted;
|
||||
|
||||
double g_running_tic_time;
|
||||
double g_avg_tic_time;
|
||||
|
||||
bool g_invalid;
|
||||
|
||||
}; // namespace
|
||||
|
||||
struct lua_timer_t
|
||||
{
|
||||
struct Stat
|
||||
{
|
||||
double calls = 0;
|
||||
double time = 0.0;
|
||||
};
|
||||
|
||||
Stat running, avg;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::unordered_map<std::string, lua_timer_t> g_tic_timers;
|
||||
|
||||
}; // namespace
|
||||
|
||||
lua_timer_t* LUA_BeginFunctionTimer(lua_State* L, int fn_idx, const char* name)
|
||||
{
|
||||
lua_Debug ar;
|
||||
|
||||
lua_pushvalue(L, fn_idx);
|
||||
lua_getinfo(L, ">S", &ar);
|
||||
|
||||
auto label = [&]
|
||||
{
|
||||
using sv = std::string_view;
|
||||
sv view{ar.source};
|
||||
|
||||
switch (view.front())
|
||||
{
|
||||
case '@': // file
|
||||
if (std::size_t p = view.rfind('/'); p != sv::npos) // lump or base
|
||||
{
|
||||
return view.substr(p + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case '=': // ??
|
||||
view.remove_prefix(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
// i sure hope this std::string mess is fine...
|
||||
auto [it, ins] = g_tic_timers.try_emplace(std::string(va("%s:%d (%s)", std::string(label()).c_str(), ar.linedefined, name)));
|
||||
auto& [key, timer] = *it;
|
||||
|
||||
g_time_reference = I_GetPreciseTime();
|
||||
|
||||
return &timer;
|
||||
}
|
||||
|
||||
void LUA_EndFunctionTimer(lua_timer_t* timer)
|
||||
{
|
||||
precise_t t = I_GetPreciseTime() - g_time_reference;
|
||||
double precision = I_GetPrecisePrecision();
|
||||
|
||||
timer->running.time += t / precision;
|
||||
timer->running.calls += 1.0;
|
||||
}
|
||||
|
||||
void LUA_ResetTicTimers(void)
|
||||
{
|
||||
if (cv_lua_profile.value <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_tics_counted < cv_lua_profile.value)
|
||||
{
|
||||
g_tics_counted++;
|
||||
|
||||
double precision = I_GetPrecisePrecision();
|
||||
g_running_tic_time += ps_prevtictime.value.p / precision;
|
||||
}
|
||||
else
|
||||
{
|
||||
double counted = g_tics_counted;
|
||||
|
||||
for (auto& [key, timer] : g_tic_timers)
|
||||
{
|
||||
timer.avg = {timer.running.calls / counted, timer.running.time / counted};
|
||||
timer.running = {};
|
||||
}
|
||||
|
||||
g_avg_tic_time = g_running_tic_time / counted;
|
||||
g_running_tic_time = 0.0;
|
||||
|
||||
g_tics_counted = 1;
|
||||
|
||||
g_invalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LUA_RenderTimers(void)
|
||||
{
|
||||
constexpr int kRowHeight = 4;
|
||||
float row_y = kRowHeight;
|
||||
|
||||
// pretty much what the whole srb2::Draw does lol
|
||||
auto draw_row = [](float x, float y, INT32 flags, const char *str)
|
||||
{
|
||||
V_DrawSmallStringAtFixed(
|
||||
FloatToFixed(x),
|
||||
FloatToFixed(y),
|
||||
V_MONOSPACE|V_ALLOWLOWERCASE|flags,
|
||||
str
|
||||
);
|
||||
};
|
||||
|
||||
draw_row(0.f, 0.f, 0, va("-- AVERAGES PER TIC (over %d tics) --", cv_lua_profile.value));
|
||||
|
||||
if (g_invalid)
|
||||
{
|
||||
draw_row(0.f, row_y, V_GRAYMAP, " <Data pending>");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<decltype(g_tic_timers)::iterator> view;
|
||||
view.reserve(g_tic_timers.size());
|
||||
|
||||
auto color_flag = [](double t)
|
||||
{
|
||||
if (t < 10.0)
|
||||
{
|
||||
return V_GRAYMAP;
|
||||
}
|
||||
else if (t >= 100.0)
|
||||
{
|
||||
return V_YELLOWMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
double cum = 0.0;
|
||||
|
||||
for (auto it = g_tic_timers.begin(); it != g_tic_timers.end(); ++it)
|
||||
{
|
||||
auto& [key, timer] = *it;
|
||||
|
||||
cum += timer.avg.time;
|
||||
|
||||
if (timer.avg.time > 0.0)
|
||||
{
|
||||
view.push_back(it);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const INT32 tally_flags = color_flag(cum * 1'000'000.0);
|
||||
|
||||
draw_row(0.f, row_y, tally_flags, va("%8.2f us - TOTAL", cum * 1'000'000.0));
|
||||
draw_row(0.f, row_y + kRowHeight, tally_flags, va("%8.2f ms", cum * 1000.0));
|
||||
|
||||
// dont need to show this if we didnt capture over time
|
||||
// this would just show nan or inf anyways
|
||||
if (std::fpclassify(g_avg_tic_time) != FP_ZERO)
|
||||
{
|
||||
draw_row(0.f, row_y + kRowHeight * 2, tally_flags, va(
|
||||
"%8.2f%% overhead (%.2f / %.2f) <-- not counting rendering time",
|
||||
(cum / g_avg_tic_time) * 100.0,
|
||||
(cum * (double)TICRATE),
|
||||
(g_avg_tic_time * (double)TICRATE)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
row_y += kRowHeight * 4;
|
||||
}
|
||||
|
||||
std::sort(
|
||||
view.rbegin(),
|
||||
view.rend(),
|
||||
[](auto a, auto b)
|
||||
{
|
||||
auto& [k1, t1] = *a;
|
||||
auto& [k2, t2] = *b;
|
||||
return t1.avg.time < t2.avg.time;
|
||||
}
|
||||
);
|
||||
|
||||
for (auto it : view)
|
||||
{
|
||||
auto& [key, timer] = *it;
|
||||
|
||||
double t = timer.avg.time * 1'000'000.0;
|
||||
|
||||
draw_row(0.f, row_y, color_flag(t), va(
|
||||
"%8.2f us %8.2f calls - %s",
|
||||
t,
|
||||
timer.avg.calls,
|
||||
key.c_str()
|
||||
));
|
||||
|
||||
row_y += kRowHeight;
|
||||
|
||||
// FIXME this is all ugly and sucks
|
||||
if (row_y >= BASEVIDHEIGHT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void lua_profile_OnChange(void)
|
||||
{
|
||||
g_invalid = true;
|
||||
|
||||
if (cv_lua_profile.value == 0)
|
||||
{
|
||||
g_tic_timers = {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by James Robert Roman
|
||||
// Copyright (C) 2025 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef lua_profile_h
|
||||
#define lua_profile_h
|
||||
|
||||
#include "blua/lua.h"
|
||||
#include "doomtype.h"
|
||||
//#include "typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct lua_timer_t;
|
||||
typedef struct lua_timer_t lua_timer_t;
|
||||
|
||||
void LUA_ResetTicTimers(void);
|
||||
|
||||
lua_timer_t *LUA_BeginFunctionTimer(lua_State *L, int fn_idx, const char *name);
|
||||
void LUA_EndFunctionTimer(lua_timer_t *timer);
|
||||
|
||||
void LUA_RenderTimers(void);
|
||||
|
||||
void lua_profile_OnChange(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif/*lua_profile_h*/
|
||||
+25
-15
@@ -62,14 +62,6 @@ static lua_CFunction liblist[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
// Lua asks for memory using this.
|
||||
static void *LUA_Alloc(void *ud, void *ptr, size_t osize, size_t nsize)
|
||||
{
|
||||
(void)ud;
|
||||
(void)osize;
|
||||
return Z_Realloc(ptr, nsize, PU_LUA, NULL);
|
||||
}
|
||||
|
||||
// Panic function Lua calls when there's an unprotected error.
|
||||
// This function cannot return. Lua would kill the application anyway if it did.
|
||||
FUNCNORETURN static int LUA_Panic(lua_State *L)
|
||||
@@ -197,7 +189,7 @@ void LUA_ClearState(void)
|
||||
CONS_Printf(M_GetText("Pardon me while I initialize the Lua scripting interface...\n"));
|
||||
|
||||
// allocate state
|
||||
L = lua_newstate(LUA_Alloc, NULL);
|
||||
L = luaL_newstate();
|
||||
lua_atpanic(L, LUA_Panic);
|
||||
|
||||
// open base libraries
|
||||
@@ -277,20 +269,19 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
||||
|
||||
if (wadfiles[wad]->type == RET_LUA)
|
||||
{
|
||||
name = malloc(len+1);
|
||||
strcpy(name, wadfiles[wad]->filename);
|
||||
name = malloc(len + 1);
|
||||
snprintf(name, len + 1, "%s", wadfiles[wad]->filename);
|
||||
}
|
||||
else // If it's not a .lua file, copy the lump name in too.
|
||||
{
|
||||
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
|
||||
len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
|
||||
name = malloc(len+1);
|
||||
name = malloc(len + 1);
|
||||
|
||||
if (!name)
|
||||
I_Error("LUA_LoadLump: Out of memory!\n");
|
||||
|
||||
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
|
||||
name[len] = '\0';
|
||||
snprintf(name, len + 1, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
|
||||
}
|
||||
|
||||
LUA_LoadFile(&f, name); // actually load file!
|
||||
@@ -374,7 +365,7 @@ void LUA_DumpFile(const char *filename)
|
||||
|
||||
static void createMathLibState(void)
|
||||
{
|
||||
mL = lua_newstate(LUA_Alloc, NULL);
|
||||
mL = luaL_newstate();
|
||||
lua_atpanic(mL, LUA_Panic);
|
||||
|
||||
// open only enum lib
|
||||
@@ -592,6 +583,7 @@ void LUA_InvalidateLevel(void)
|
||||
|
||||
for (i = 0; i < numsubsectors; i++)
|
||||
LUA_InvalidateUserdata(&subsectors[i]);
|
||||
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(§ors[i]);
|
||||
@@ -612,6 +604,7 @@ void LUA_InvalidateLevel(void)
|
||||
|
||||
for (i = 0; i < numsides; i++)
|
||||
LUA_InvalidateUserdata(&sides[i]);
|
||||
|
||||
for (i = 0; i < numvertexes; i++)
|
||||
LUA_InvalidateUserdata(&vertexes[i]);
|
||||
|
||||
@@ -622,6 +615,10 @@ void LUA_InvalidateLevel(void)
|
||||
LUA_InvalidateUserdata(&slope->o);
|
||||
LUA_InvalidateUserdata(&slope->d);
|
||||
}
|
||||
|
||||
// We invalidated a lot of userdata objects, a lot of them probably ended up unreachable so they can be
|
||||
// GC'd right away
|
||||
lua_gc(gL, LUA_GCCOLLECT, 0);
|
||||
}
|
||||
|
||||
void LUA_InvalidateMapthings(void)
|
||||
@@ -1460,3 +1457,16 @@ int Lua_CreateFieldTable(lua_State *L, const char *const lst[])
|
||||
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
size_t LUA_MemoryUsage(void)
|
||||
{
|
||||
size_t usage = 0;
|
||||
|
||||
if (gL)
|
||||
usage += lua_gc(gL, LUA_GCCOUNT, 0);
|
||||
|
||||
if (mL)
|
||||
usage += lua_gc(mL, LUA_GCCOUNT, 0);
|
||||
|
||||
return usage;
|
||||
}
|
||||
@@ -82,6 +82,9 @@ int Lua_optoption(lua_State *L, int narg, int def, int list_ref);
|
||||
int Lua_CreateFieldTable(lua_State *L, const char *const lst[]);
|
||||
void LUA_HookNetArchive(lua_CFunction archFunc, savebuffer_t *save);
|
||||
|
||||
// Returns lua memory usage in kbytes
|
||||
size_t LUA_MemoryUsage(void);
|
||||
|
||||
// Console wrapper
|
||||
void COM_Lua_f(void);
|
||||
|
||||
|
||||
+11
-2
@@ -13,6 +13,12 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#define local_for_thread _Thread_local
|
||||
#else
|
||||
#define local_for_thread
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "command.h"
|
||||
#include "m_argv.h"
|
||||
@@ -31,8 +37,11 @@ char **myargv = NULL;
|
||||
boolean myargmalloc = false;
|
||||
|
||||
/** \brief founded the parm
|
||||
*
|
||||
* thread_local because it can potentially be used from multiple threads (global variables aaaaaa)
|
||||
* (myargc and myargv don't have to be thread_local because they are never modified after being set up)
|
||||
*/
|
||||
static INT32 found;
|
||||
static local_for_thread INT32 found;
|
||||
|
||||
|
||||
/** \brief The M_CheckParm function
|
||||
@@ -91,7 +100,7 @@ INT32 M_CheckProtoParam(const char *check)
|
||||
const char *M_GetProtoParam(void)
|
||||
{
|
||||
INT32 i;
|
||||
static char *string;
|
||||
char *string;
|
||||
|
||||
for (i = 1; i < myargc; i++)
|
||||
{
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "m_curl.h"
|
||||
#include "doomtype.h"
|
||||
#include "i_system.h" // I_OutputMsg
|
||||
#include "doomdef.h" // I_OutputMsg
|
||||
#include "m_argv.h" // M_CheckParm, M_GetNextParm
|
||||
|
||||
static boolean curl_args_init = false;
|
||||
|
||||
+186
-141
@@ -616,7 +616,7 @@ void Nextmap_OnChange(void)
|
||||
if (!gpath)
|
||||
return;
|
||||
|
||||
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
|
||||
snprintf(gpath, glen, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
|
||||
|
||||
CV_StealthSetValue(&cv_dummystaff, 0);
|
||||
|
||||
@@ -735,7 +735,7 @@ static void Dummystaff_OnChange(void)
|
||||
while (*temp)
|
||||
temp++;
|
||||
|
||||
sprintf(temp, " - %d", cv_dummystaff.value);
|
||||
snprintf(temp, sizeof(dummystaffname) - (size_t)(temp - dummystaffname), " - %d", cv_dummystaff.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -825,7 +825,8 @@ static void M_ChangeCvar(INT32 choice)
|
||||
float increment;
|
||||
|
||||
increment = FIXED_TO_FLOAT(cv->value)+(choice)*((currentMenu->menuitems[itemOn].status & IT_CV_BIGFLOAT) ? 0.5f : (1.0f/16.0f));
|
||||
sprintf(s,"%ld%s",(long)increment,M_Ftrim(increment));
|
||||
snprintf(s, sizeof(s), "%ld%s", (long)increment, M_Ftrim(increment));
|
||||
|
||||
CV_Set(cv, s);
|
||||
}
|
||||
else
|
||||
@@ -3983,6 +3984,14 @@ menudemo_t *demolist = NULL; // Replays that that have been checked to match wit
|
||||
menudemo_t *demolist_all = NULL; // All replays
|
||||
size_t demolist_all_size = 0;
|
||||
boolean replaynamesloaded = false;
|
||||
// Whenever we start a replay load thread, we increment this number and then thread will remember current value,
|
||||
// and by the end it will compare it with current value, and if it is equal it means thread can store data it has loaded.
|
||||
// If it's not equal, that means we started more than one thread (left and re-entered menu for example)
|
||||
size_t replaythreadnum = 0;
|
||||
|
||||
// for replay dates
|
||||
#include <locale.h>
|
||||
const char *demodateformat = "%d.%m.%Y";
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
I_mutex replayquerymutex;
|
||||
@@ -4012,12 +4021,15 @@ static SINT8 replayScrollDelay = TICRATE, replayScrollDir = 1;
|
||||
|
||||
static void ReplayNamesLoadThread(void* userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
Lock_search_state();
|
||||
|
||||
size_t demolist_all_size_local = demolist_all_size;
|
||||
menudemo_t *demolist_all_local = (menudemo_t*)malloc(sizeof(menudemo_t)*demolist_all_size_local);
|
||||
memcpy(demolist_all_local, demolist_all, sizeof(menudemo_t)*demolist_all_size_local);
|
||||
char *replaydirpath = (char*)userdata;
|
||||
size_t localreplaythreadnum = replaythreadnum;
|
||||
const char *localdemodateformat = demodateformat;
|
||||
|
||||
Unlock_search_state();
|
||||
|
||||
@@ -4025,19 +4037,13 @@ static void ReplayNamesLoadThread(void* userdata)
|
||||
{
|
||||
if (demolist_all_local[i].type != MD_SUBDIR)
|
||||
{
|
||||
G_LoadDemoTitle(&demolist_all_local[i]);
|
||||
|
||||
// this is fucking horrid, but i wanna be able to search for dates
|
||||
/*if (demolist_all_local[i].date[0] != '\0')
|
||||
{
|
||||
snprintf(demolist_all_local[i].title, sizeof(demolist_all_local[i].title), "%s %s", demolist_all_local[i].title, demolist_all_local[i].date);
|
||||
}*/
|
||||
G_LoadDemoTitle(&demolist_all_local[i], localdemodateformat);
|
||||
}
|
||||
}
|
||||
|
||||
Lock_search_state();
|
||||
|
||||
if (fastcmp(menupath, replaydirpath) && demolist_all)
|
||||
if (replaythreadnum == localreplaythreadnum && demolist_all)
|
||||
{
|
||||
memcpy(demolist_all, demolist_all_local, sizeof(menudemo_t)*demolist_all_size);
|
||||
replaynamesloaded = true;
|
||||
@@ -4046,22 +4052,32 @@ static void ReplayNamesLoadThread(void* userdata)
|
||||
Unlock_search_state();
|
||||
|
||||
// Was allocated before thread start, we need to free it
|
||||
free(replaydirpath);
|
||||
free(demolist_all_local);
|
||||
}
|
||||
|
||||
static void LoadReplayNames(void)
|
||||
{
|
||||
char *replaydirpath = strdup(menupath);
|
||||
|
||||
Lock_search_state();
|
||||
replaythreadnum++;
|
||||
replaynamesloaded = false;
|
||||
if (cv_demodateformat.value == 2)
|
||||
demodateformat = "%m.%d.%Y";
|
||||
else if (cv_demodateformat.value == 1)
|
||||
demodateformat = "%d.%m.%Y";
|
||||
else
|
||||
{
|
||||
// get the date format here
|
||||
// setlocale reads/writes global state
|
||||
const char *locale = setlocale(LC_TIME, NULL);
|
||||
// US ppl are special (:
|
||||
demodateformat = (locale && strstr(locale, "en_US")) ? "%m.%d.%Y" : "%d.%m.%Y";
|
||||
}
|
||||
Unlock_search_state();
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
I_spawn_thread("replay-names-load", ReplayNamesLoadThread, replaydirpath);
|
||||
I_spawn_thread("replay-names-load", ReplayNamesLoadThread, NULL);
|
||||
#else
|
||||
ReplayNamesLoadThread(replaydirpath);
|
||||
ReplayNamesLoadThread(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4100,8 +4116,12 @@ static void M_HutCheckReplays(size_t maxnum)
|
||||
// Mark as done
|
||||
replayqueryfound = replayquerycheck = sizedirmenu;
|
||||
|
||||
Lock_search_state();
|
||||
|
||||
memcpy(demolist, demolist_all, sizeof(menudemo_t) * sizedirmenu);
|
||||
|
||||
Unlock_search_state();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4185,12 +4205,12 @@ static void PrepReplayList(boolean reset)
|
||||
if (dirmenu[i][DIR_TYPE] == EXT_UP)
|
||||
{
|
||||
demolist_all[i].type = MD_SUBDIR;
|
||||
sprintf(demolist_all[i].title, "UP");
|
||||
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), "UP");
|
||||
}
|
||||
else if (dirmenu[i][DIR_TYPE] == EXT_FOLDER)
|
||||
{
|
||||
demolist_all[i].type = MD_SUBDIR;
|
||||
strncpy(demolist_all[i].title, dirmenu[i] + DIR_STRING, 64);
|
||||
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), "%s", dirmenu[i] + DIR_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4198,7 +4218,7 @@ static void PrepReplayList(boolean reset)
|
||||
snprintf(demolist_all[i].filepath, sizeof(demolist_all[i].filepath),
|
||||
// 255 = UINT8 limit. dirmenu entries are restricted to this length (see DIR_LEN).
|
||||
"%s%.255s", menupath, dirmenu[i] + DIR_STRING);
|
||||
sprintf(demolist_all[i].title, ".....");
|
||||
snprintf(demolist_all[i].title, sizeof(demolist_all[i].title), ".....");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4250,13 +4270,15 @@ static boolean M_HandleReplayHutQuery(INT32 choice)
|
||||
char tmp[MAXREPLAYQUERY+1];
|
||||
memcpy(tmp, replayqueryinput_buffer, MAXREPLAYQUERY+1);
|
||||
|
||||
Lock_search_state();
|
||||
// Honestly not sure if locks for replaynamesloaded are necessary...
|
||||
// Thread sanitizer does report race condition whenever replaynamesloaded is accessed without lock
|
||||
// but really it is only ever set to false in main thread and only set to true in replay load thread,
|
||||
// and both are done via locks. If replaynamesloaded is true, it is never gonna suddenly switch from true to false
|
||||
// while we're in main thread, and if it would switch from false to true it is not really a big deal, we will just skip
|
||||
// 1 frame where replay names were loaded
|
||||
|
||||
if (!replaynamesloaded)
|
||||
{
|
||||
Unlock_search_state();
|
||||
return false;
|
||||
}
|
||||
Unlock_search_state();
|
||||
|
||||
if (M_TextInputHandle(&replayqueryinput, choice))
|
||||
{
|
||||
@@ -5766,7 +5788,8 @@ static void M_DrawMusicTest(void)
|
||||
x = 24;
|
||||
y = 64;
|
||||
|
||||
if (renderisnewtic) st_musictime++;
|
||||
if (renderisnewtic)
|
||||
st_musictime++;
|
||||
|
||||
while (t <= b)
|
||||
{
|
||||
@@ -5775,11 +5798,11 @@ static void M_DrawMusicTest(void)
|
||||
|
||||
{
|
||||
const musicdef_t *def = S_GetMusicCredit(t);
|
||||
const size_t MAXLENGTH = 34;
|
||||
const char *songname = def->title[0] ? def->title : def->source;
|
||||
|
||||
size_t namelength = strlen(songname);
|
||||
|
||||
#define MAXLENGTH 34
|
||||
char buf[MAXLENGTH+1];
|
||||
|
||||
if (t == st_sel && namelength > MAXLENGTH)
|
||||
@@ -5788,11 +5811,14 @@ static void M_DrawMusicTest(void)
|
||||
strlcpy(buf, songname, MAXLENGTH);
|
||||
|
||||
V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE|V_MONOSPACE, buf);
|
||||
|
||||
if (curplaying == def)
|
||||
{
|
||||
V_DrawFill(20+280-9, y-4, 8, 16, 230);
|
||||
}
|
||||
#undef MAXLENGTH
|
||||
}
|
||||
|
||||
t++;
|
||||
y += 16;
|
||||
}
|
||||
@@ -5979,7 +6005,8 @@ static void M_DrawStatsMaps(void)
|
||||
|
||||
V_DrawString(20, 42, highlightflags|MENUCAPS, "Combined time records:");
|
||||
|
||||
sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime));
|
||||
snprintf(beststr, sizeof(beststr), "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime));
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, (mapsunfinished ? warningflags : 0), beststr);
|
||||
|
||||
if (mapsunfinished)
|
||||
@@ -6445,7 +6472,7 @@ static void M_ChooseTimeAttack(INT32 choice)
|
||||
else
|
||||
G_RecordDemo(nameofdemo);
|
||||
|
||||
G_DeferedInitNew(false, mapname, (UINT8)(cv_chooseskin.value-1), 0, false);
|
||||
G_DeferedInitNew(false, mapname, (skinnum_t)(cv_chooseskin.value-1), 0, false);
|
||||
}
|
||||
|
||||
static void M_HandleStaffReplay(INT32 choice)
|
||||
@@ -7146,7 +7173,7 @@ static void M_CheckMODVersion(int id)
|
||||
|
||||
if (updatecheck)
|
||||
{
|
||||
sprintf(updatestring, UPDATE_ALERT_STRING, VERSIONSTRING, updatecheck);
|
||||
snprintf(updatestring, sizeof(updatestring), UPDATE_ALERT_STRING, VERSIONSTRING, updatecheck);
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
#endif
|
||||
@@ -7644,11 +7671,8 @@ static void M_DrawMPMainMenu(void)
|
||||
// use generic drawer for cursor, items and title
|
||||
M_DrawGenericMenu();
|
||||
|
||||
#if MAXPLAYERS != 16
|
||||
Update the maxplayers label...
|
||||
#endif
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[4].alphaKey,
|
||||
((itemOn == 4) ? highlightflags : 0)|MENUCAPS, "(2-16 Players)");
|
||||
((itemOn == 4) ? highlightflags : 0)|MENUCAPS, va("(2-%d Players)", MAXPLAYERS));
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[5].alphaKey,
|
||||
((itemOn == 5) ? highlightflags : 0)|MENUCAPS,
|
||||
@@ -7664,7 +7688,7 @@ Update the maxplayers label...
|
||||
{
|
||||
char buf[28];
|
||||
strlcpy(buf, setupm_ip, sizeof(buf));
|
||||
V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, buf);
|
||||
V_DrawString(x+8, y+12, V_ALLOWLOWERCASE, buf);
|
||||
}
|
||||
else
|
||||
M_DrawTextInputScroll(x+8, y+12, &setupm_input_ip, 0, SETUPM_IP_MAXSIZE);
|
||||
@@ -7674,7 +7698,7 @@ Update the maxplayers label...
|
||||
#define iconwidth 32
|
||||
#define spacingwidth 32
|
||||
#define incrwidth (iconwidth + spacingwidth)
|
||||
UINT8 i = 0, pskin, pcol;
|
||||
UINT16 i = 0, pskin, pcol;
|
||||
// player arrangement width, but there's also a chance i'm a furry, shhhhhh
|
||||
const INT32 paw = iconwidth + 3*incrwidth;
|
||||
INT32 trans = 0;
|
||||
@@ -7927,16 +7951,16 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
patch_t *patch;
|
||||
UINT8 frame;
|
||||
UINT8 speed;
|
||||
UINT8 weight;
|
||||
UINT8 i;
|
||||
UINT8 s, w;
|
||||
UINT16 frame;
|
||||
UINT16 speed;
|
||||
UINT16 weight;
|
||||
UINT16 i;
|
||||
UINT16 s, w;
|
||||
INT32 skinnum = 0;
|
||||
INT32 statx, staty;
|
||||
UINT32 speenframe;
|
||||
INT32 sltw, actw, hetw;
|
||||
UINT8 skintodisplay;
|
||||
skinnum_t skintodisplay;
|
||||
INT32 nameboxaddy = 0;
|
||||
|
||||
const UINT8 *flashcol = V_GetStringColormap(highlightflags);
|
||||
@@ -7993,7 +8017,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
break;
|
||||
case SKINMENUTYPE_2D:
|
||||
|
||||
skintodisplay = setupm_fakeskin;
|
||||
skintodisplay = (skinnum_t)setupm_fakeskin;
|
||||
if (setupm_skinlockedselect) //show the skin we are trying to select
|
||||
skintodisplay = skinstats[setupm_skinxpos][setupm_skinypos][setupm_skinselect];
|
||||
else if (skinstatscount[setupm_skinxpos][setupm_skinypos] && itemOn == 1)
|
||||
@@ -8202,12 +8226,12 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
case SKINMENUTYPE_EXTENDED:
|
||||
for (s = 0; s < SKINGRIDNEWWIDTH*SKINGRIDNEWHEIGHT; s++)
|
||||
{
|
||||
INT32 x = ((s % SKINGRIDNEWWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDNEWWIDTH) - 8) + 100 + SKINXSHIFT; //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
INT32 y = ((s / SKINGRIDNEWWIDTH) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDNEWWIDTH/2)) + 10); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
INT32 calcs = s + (setupm_skinypos * SKINGRIDNEWWIDTH);
|
||||
INT32 skinn;
|
||||
patch_t *face;
|
||||
UINT8 *cmap;
|
||||
const INT32 x = ((s % SKINGRIDNEWWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDNEWWIDTH) - 8) + 100 + SKINXSHIFT; //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
const INT32 y = ((s / SKINGRIDNEWWIDTH) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDNEWWIDTH/2)) + 10); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
const INT32 calcs = s + (setupm_skinypos * SKINGRIDNEWWIDTH);
|
||||
|
||||
if (calcs < numskins)
|
||||
skinn = skinsorted[calcs];
|
||||
@@ -8228,10 +8252,10 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
if (itemOn == 1) //has to be on skin select part
|
||||
{
|
||||
patch_t *cursor;
|
||||
INT32 curx = (((setupm_skinselect % SKINGRIDNEWWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDNEWWIDTH/2)) + SKINXSHIFT) + 20;
|
||||
INT32 cury = (((setupm_skinselect / SKINGRIDNEWWIDTH) - setupm_skinypos) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDNEWWIDTH/2))+ 10);
|
||||
const INT32 curx = (((setupm_skinselect % SKINGRIDNEWWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDNEWWIDTH/2)) + SKINXSHIFT) + 20;
|
||||
const INT32 cury = (((setupm_skinselect / SKINGRIDNEWWIDTH) - setupm_skinypos) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDNEWWIDTH/2))+ 10);
|
||||
|
||||
UINT8 cursorframe = (I_GetTime() / 4) % 7;
|
||||
const UINT8 cursorframe = (I_GetTime() / 4) % 7;
|
||||
cursor = (patch_t *)W_CachePatchName(va("K_CHILI%d", cursorframe + 1), PU_PATCH);
|
||||
V_DrawFixedPatch((curx << FRACBITS) - (FRACUNIT), (cury << FRACBITS) - (FRACUNIT), FRACUNIT+(FRACUNIT>>3), 0, cursor, NULL);
|
||||
}
|
||||
@@ -8240,9 +8264,9 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
case SKINMENUTYPE_GRID:
|
||||
for (s = 0; s < SKINGRIDWIDTH*SKINGRIDHEIGHT; s++)
|
||||
{
|
||||
INT32 x = ((s % SKINGRIDWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDWIDTH) - 8) + 100 + SKINXSHIFT; //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
INT32 y = ((s / SKINGRIDWIDTH) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDWIDTH/2))); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
INT32 calcs = s + (setupm_skinypos * SKINGRIDWIDTH);
|
||||
const INT32 x = ((s % SKINGRIDWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDWIDTH) - 8) + 100 + SKINXSHIFT; //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
const INT32 y = ((s / SKINGRIDWIDTH) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDWIDTH/2))); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
const INT32 calcs = s + (setupm_skinypos * SKINGRIDWIDTH);
|
||||
INT16 skinn;
|
||||
patch_t *face;
|
||||
UINT8 *cmap;
|
||||
@@ -8266,36 +8290,44 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
if (itemOn == 1) //has to be on skin select part
|
||||
{
|
||||
patch_t *cursor;
|
||||
INT32 curx = (((setupm_skinselect % SKINGRIDWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDWIDTH/2)) + SKINXSHIFT) + 20;
|
||||
INT32 cury = (((setupm_skinselect / SKINGRIDWIDTH) - setupm_skinypos) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDWIDTH/2)));
|
||||
const INT32 curx = (((setupm_skinselect % SKINGRIDWIDTH) * 18) + ((BASEVIDWIDTH / 2) - (18 * SKINGRIDWIDTH/2)) + SKINXSHIFT) + 20;
|
||||
const INT32 cury = (((setupm_skinselect / SKINGRIDWIDTH) - setupm_skinypos) * 18) + ((BASEVIDHEIGHT / 2) - (18 * (SKINGRIDWIDTH/2)));
|
||||
|
||||
if (setupm_skinselect < numskins)
|
||||
{
|
||||
UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
|
||||
const UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
|
||||
cursor = facewantprefix[skinsorted[setupm_skinselect]];
|
||||
V_DrawFixedPatch(((curx-8) << FRACBITS), ((cury-8) << FRACBITS), FRACUNIT, 0, cursor, cmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 cursorframe = (I_GetTime() / 4) % 7;
|
||||
const UINT8 cursorframe = (I_GetTime() / 4) % 7;
|
||||
cursor = (patch_t *)W_CachePatchName(va("K_CHILI%d", cursorframe + 1), PU_PATCH);
|
||||
V_DrawFixedPatch((curx << FRACBITS) - (FRACUNIT), (cury << FRACBITS) - (FRACUNIT), FRACUNIT+(FRACUNIT>>3), 0, cursor, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
{ // stat dot
|
||||
INT32 selectedskin = (itemOn == 1 && setupm_skinselect < numskins ? skinsorted[setupm_skinselect] : setupm_fakeskin);
|
||||
const INT32 selectedskin = (itemOn == 1 && setupm_skinselect < numskins ? skinsorted[setupm_skinselect] : setupm_fakeskin);
|
||||
|
||||
speed = skins[selectedskin].kartspeed;
|
||||
weight = skins[selectedskin].kartweight;
|
||||
statdot = (patch_t *)W_CachePatchName("K_SDOT1", PU_PATCH);
|
||||
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
|
||||
V_DrawFixedPatch((((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1), (((staty+71) + (weight*4))<<FRACBITS), FRACUNIT>>1, 0, statdot, flashcol);
|
||||
else
|
||||
V_DrawFixedPatch((((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1), (((staty+71) + (weight*4))<<FRACBITS), FRACUNIT>>1, 0, statdot, NULL);
|
||||
|
||||
statdot = (patch_t *)W_CachePatchName("K_SDOT2", PU_PATCH); // coloured center
|
||||
const INT32 x = (((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1);
|
||||
const INT32 y = (((staty+71) + (weight*4))<<FRACBITS);
|
||||
|
||||
statdot = (patch_t *)W_CachePatchName("K_SDOT1", PU_PATCH);
|
||||
|
||||
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
|
||||
V_DrawFixedPatch(x, y, FRACUNIT>>1, 0, statdot, flashcol);
|
||||
else
|
||||
V_DrawFixedPatch(x, y, FRACUNIT>>1, 0, statdot, NULL);
|
||||
|
||||
if (setupm_fakecolor)
|
||||
V_DrawFixedPatch((((statx+46) + (speed*4))<<FRACBITS) + (FRACUNIT>>1), (((staty+71) + (weight*4))<<FRACBITS), FRACUNIT>>1, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
|
||||
{
|
||||
statdot = (patch_t *)W_CachePatchName("K_SDOT2", PU_PATCH); // coloured center
|
||||
V_DrawFixedPatch(x, y, FRACUNIT>>1, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SKINMENUTYPE_2D:
|
||||
@@ -8304,12 +8336,13 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
{
|
||||
for (w = 0; w < MAXSTAT; w++)
|
||||
{
|
||||
INT32 x = ((s * 18) + ((BASEVIDWIDTH / 2) - (18 * 4)) - 8 + SKINXSHIFT); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
INT32 y = ((w * 18) + ((BASEVIDHEIGHT / 2) - (18 * 4)) - 8); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
INT32 skinn;
|
||||
patch_t *face;
|
||||
UINT8 *cmap;
|
||||
|
||||
const INT32 x = ((s * 18) + ((BASEVIDWIDTH / 2) - (18 * 4)) - 8 + SKINXSHIFT); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
const INT32 y = ((w * 18) + ((BASEVIDHEIGHT / 2) - (18 * 4)) - 8); //BASEVIDWIDTH / 2 - ((icons + 1) * 24) - 4;
|
||||
|
||||
if (!skinstatscount[s][w])
|
||||
{
|
||||
V_DrawFill(x, y, 16, 16, 239);
|
||||
@@ -8327,20 +8360,20 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
if (itemOn == 1) //has to be on skin select part
|
||||
{
|
||||
patch_t *cursor;
|
||||
INT32 curx = ((setupm_skinxpos * 18) + ((BASEVIDWIDTH / 2) - (18 * 4)) - 8 + SKINXSHIFT);
|
||||
INT32 cury = ((setupm_skinypos * 18) + ((BASEVIDHEIGHT / 2) - (18 * 4)) - 8);
|
||||
const INT32 curx = ((setupm_skinxpos * 18) + ((BASEVIDWIDTH / 2) - (18 * 4)) - 8 + SKINXSHIFT);
|
||||
const INT32 cury = ((setupm_skinypos * 18) + ((BASEVIDHEIGHT / 2) - (18 * 4)) - 8);
|
||||
|
||||
if (skinstatscount[setupm_skinxpos][setupm_skinypos])
|
||||
{
|
||||
UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
|
||||
INT32 skinn = skinstats[setupm_skinxpos][setupm_skinypos][(I_GetTime() / TICRATE) % skinstatscount[setupm_skinxpos][setupm_skinypos]];
|
||||
const UINT8 *cmap = R_GetTranslationColormap(setupm_skinselect, setupm_fakecolor, GTC_MENUCACHE);
|
||||
const INT32 skinn = skinstats[setupm_skinxpos][setupm_skinypos][(I_GetTime() / TICRATE) % skinstatscount[setupm_skinxpos][setupm_skinypos]];
|
||||
|
||||
cursor = facewantprefix[skinn];
|
||||
V_DrawFixedPatch(((curx-8) << FRACBITS), ((cury-8) << FRACBITS), FRACUNIT, 0, cursor, cmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 cursorframe = (I_GetTime() / 4) % 7;
|
||||
const UINT8 cursorframe = (I_GetTime() / 4) % 7;
|
||||
cursor = (patch_t *)W_CachePatchName(va("K_CHILI%d", cursorframe + 1), PU_PATCH);
|
||||
V_DrawFixedPatch((curx << FRACBITS) - (FRACUNIT), (cury << FRACBITS) - (FRACUNIT), FRACUNIT+(FRACUNIT>>3), 0, cursor, NULL);
|
||||
}
|
||||
@@ -8348,18 +8381,26 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
break;
|
||||
#undef SKINXSHIFT
|
||||
default:
|
||||
speed = skins[setupm_fakeskin].kartspeed;
|
||||
weight = skins[setupm_fakeskin].kartweight;
|
||||
{
|
||||
speed = skins[setupm_fakeskin].kartspeed;
|
||||
weight = skins[setupm_fakeskin].kartweight;
|
||||
|
||||
statdot = (patch_t *)W_CachePatchName("K_SDOT1", PU_PATCH);
|
||||
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
|
||||
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, flashcol);
|
||||
else
|
||||
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, NULL);
|
||||
const INT32 x = ((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS;
|
||||
const INT32 y = ((my+76) + ((weight-1)*8))<<FRACBITS;
|
||||
|
||||
statdot = (patch_t *)W_CachePatchName("K_SDOT2", PU_PATCH); // coloured center
|
||||
if (setupm_fakecolor)
|
||||
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
|
||||
statdot = (patch_t *)W_CachePatchName("K_SDOT1", PU_PATCH);
|
||||
|
||||
if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, 0, statdot, flashcol);
|
||||
else
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, 0, statdot, NULL);
|
||||
|
||||
if (setupm_fakecolor)
|
||||
{
|
||||
statdot = (patch_t *)W_CachePatchName("K_SDOT2", PU_PATCH); // coloured center
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8373,7 +8414,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
colwidth = colwidth - 10;
|
||||
|
||||
INT32 j = -colwidth;
|
||||
INT16 col = setupm_fakecolor - colwidth;
|
||||
INT32 col = setupm_fakecolor - colwidth;
|
||||
INT32 x = mx;
|
||||
INT32 cw = indexwidth;
|
||||
UINT8 ch;
|
||||
@@ -8386,10 +8427,13 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
cw = charw;
|
||||
else
|
||||
cw = indexwidth;
|
||||
|
||||
for (ch = 0; ch < 16; ch++)
|
||||
V_DrawFill(x, my+(cv_skinselectmenu.value?176:162)+ch, cw, 1, colortranslations[col][ch]);
|
||||
|
||||
if (++col >= MAXSKINCOLORS)
|
||||
col -= MAXSKINCOLORS-1;
|
||||
|
||||
x += cw;
|
||||
}
|
||||
}
|
||||
@@ -8401,7 +8445,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
{
|
||||
const INT32 icons = 4;
|
||||
INT32 k = -icons;
|
||||
INT16 col = setupm_fakeskin - icons;
|
||||
INT32 col = setupm_fakeskin - icons;
|
||||
INT32 x = BASEVIDWIDTH/2 - ((icons+1)*24) - 4;
|
||||
fixed_t scale = FRACUNIT/2;
|
||||
INT32 offx = 8, offy = 8;
|
||||
@@ -8417,6 +8461,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
|
||||
if (col < 0)
|
||||
col += numskins;
|
||||
|
||||
while (k <= icons)
|
||||
{
|
||||
if (!(k++))
|
||||
@@ -8433,12 +8478,16 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
offx = 8;
|
||||
offy = 8;
|
||||
}
|
||||
|
||||
colmap = R_GetTranslationColormap(col, setupm_fakecolor, GTC_MENUCACHE);
|
||||
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, face, colmap);
|
||||
|
||||
if (scale == FRACUNIT) // bit of a hack
|
||||
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, cursor, colmap);
|
||||
|
||||
if (++col >= numskins)
|
||||
col -= numskins;
|
||||
|
||||
x += FixedMul(iconwidth<<FRACBITS, 3*scale/2)/FRACUNIT;
|
||||
}
|
||||
}
|
||||
@@ -8464,7 +8513,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
switch (cv_skinselectmenu.value)
|
||||
{
|
||||
case SKINMENUTYPE_2D:
|
||||
skintodisplay = (UINT8)setupm_fakeskin;
|
||||
skintodisplay = (skinnum_t)setupm_fakeskin;
|
||||
if (setupm_skinlockedselect) // show the skin we are trying to select
|
||||
skintodisplay = skinstats[setupm_skinxpos][setupm_skinypos][setupm_skinselect];
|
||||
else if (skinstatscount[setupm_skinxpos][setupm_skinypos] && itemOn == 1)
|
||||
@@ -8472,10 +8521,10 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
||||
break;
|
||||
case SKINMENUTYPE_EXTENDED:
|
||||
case SKINMENUTYPE_GRID:
|
||||
skintodisplay = ((itemOn == 1 && (setupm_skinselect < numskins)) ? skinsorted[setupm_skinselect] : (UINT8)setupm_fakeskin);
|
||||
skintodisplay = ((itemOn == 1 && (setupm_skinselect < numskins)) ? skinsorted[setupm_skinselect] : (skinnum_t)setupm_fakeskin);
|
||||
break;
|
||||
default:
|
||||
skintodisplay = (UINT8)setupm_fakeskin;
|
||||
skintodisplay = (skinnum_t)setupm_fakeskin;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8579,6 +8628,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
}
|
||||
else
|
||||
M_NextOpt();
|
||||
|
||||
S_StartSound(NULL, sfx_menu1); // Tails
|
||||
break;
|
||||
}
|
||||
@@ -8605,6 +8655,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
{
|
||||
M_NextOpt();
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
else if (itemOn == 0)
|
||||
@@ -8615,9 +8666,11 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
}
|
||||
else
|
||||
M_NextOpt();
|
||||
|
||||
S_StartSound(NULL, sfx_menu1); // Tails
|
||||
break;
|
||||
}
|
||||
|
||||
M_NextOpt();
|
||||
S_StartSound(NULL, sfx_menu1); // Tails
|
||||
break;
|
||||
@@ -8635,6 +8688,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
}
|
||||
else
|
||||
M_PrevOpt();
|
||||
|
||||
S_StartSound(NULL, sfx_menu1); // Tails
|
||||
break;
|
||||
}
|
||||
@@ -8653,6 +8707,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
{
|
||||
M_PrevOpt();
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
else if (itemOn == 2)
|
||||
@@ -8672,9 +8727,11 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
}
|
||||
else
|
||||
M_PrevOpt();
|
||||
|
||||
S_StartSound(NULL, sfx_menu1); // Tails
|
||||
break;
|
||||
}
|
||||
|
||||
M_PrevOpt();
|
||||
S_StartSound(NULL, sfx_menu1); // Tails
|
||||
break;
|
||||
@@ -8693,6 +8750,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
setupm_skinselect--;
|
||||
else
|
||||
setupm_skinselect = SELECTEDSTATSCOUNT - 1;
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
else //player skin
|
||||
@@ -8725,6 +8783,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
else if (cv_skinselectmenu.value == SKINMENUTYPE_EXTENDED)
|
||||
setupm_skinypos = (((roundedskins/8) - SKINGRIDHEIGHT-2) > 0 ? (roundedskins/8) - SKINGRIDHEIGHT-2 : 0);
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
break;
|
||||
}
|
||||
@@ -8755,6 +8814,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
setupm_skinselect++;
|
||||
else
|
||||
setupm_skinselect = 0;
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
else //player skin
|
||||
@@ -8789,6 +8849,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
setupm_skinselect = 0;
|
||||
setupm_skinypos = 0;
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
break;
|
||||
}
|
||||
@@ -8811,12 +8872,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
setupm_skinlockedselect = false;
|
||||
break;
|
||||
}
|
||||
|
||||
exitmenu = true;
|
||||
break;
|
||||
|
||||
case KEY_BACKSPACE:
|
||||
if (cv_skinselectmenu.value)
|
||||
BREAKWHENLOCKED
|
||||
|
||||
if (itemOn == 0)
|
||||
{
|
||||
M_TextInputHandle(&setupm_input, choice);
|
||||
@@ -8846,6 +8909,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
|
||||
case KEY_DEL:
|
||||
if (cv_skinselectmenu.value)
|
||||
BREAKWHENLOCKED
|
||||
|
||||
if (itemOn == 0)
|
||||
{
|
||||
M_TextInputHandle(&setupm_input, choice);
|
||||
@@ -9162,7 +9226,7 @@ static void M_DrawJoystick(void)
|
||||
compareval4 = cv_usejoystick[3].value;
|
||||
compareval3 = cv_usejoystick[2].value;
|
||||
compareval2 = cv_usejoystick[1].value;
|
||||
compareval = cv_usejoystick[0].value;
|
||||
compareval = cv_usejoystick[0].value;
|
||||
#endif
|
||||
|
||||
if ((setupcontrolplayer == 4 && (i == compareval4))
|
||||
@@ -9201,14 +9265,13 @@ void M_SetupJoystickMenu(INT32 choice)
|
||||
//
|
||||
// Update cv_usejoystick.string here so that the user can
|
||||
// properly change this value.
|
||||
if (i == cv_usejoystick[0].value)
|
||||
CV_SetValue(&cv_usejoystick[0], i);
|
||||
if (i == cv_usejoystick[1].value)
|
||||
CV_SetValue(&cv_usejoystick[1], i);
|
||||
if (i == cv_usejoystick[2].value)
|
||||
CV_SetValue(&cv_usejoystick[2], i);
|
||||
if (i == cv_usejoystick[3].value)
|
||||
CV_SetValue(&cv_usejoystick[3], i);
|
||||
for (INT32 f = 0; f < MAXSPLITSCREENPLAYERS; f++)
|
||||
{
|
||||
if (i == cv_usejoystick[f].value)
|
||||
{
|
||||
CV_SetValue(&cv_usejoystick[f], i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -9247,9 +9310,11 @@ static void M_Setup4PJoystickMenu(INT32 choice)
|
||||
static void M_DoAssignJoystick(UINT8 pnum, INT32 choice)
|
||||
{
|
||||
INT32 oldchoice, oldstringchoice;
|
||||
const int joynum = atoi(cv_usejoystick[pnum].string);
|
||||
|
||||
oldchoice = oldstringchoice = joynum > numcontrollers ? joynum : cv_usejoystick[pnum].value;
|
||||
#define joystrnum (atoi(cv_usejoystick[pnum].string))
|
||||
#define joyoldchoice ((joystrnum > numcontrollers) ? joystrnum : cv_usejoystick[pnum].value)
|
||||
|
||||
oldchoice = oldstringchoice = joyoldchoice;
|
||||
CV_SetValue(&cv_usejoystick[pnum], choice);
|
||||
|
||||
// Just in case last-minute changes were made to cv_usejoystick.value,
|
||||
@@ -9259,59 +9324,37 @@ static void M_DoAssignJoystick(UINT8 pnum, INT32 choice)
|
||||
{
|
||||
CV_SetValue(&cv_usejoystick[pnum], cv_usejoystick[pnum].value);
|
||||
|
||||
if (oldchoice > numcontrollers) /* reset this so the comparison is valid*/
|
||||
// reset this so the comparison is valid
|
||||
if (oldchoice > numcontrollers)
|
||||
oldchoice = cv_usejoystick[pnum].value;
|
||||
|
||||
if (oldchoice != choice)
|
||||
{
|
||||
if (choice && oldstringchoice > numcontrollers) // if we did not select "None", we likely selected a used device
|
||||
CV_SetValue(&cv_usejoystick[pnum], (oldstringchoice > numcontrollers ? oldstringchoice : oldchoice));
|
||||
{
|
||||
CV_SetValue(&cv_usejoystick[pnum], ((oldstringchoice > numcontrollers) ? oldstringchoice : oldchoice));
|
||||
}
|
||||
|
||||
if (oldstringchoice ==
|
||||
(joynum > numcontrollers ? joynum : cv_usejoystick[pnum].value))
|
||||
if (oldstringchoice == joyoldchoice)
|
||||
{
|
||||
M_StartMessage("This joystick is used by another\n"
|
||||
"player. Reset the joystick\n"
|
||||
"for that player first.\n\n"
|
||||
"(Press a key)\n", NULL, MM_NOTHING);
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef joystrnum
|
||||
#undef joyoldchoice
|
||||
}
|
||||
#endif
|
||||
|
||||
static void M_AssignJoystick(INT32 choice)
|
||||
{
|
||||
#ifdef JOYSTICK_HOTPLUG
|
||||
switch (setupcontrolplayer)
|
||||
{
|
||||
case 4:
|
||||
M_DoAssignJoystick(3, choice);
|
||||
break;
|
||||
case 3:
|
||||
M_DoAssignJoystick(2, choice);
|
||||
break;
|
||||
case 2:
|
||||
M_DoAssignJoystick(1, choice);
|
||||
break;
|
||||
case 1:
|
||||
M_DoAssignJoystick(0, choice);
|
||||
break;
|
||||
}
|
||||
M_DoAssignJoystick((setupcontrolplayer-1), choice);
|
||||
#else
|
||||
switch (setupcontrolplayer)
|
||||
{
|
||||
case 4:
|
||||
CV_SetValue(&cv_usejoystick[3], choice);
|
||||
break;
|
||||
case 3:
|
||||
CV_SetValue(&cv_usejoystick[2], choice);
|
||||
break;
|
||||
case 2:
|
||||
CV_SetValue(&cv_usejoystick[1], choice);
|
||||
break;
|
||||
case 1:
|
||||
CV_SetValue(&cv_usejoystick[0], choice);
|
||||
break;
|
||||
}
|
||||
CV_SetValue(&cv_usejoystick[(setupcontrolplayer-1)], choice);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -9349,7 +9392,7 @@ static void M_SetupControlsMenu(UINT8 pnum)
|
||||
{
|
||||
// Hide P1-only controls
|
||||
OP_AllControlsMenu[19].status = IT_GRAYEDOUT2; // Chat
|
||||
OP_AllControlsMenu[10].status = IT_GRAYEDOUT2; // Rankings
|
||||
OP_AllControlsMenu[20].status = IT_GRAYEDOUT2; // Rankings
|
||||
OP_AllControlsMenu[21].status = IT_GRAYEDOUT2; // Pause
|
||||
OP_AllControlsMenu[22].status = IT_GRAYEDOUT2; // Screenshot
|
||||
OP_AllControlsMenu[23].status = IT_GRAYEDOUT2; // GIF
|
||||
@@ -9361,7 +9404,7 @@ static void M_SetupControlsMenu(UINT8 pnum)
|
||||
{
|
||||
// Unhide P1-only controls
|
||||
OP_AllControlsMenu[19].status = IT_CONTROL; // Chat
|
||||
OP_AllControlsMenu[10].status = IT_CONTROL; // Rankings
|
||||
OP_AllControlsMenu[20].status = IT_CONTROL; // Rankings
|
||||
OP_AllControlsMenu[21].status = IT_CONTROL; // Pause
|
||||
OP_AllControlsMenu[22].status = IT_CONTROL; // Screenshot
|
||||
OP_AllControlsMenu[23].status = IT_CONTROL; // GIF
|
||||
@@ -9598,11 +9641,13 @@ static void M_ChangecontrolResponse(event_t *ev)
|
||||
menu_t *prev = currentMenu->prevMenu;
|
||||
|
||||
if (controltochange == gc_pause)
|
||||
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"),
|
||||
controltochangetext);
|
||||
{
|
||||
snprintf(tmp, sizeof(tmp), M_GetText("The \x82Pause Key \x80is enabled, but \nyou may select another key. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext);
|
||||
}
|
||||
else
|
||||
sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"),
|
||||
controltochangetext);
|
||||
{
|
||||
snprintf(tmp, sizeof(tmp), M_GetText("The \x82Pause Key \x80is enabled, but \nit is not configurable. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext);
|
||||
}
|
||||
|
||||
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
|
||||
currentMenu->prevMenu = prev;
|
||||
@@ -9623,8 +9668,7 @@ static void M_ChangeControl(INT32 choice)
|
||||
static char tmp[68];
|
||||
|
||||
controltochange = currentMenu->menuitems[choice].alphaKey;
|
||||
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
||||
currentMenu->menuitems[choice].text);
|
||||
snprintf(tmp, sizeof(tmp), M_GetText("Hit the new key for\n%s\nESC for Cancel"), currentMenu->menuitems[choice].text);
|
||||
strlcpy(controltochangetext, currentMenu->menuitems[choice].text, 33);
|
||||
|
||||
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
|
||||
@@ -9906,6 +9950,7 @@ static void M_DrawLocalSkinMenu(void)
|
||||
V_DrawFill(mx + 220 - (charw/2), my+54, charw, 84, 239);
|
||||
#undef charw
|
||||
|
||||
// FIXME: is skins[displayskin.localnum] even correct?
|
||||
UINT8 *colormap = R_GetLocalTranslationColormap(&skins[displayskin.localnum], (displayskin.localskin ? &localskins[displayskin.localnum] : NULL), cv_playercolor.value, GTC_MENUCACHE, displayskin.localskin);
|
||||
|
||||
V_DrawMappedPatch(mx, my+50, 0, (patch_t *)W_CachePatchName(displayskin.facewant, PU_PATCH), colormap);
|
||||
@@ -9923,7 +9968,7 @@ static void M_DrawLocalSkinMenu(void)
|
||||
my += 120;
|
||||
|
||||
#ifdef HWRENDER
|
||||
md2_t *md2 = (displayskin.localskin ? &md2_localplayermodels[skintodisplay] : &md2_playermodels[skintodisplay]);
|
||||
md2_t *md2 = (displayskin.localskin ? &md2_localplayermodels[displayskin.localnum] : &md2_playermodels[skintodisplay]);
|
||||
|
||||
// if we have 3d models enabled and a model exists
|
||||
// try to show it instead of the sprite
|
||||
@@ -10056,7 +10101,7 @@ static void M_DrawColorMenu(void)
|
||||
|
||||
for (max = currentMenu->numitems; max > 0; max--)
|
||||
{
|
||||
if (currentMenu->menuitems[max].status != IT_DISABLED && currentMenu->menuitems[max-1].alphaKey*2 + tempcentery <= (currentMenu->y + 2*scrollareaheight))
|
||||
if (currentMenu->menuitems[max-1].status != IT_DISABLED && currentMenu->menuitems[max-1].alphaKey*2 + tempcentery <= (currentMenu->y + 2*scrollareaheight))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -230,8 +230,8 @@ typedef struct
|
||||
char levelname[32];
|
||||
UINT8 actnum;
|
||||
UINT8 skincolor;
|
||||
UINT8 skinnum;
|
||||
UINT8 botskin;
|
||||
skinnum_t skinnum;
|
||||
skinnum_t botskin;
|
||||
UINT8 botcolor;
|
||||
UINT8 numemeralds;
|
||||
INT32 lives;
|
||||
|
||||
+19
-18
@@ -515,8 +515,8 @@ static boolean M_BackupConfig(const char *filename)
|
||||
{
|
||||
char backupfile[MAX_WADPATH+4];
|
||||
|
||||
snprintf(backupfile, sizeof backupfile, "%s.bak", filename);
|
||||
backupfile[sizeof backupfile - 1] = '\0';
|
||||
snprintf(backupfile, sizeof(backupfile), "%s.bak", filename);
|
||||
backupfile[sizeof(backupfile) - 1] = '\0';
|
||||
|
||||
FILE *config = fopen(filename, "r");
|
||||
|
||||
@@ -766,27 +766,27 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
|
||||
}
|
||||
|
||||
if (gamestate == GS_LEVEL)
|
||||
snprintf(maptext, 8, "%s", G_BuildMapName(gamemap));
|
||||
snprintf(maptext, sizeof(maptext), "%s", G_BuildMapName(gamemap));
|
||||
else
|
||||
snprintf(maptext, 8, "Unknown");
|
||||
snprintf(maptext, sizeof(maptext), "Unknown");
|
||||
|
||||
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0')
|
||||
snprintf(lvlttltext, 48, "%s%s%s",
|
||||
snprintf(lvlttltext, sizeof(lvlttltext), "%s%s%s",
|
||||
mapheaderinfo[gamemap-1]->lvlttl,
|
||||
(strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart
|
||||
((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE"),
|
||||
(strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->actnum) : "");
|
||||
else
|
||||
snprintf(lvlttltext, 48, "Unknown");
|
||||
snprintf(lvlttltext, sizeof(lvlttltext), "Unknown");
|
||||
|
||||
if (gamestate == GS_LEVEL && players[displayplayers[0]].mo)
|
||||
snprintf(locationtxt, 40, "X:%d Y:%d Z:%d A:%d",
|
||||
snprintf(locationtxt, sizeof(locationtxt), "X:%d Y:%d Z:%d A:%d",
|
||||
players[displayplayers[0]].mo->x>>FRACBITS,
|
||||
players[displayplayers[0]].mo->y>>FRACBITS,
|
||||
players[displayplayers[0]].mo->z>>FRACBITS,
|
||||
FixedInt(AngleFixed(players[displayplayers[0]].mo->angle)));
|
||||
else
|
||||
snprintf(locationtxt, 40, "Unknown");
|
||||
snprintf(locationtxt, sizeof(locationtxt), "Unknown");
|
||||
|
||||
memset(png_infotext, 0x00, sizeof(png_infotext));
|
||||
|
||||
@@ -1253,7 +1253,6 @@ boolean M_ScreenshotResponder(event_t *ev)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen, tic_t timer)
|
||||
{
|
||||
// How much should we scroll. Not sure why +1 is needed, but without it this function skips 2
|
||||
@@ -1261,7 +1260,7 @@ void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen,
|
||||
const size_t amount = len - maxlen + 1;
|
||||
|
||||
// Note: anything above 17 will cause zero division
|
||||
const size_t MAXSPEED = 6;
|
||||
static const size_t MAXSPEED = 6;
|
||||
const tic_t t = timer / (35/min(amount, MAXSPEED));
|
||||
|
||||
const size_t state = (t / amount) % 4;
|
||||
@@ -1296,7 +1295,7 @@ void M_ScrollString(const char name[], size_t len, char result[], size_t maxlen,
|
||||
}
|
||||
|
||||
// Technically not necessary, since it gets set again after function call, but just in case
|
||||
result[maxlen] = 0;
|
||||
result[maxlen-1] = '\0';
|
||||
}
|
||||
|
||||
void M_MinimapGenerate(void)
|
||||
@@ -1394,7 +1393,7 @@ char *va(const char *format, ...)
|
||||
static char string[1024];
|
||||
|
||||
va_start(argptr, format);
|
||||
vsnprintf(string, 1024, format, argptr);
|
||||
vsnprintf(string, sizeof(string), format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
return string;
|
||||
@@ -1708,7 +1707,7 @@ const char * M_Ftrim(double f)
|
||||
int i;
|
||||
|
||||
/* I know I said it's the default, but just in case... */
|
||||
sprintf(dig, "%.6f", fabs(modf(f, &f)));
|
||||
snprintf(dig, sizeof(dig), "%.6f", fabs(modf(f, &f)));
|
||||
|
||||
/* trim trailing zeroes */
|
||||
for (i = strlen(dig)-1; dig[i] == '0'; --i)
|
||||
@@ -1736,6 +1735,7 @@ UINT8 M_CountBits(UINT32 num, UINT8 size)
|
||||
const char *GetRevisionString(void)
|
||||
{
|
||||
static char rev[9] = {0};
|
||||
|
||||
if (rev[0])
|
||||
return rev;
|
||||
|
||||
@@ -1743,6 +1743,7 @@ const char *GetRevisionString(void)
|
||||
strncpy(rev, comprevision, 7);
|
||||
else
|
||||
snprintf(rev, 7, "r%s", comprevision);
|
||||
|
||||
rev[7] = '\0';
|
||||
|
||||
return rev;
|
||||
@@ -1814,35 +1815,35 @@ TMatrix *RotateZMatrix(angle_t rad)
|
||||
char *sizeu1(size_t num)
|
||||
{
|
||||
static char sizeu1_buf[28];
|
||||
sprintf(sizeu1_buf, "%"PRIdS, num);
|
||||
snprintf(sizeu1_buf, sizeof(sizeu1_buf), "%" PRIdS, num);
|
||||
return sizeu1_buf;
|
||||
}
|
||||
|
||||
char *sizeu2(size_t num)
|
||||
{
|
||||
static char sizeu2_buf[28];
|
||||
sprintf(sizeu2_buf, "%"PRIdS, num);
|
||||
snprintf(sizeu2_buf, sizeof(sizeu2_buf), "%" PRIdS, num);
|
||||
return sizeu2_buf;
|
||||
}
|
||||
|
||||
char *sizeu3(size_t num)
|
||||
{
|
||||
static char sizeu3_buf[28];
|
||||
sprintf(sizeu3_buf, "%"PRIdS, num);
|
||||
snprintf(sizeu3_buf, sizeof(sizeu3_buf), "%" PRIdS, num);
|
||||
return sizeu3_buf;
|
||||
}
|
||||
|
||||
char *sizeu4(size_t num)
|
||||
{
|
||||
static char sizeu4_buf[28];
|
||||
sprintf(sizeu4_buf, "%"PRIdS, num);
|
||||
snprintf(sizeu4_buf, sizeof(sizeu4_buf), "%" PRIdS, num);
|
||||
return sizeu4_buf;
|
||||
}
|
||||
|
||||
char *sizeu5(size_t num)
|
||||
{
|
||||
static char sizeu5_buf[28];
|
||||
sprintf(sizeu5_buf, "%"PRIdS, num);
|
||||
snprintf(sizeu5_buf, sizeof(sizeu5_buf), "%" PRIdS, num);
|
||||
return sizeu5_buf;
|
||||
}
|
||||
|
||||
|
||||
+42
-56
@@ -47,6 +47,7 @@ struct perfstatrow {
|
||||
static ps_metric_t ps_frametime = {0};
|
||||
|
||||
ps_metric_t ps_tictime = {0};
|
||||
ps_metric_t ps_prevtictime = {0};
|
||||
|
||||
ps_metric_t ps_playerthink_time = {0};
|
||||
ps_metric_t ps_thinkertime = {0};
|
||||
@@ -168,14 +169,14 @@ perfstatrow_t gamelogic_rows[] = {
|
||||
};
|
||||
|
||||
perfstatrow_t thinkercount_rows[] = {
|
||||
{"thnkers", "Thinkers: ", &ps_thinkercount, PS_LEVEL},
|
||||
{" mobjs ", " Mobjs: ", &ps_mobjcount, PS_LEVEL},
|
||||
{"thnkers" , "Thinkers: ", &ps_thinkercount, PS_LEVEL},
|
||||
{" mobjs " , " Mobjs: ", &ps_mobjcount, PS_LEVEL},
|
||||
{" regular", " Regular: ", &ps_regularcount, PS_LEVEL},
|
||||
{" scenery", " Scenery: ", &ps_scenerycount, PS_LEVEL},
|
||||
{" nothink", " Nothink: ", &ps_nothinkcount, PS_HIDE_ZERO|PS_LEVEL},
|
||||
{" precip ", " Precipitation: ", &ps_precipcount, PS_LEVEL},
|
||||
{" other ", " Other: ", &ps_otherthcount, PS_LEVEL},
|
||||
{" remove ", " Pending removal:", &ps_removecount, PS_LEVEL},
|
||||
{" precip " , " Precipitation: ", &ps_precipcount, PS_LEVEL},
|
||||
{" other " , " Other: ", &ps_otherthcount, PS_LEVEL},
|
||||
{" remove " , " Pending removal:", &ps_removecount, PS_LEVEL},
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -605,7 +606,9 @@ static void PS_CountThinkers(void)
|
||||
else if (thinker->function == (actionf_p1)P_MobjThinker)
|
||||
{
|
||||
mobj_t *mobj = (mobj_t*)thinker;
|
||||
|
||||
ps_mobjcount.value.i++;
|
||||
|
||||
if (mobj->flags & MF_NOTHINK)
|
||||
ps_nothinkcount.value.i++;
|
||||
else if (mobj->flags & MF_SCENERY)
|
||||
@@ -624,49 +627,17 @@ static void PS_CountThinkers(void)
|
||||
|
||||
ps_precipcount.value.i++;
|
||||
}
|
||||
|
||||
/*for (i = 0; i < NUM_THINKERLISTS; i++)
|
||||
{
|
||||
for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next)
|
||||
{
|
||||
ps_thinkercount.value.i++;
|
||||
if (thinker->function == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
ps_removecount.value.i++;
|
||||
else if (i == THINK_POLYOBJ)
|
||||
ps_polythcount.value.i++;
|
||||
else if (i == THINK_MAIN)
|
||||
ps_mainthcount.value.i++;
|
||||
else if (i == THINK_MOBJ)
|
||||
{
|
||||
if (thinker->function == (actionf_p1)P_MobjThinker)
|
||||
{
|
||||
mobj_t *mobj = (mobj_t*)thinker;
|
||||
ps_mobjcount.value.i++;
|
||||
if (mobj->flags & MF_NOTHINK)
|
||||
ps_nothinkcount.value.i++;
|
||||
else if (mobj->flags & MF_SCENERY)
|
||||
ps_scenerycount.value.i++;
|
||||
else
|
||||
ps_regularcount.value.i++;
|
||||
}
|
||||
}
|
||||
else if (i == THINK_DYNSLOPE)
|
||||
ps_dynslopethcount.value.i++;
|
||||
else if (i == THINK_PRECIP)
|
||||
ps_precipcount.value.i++;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// Update all metrics that are calculated on every tick.
|
||||
void PS_UpdateTickStats(void)
|
||||
{
|
||||
if (cv_perfstats.value == 1 && cv_ps_samplesize.value > 1)
|
||||
if (cv_perfstats.value == PS_RENDER && cv_ps_samplesize.value > 1)
|
||||
{
|
||||
PS_UpdateRowHistories(gamelogicbrief_row, false);
|
||||
}
|
||||
|
||||
if (cv_perfstats.value == 2)
|
||||
if (cv_perfstats.value == PS_LOGIC)
|
||||
{
|
||||
if (PS_IsLevelActive())
|
||||
{
|
||||
@@ -691,25 +662,25 @@ void PS_UpdateTickStats(void)
|
||||
|
||||
if (cv_ps_samplesize.value > 1)
|
||||
{
|
||||
if (cv_perfstats.value >= 3 && PS_IsLevelActive())
|
||||
if (cv_perfstats.value >= PS_THINKFRAME && PS_IsLevelActive())
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (cv_perfstats.value)
|
||||
{
|
||||
case 3:
|
||||
case PS_THINKFRAME:
|
||||
for (i = 0; i < thinkframe_hooks_length; i++)
|
||||
{
|
||||
PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case PS_PRETHINKFRAME:
|
||||
for (i = 0; i < prethinkframe_hooks_length; i++)
|
||||
{
|
||||
PS_UpdateMetricHistory(&prethinkframe_hooks[i].time_taken, true, false);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case PS_POSTTHINKFRAME:
|
||||
for (i = 0; i < postthinkframe_hooks_length; i++)
|
||||
{
|
||||
PS_UpdateMetricHistory(&postthinkframe_hooks[i].time_taken, true, false);
|
||||
@@ -719,6 +690,7 @@ void PS_UpdateTickStats(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cv_perfstats.value)
|
||||
{
|
||||
ps_tick_index++;
|
||||
@@ -749,7 +721,7 @@ static void PS_DrawDescriptorHeader(void)
|
||||
int samples_left = max(ps_frame_samples_left, ps_tick_samples_left);
|
||||
int x, y;
|
||||
|
||||
if (cv_perfstats.value >= 3)
|
||||
if (cv_perfstats.value >= PS_THINKFRAME)
|
||||
{
|
||||
x = 2;
|
||||
y = 0;
|
||||
@@ -865,20 +837,19 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
|
||||
last_mod_name[0] = '\0';
|
||||
INT32 total = 0;
|
||||
|
||||
//Decide page length based and drawn text on choosen thinker type
|
||||
// Decide page length based and drawn text on choosen thinker type
|
||||
switch (cv_perfstats.value)
|
||||
{
|
||||
case 3:
|
||||
case PS_THINKFRAME:
|
||||
{
|
||||
maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
|
||||
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
|
||||
pagestart = min((page - 1)*PAGE_ENTRIES, thinkframe_hooks_length);
|
||||
pageend = min(pagestart + PAGE_ENTRIES, thinkframe_hooks_length);
|
||||
|
||||
V_DrawSmallString(MAX_X-50, MAX_Y+2*HEIGHT, V_MONOSPACE | V_GREENMAP, "ThinkFrame");
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case PS_PRETHINKFRAME:
|
||||
{
|
||||
maxpage = prethinkframe_hooks_length/PAGE_ENTRIES + 1;
|
||||
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
|
||||
@@ -887,7 +858,7 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
|
||||
V_DrawSmallString(MAX_X-60, MAX_Y+2*HEIGHT, V_MONOSPACE | V_GREENMAP, "PreThinkFrame");
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case PS_POSTTHINKFRAME:
|
||||
{
|
||||
maxpage = postthinkframe_hooks_length/PAGE_ENTRIES + 1;
|
||||
page = max(1, min(cv_ps_thinkframe_page.value, maxpage));
|
||||
@@ -975,7 +946,22 @@ static void draw_think_frame_stats(int hook_length, ps_hookinfo_t *hook)
|
||||
|
||||
void PS_ThinkFrame_Page_OnChange(void)
|
||||
{
|
||||
int maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
|
||||
int maxpage = 0;
|
||||
|
||||
switch (cv_perfstats.value)
|
||||
{
|
||||
case PS_THINKFRAME:
|
||||
maxpage = thinkframe_hooks_length/PAGE_ENTRIES + 1;
|
||||
break;
|
||||
case PS_PRETHINKFRAME:
|
||||
maxpage = prethinkframe_hooks_length/PAGE_ENTRIES + 1;
|
||||
break;
|
||||
case PS_POSTTHINKFRAME:
|
||||
maxpage = postthinkframe_hooks_length/PAGE_ENTRIES + 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (cv_ps_thinkframe_page.value > maxpage)
|
||||
CV_StealthSetValue(&cv_ps_thinkframe_page, maxpage);
|
||||
@@ -1008,18 +994,18 @@ static void PS_DrawPostThinkFrameStats(void)
|
||||
|
||||
void M_DrawPerfStats(void)
|
||||
{
|
||||
if (cv_perfstats.value == 1) // rendering
|
||||
if (cv_perfstats.value == PS_RENDER) // rendering
|
||||
{
|
||||
PS_UpdateFrameStats();
|
||||
PS_DrawRenderStats();
|
||||
}
|
||||
else if (cv_perfstats.value == 2) // logic
|
||||
else if (cv_perfstats.value == PS_LOGIC) // logic
|
||||
{
|
||||
// PS_UpdateTickStats is called in TryRunTics, since otherwise it would miss
|
||||
// tics when frame skips happen
|
||||
PS_DrawGameLogicStats();
|
||||
}
|
||||
else if (cv_perfstats.value >= 3) // lua thinkframe
|
||||
else if (cv_perfstats.value >= PS_THINKFRAME) // lua thinkframe
|
||||
{
|
||||
if (!PS_IsLevelActive())
|
||||
return;
|
||||
@@ -1036,13 +1022,13 @@ void M_DrawPerfStats(void)
|
||||
|
||||
switch (cv_perfstats.value)
|
||||
{
|
||||
case 3:
|
||||
case PS_THINKFRAME:
|
||||
PS_DrawThinkFrameStats();
|
||||
break;
|
||||
case 4:
|
||||
case PS_PRETHINKFRAME:
|
||||
PS_DrawPreThinkFrameStats();
|
||||
break;
|
||||
case 5:
|
||||
case PS_POSTTHINKFRAME:
|
||||
PS_DrawPostThinkFrameStats();
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -26,6 +26,16 @@ typedef struct
|
||||
void *history;
|
||||
} ps_metric_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PS_OFF = 0,
|
||||
PS_RENDER,
|
||||
PS_LOGIC,
|
||||
PS_THINKFRAME,
|
||||
PS_PRETHINKFRAME,
|
||||
PS_POSTTHINKFRAME
|
||||
} ps_types_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ps_metric_t time_taken;
|
||||
@@ -36,6 +46,7 @@ typedef struct
|
||||
#define PS_STOP_TIMING(metric) metric.value.p = I_GetPreciseTime() - metric.value.p
|
||||
|
||||
extern ps_metric_t ps_tictime;
|
||||
extern ps_metric_t ps_prevtictime;
|
||||
|
||||
extern ps_metric_t ps_playerthink_time;
|
||||
extern ps_metric_t ps_thinkertime;
|
||||
|
||||
+2
-2
@@ -238,8 +238,8 @@ void M_TextInputClear(textinput_t *input)
|
||||
|
||||
void M_TextInputSetString(textinput_t *input, const char *c)
|
||||
{
|
||||
memset(input->buffer, 0, input->buffer_size);
|
||||
strncpy(input->buffer, c, input->buffer_size);
|
||||
strncpy(input->buffer, c, input->buffer_size-1);
|
||||
input->buffer[input->buffer_size-1] = '\0';
|
||||
input->cursor = input->select = input->length = strlen(input->buffer);
|
||||
}
|
||||
|
||||
|
||||
+710
-333
File diff suppressed because it is too large.
Load diff
+5
-1
@@ -107,6 +107,9 @@ void P_DoNightsScore(player_t *player)
|
||||
|
||||
dummymo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z+player->mo->height/2, MT_NIGHTSCORE);
|
||||
|
||||
if (P_MobjWasRemovedCompat(dummymo))
|
||||
return;
|
||||
|
||||
if (player->bot)
|
||||
player = &players[consoleplayer];
|
||||
|
||||
@@ -2013,7 +2016,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
|
||||
}
|
||||
}
|
||||
|
||||
static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
{
|
||||
player_t *player = target->player;
|
||||
(void)damage; //unused parm
|
||||
@@ -2632,6 +2635,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
||||
if (i & 1)
|
||||
P_SetObjectMomZ(mo, ns, true);
|
||||
}
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
mo->momz *= -1;
|
||||
}
|
||||
|
||||
+4
-3
@@ -295,10 +295,10 @@ FUNCINLINE static ATTRINLINE boolean P_MobjWasRemoved(const mobj_t *mobj)
|
||||
// so can only check if its not NULL in vanilla compat mode
|
||||
FUNCINLINE static ATTRINLINE boolean P_MobjWasRemovedCompat(const mobj_t *mobj)
|
||||
{
|
||||
#ifdef COMPAT_VANILLA
|
||||
return (!mobj);
|
||||
#else
|
||||
#ifdef PHOBOS_BUILD
|
||||
return P_MobjWasRemoved(mobj);
|
||||
#else
|
||||
return !mobj;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -418,6 +418,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch);
|
||||
void P_DelSeclist(msecnode_t *node);
|
||||
|
||||
void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y);
|
||||
void P_Initsecnode(void);
|
||||
|
||||
void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist);
|
||||
|
||||
|
||||
+39
-7
@@ -245,12 +245,12 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||
|
||||
static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
||||
{
|
||||
player_t *p = object->player; // will be NULL if not a player
|
||||
player_t *player = object->player; // will be NULL if not a player
|
||||
fixed_t zdist; // distance between bottoms
|
||||
fixed_t speed = spring->info->mass; // conveniently, both fans and gas jets use this for the vertical thrust
|
||||
SINT8 flipval = P_MobjFlip(spring); // virtually everything here centers around the thruster's gravity, not the object's!
|
||||
|
||||
if (p && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
|
||||
if (player && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
|
||||
return;
|
||||
|
||||
// is object's top below thruster's position? if not, calculate distance between their bottoms
|
||||
@@ -276,7 +276,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
|
||||
break;
|
||||
if (flipval*object->momz >= FixedMul(speed, spring->scale)) // if object's already moving faster than your best, don't bother
|
||||
break;
|
||||
if (p && (p->climbing || p->pflags & PF_GLIDING)) // doesn't affect Knux when he's using his abilities!
|
||||
if (player && (player->climbing || player->pflags & PF_GLIDING)) // doesn't affect Knux when he's using his abilities!
|
||||
break;
|
||||
|
||||
object->momz += flipval*FixedMul(speed/4, spring->scale);
|
||||
@@ -2026,7 +2026,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
|
||||
mapcampointer = thiscam;
|
||||
|
||||
if (UNLIKELY(GETSECSPECIAL(newsec->special, 4) == 12))
|
||||
if (newsec->flags & SF_NOCLIPCAMERA)
|
||||
{ // Camera noclip on entire sector.
|
||||
tmfloorz = tmdropoffz = thiscam->z;
|
||||
tmceilingz = tmdrpoffceilz = thiscam->z + thiscam->height;
|
||||
@@ -2068,7 +2068,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
fixed_t topheight, bottomheight, midheight;
|
||||
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL)
|
||||
|| UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
|| rover->master->frontsector->flags & SF_NOCLIPCAMERA)
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(thiscam, newsec, rover, x, y, NULL);
|
||||
@@ -2144,7 +2144,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
// We're inside it! Yess...
|
||||
polysec = po->lines[0]->backsector;
|
||||
|
||||
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
|
||||
if (polysec->flags & SF_NOCLIPCAMERA)
|
||||
{ // Camera noclip polyobj.
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
continue;
|
||||
@@ -3983,19 +3983,51 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
|
||||
Lots of new Boom functions that work faster and add functionality.
|
||||
*/
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
static msecnode_t *headsecnode = NULL;
|
||||
#endif
|
||||
|
||||
void P_Initsecnode(void)
|
||||
{
|
||||
#ifndef PHOBOS_BUILD
|
||||
headsecnode = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// P_GetSecnode() retrieves a node from the freelist. The calling routine
|
||||
// should make sure it sets all fields properly.
|
||||
|
||||
static msecnode_t *P_GetSecnode(void)
|
||||
{
|
||||
#ifdef PHOBOS_BUILD
|
||||
return Z_LevelPoolCalloc(sizeof(msecnode_t));
|
||||
#else
|
||||
msecnode_t *node;
|
||||
|
||||
if (headsecnode)
|
||||
{
|
||||
// vanilla does not clear this
|
||||
// so for compat reasons we also dont
|
||||
// means we just reuse stale data which causes weird interactions with orbiting items in some cases
|
||||
node = headsecnode;
|
||||
headsecnode = headsecnode->m_thinglist_next;
|
||||
}
|
||||
else
|
||||
node = Z_LevelPoolCalloc(sizeof(msecnode_t));
|
||||
|
||||
return node;
|
||||
#endif
|
||||
}
|
||||
|
||||
// P_PutSecnode() returns a node to the freelist.
|
||||
|
||||
static inline void P_PutSecnode(msecnode_t *node)
|
||||
{
|
||||
#ifdef PHOBOS_BUILD
|
||||
Z_LevelPoolFree(node, sizeof(msecnode_t));
|
||||
#else
|
||||
node->m_thinglist_next = headsecnode;
|
||||
headsecnode = node;
|
||||
#endif
|
||||
}
|
||||
|
||||
// P_AddSecnode() searches the current list to see if this sector is
|
||||
|
||||
+3
-3
@@ -328,7 +328,7 @@ void P_CameraLineOpening(line_t *linedef)
|
||||
{
|
||||
fixed_t topheight, bottomheight, midheight;
|
||||
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
|
||||
@@ -358,7 +358,7 @@ void P_CameraLineOpening(line_t *linedef)
|
||||
{
|
||||
fixed_t topheight, bottomheight, midheight;
|
||||
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
|
||||
@@ -466,7 +466,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
// Check for collision with front side's midtexture if Effect 4 is set
|
||||
if (linedef->flags & ML_EFFECT4
|
||||
&& !linedef->polyobj) // don't do anything for polyobjects! ...for now
|
||||
{
|
||||
{
|
||||
side_t *side = &sides[linedef->sidenum[0]];
|
||||
fixed_t textop, texbottom, texheight;
|
||||
fixed_t texmid, delta1, delta2;
|
||||
|
||||
+1187
-942
File diff suppressed because it is too large.
Load diff
+4
-18
@@ -113,7 +113,7 @@ typedef enum
|
||||
// Don't use the blocklinks (inert but displayable)
|
||||
MF_NOBLOCKMAP = 1<<4,
|
||||
// Thin, paper-like collision bound (for visual equivalent, see FF_PAPERSPRITE)
|
||||
MF_PAPERCOLLISION = 1<<5,
|
||||
MF_PAPERCOLLISION = 1<<5,
|
||||
// You can push this object. It can activate switches and things by pushing it on top.
|
||||
MF_PUSHABLE = 1<<6,
|
||||
// Object is a boss.
|
||||
@@ -258,23 +258,12 @@ typedef enum
|
||||
// PRECIPITATION flags ?! ?! ?!
|
||||
//
|
||||
typedef enum {
|
||||
PCF_INVISIBLE = 1, // Don't draw.
|
||||
PCF_INVISIBLE = 1, // Don't draw.
|
||||
PCF_PIT = 1<<1, // Above pit.
|
||||
PCF_FOF = 1<<2, // Above FOF.
|
||||
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_THUNK = 1<<5, // Ran the thinker this tic.
|
||||
PCF_SPLASH = 1<<2, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_THUNK = 1<<3, // Ran the thinker this tic.
|
||||
} precipflag_t;
|
||||
|
||||
typedef struct salty_s
|
||||
{
|
||||
bool init;
|
||||
bool ready;
|
||||
bool tapping;
|
||||
fixed_t zoffset;
|
||||
fixed_t momz;
|
||||
bool jump;
|
||||
} salty_t;
|
||||
|
||||
// Map Object definition.
|
||||
typedef struct mobj_s
|
||||
@@ -412,9 +401,6 @@ typedef struct mobj_s
|
||||
|
||||
tic_t slamsoundtimer; // Funni slam sound when landing
|
||||
|
||||
// saltyhop! hardcode edition
|
||||
salty_t salty;
|
||||
|
||||
// WARNING: New fields must be added separately to savegame and Lua.
|
||||
boolean islocal; // BEWARE: islocal does not exist in vanilla, strictly to be used for locally loaded addons to not cause desynchs with the mobj linedef trigger check. DO NOT USE THIS IN ACTUAL ADDONS YOU INTEND TO USE ON YOUR SERVER
|
||||
} mobj_t;
|
||||
|
||||
+72
-6
@@ -69,7 +69,7 @@ FUNCINLINE static ATTRINLINE void P_ArchivePlayer(savebuffer_t *save)
|
||||
pllives = 3; // has less than that.
|
||||
|
||||
WRITEUINT8(save->p, player->skincolor);
|
||||
WRITEUINT8(save->p, player->skin);
|
||||
WRITESKIN(save->p, player->skin);
|
||||
|
||||
WRITEUINT32(save->p, player->score);
|
||||
WRITEINT32(save->p, pllives);
|
||||
@@ -77,7 +77,7 @@ FUNCINLINE static ATTRINLINE void P_ArchivePlayer(savebuffer_t *save)
|
||||
|
||||
if (botskin)
|
||||
{
|
||||
WRITEUINT8(save->p, botskin);
|
||||
WRITESKIN(save->p, botskin);
|
||||
WRITEUINT8(save->p, botcolor);
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ FUNCINLINE static ATTRINLINE void P_ArchivePlayer(savebuffer_t *save)
|
||||
FUNCINLINE static ATTRINLINE void P_UnArchivePlayer(savebuffer_t *save)
|
||||
{
|
||||
savedata.skincolor = READUINT8(save->p);
|
||||
savedata.skin = READUINT8(save->p);
|
||||
savedata.skin = READSKIN(save->p);
|
||||
|
||||
savedata.score = READINT32(save->p);
|
||||
savedata.lives = READINT32(save->p);
|
||||
@@ -96,9 +96,11 @@ FUNCINLINE static ATTRINLINE void P_UnArchivePlayer(savebuffer_t *save)
|
||||
|
||||
if (savedata.botcolor)
|
||||
{
|
||||
savedata.botskin = READUINT8(save->p);
|
||||
savedata.botskin = READSKIN(save->p);
|
||||
|
||||
if (savedata.botskin-1 >= numskins)
|
||||
savedata.botskin = 0;
|
||||
|
||||
savedata.botcolor = READUINT8(save->p);
|
||||
}
|
||||
else
|
||||
@@ -117,7 +119,9 @@ static void P_NetArchivePlayers(savebuffer_t *save, boolean resending)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
#ifndef PHOBOS_BUILD
|
||||
if (resending)
|
||||
#endif
|
||||
WRITESINT8(save->p, (SINT8)adminplayers[i]);
|
||||
|
||||
if (!playeringame[i])
|
||||
@@ -127,7 +131,9 @@ static void P_NetArchivePlayers(savebuffer_t *save, boolean resending)
|
||||
|
||||
// no longer send ticcmds
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
if (resending)
|
||||
#endif
|
||||
WRITESTRINGN(save->p, player_names[i], MAXPLAYERNAME);
|
||||
|
||||
const player_t *player = &players[i];
|
||||
@@ -156,11 +162,16 @@ static void P_NetArchivePlayers(savebuffer_t *save, boolean resending)
|
||||
WRITEUINT16(save->p, player->flashpal);
|
||||
WRITEUINT16(save->p, player->flashcount);
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
WRITEUINT8(save->p, player->skincolor);
|
||||
WRITEINT32(save->p, player->skin);
|
||||
#else
|
||||
if (resending)
|
||||
{
|
||||
WRITEUINT8(save->p, player->skincolor);
|
||||
WRITEINT32(save->p, player->skin);
|
||||
}
|
||||
#endif
|
||||
|
||||
WRITEUINT32(save->p, player->score);
|
||||
WRITEFIXED(save->p, player->dashspeed);
|
||||
@@ -309,7 +320,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save, boolean reloading)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
#ifndef PHOBOS_BUILD
|
||||
if (reloading)
|
||||
#endif
|
||||
adminplayers[i] = (INT32)READSINT8(save->p);
|
||||
|
||||
// Do NOT memset player struct to 0
|
||||
@@ -320,7 +333,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save, boolean reloading)
|
||||
|
||||
// NOTE: sending tics should (hopefully) no longer be necessary
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
if (reloading)
|
||||
#endif
|
||||
READSTRINGN(save->p, player_names[i], MAXPLAYERNAME);
|
||||
|
||||
player_t *player = &players[i];
|
||||
@@ -349,11 +364,16 @@ static void P_NetUnArchivePlayers(savebuffer_t *save, boolean reloading)
|
||||
player->flashpal = READUINT16(save->p);
|
||||
player->flashcount = READUINT16(save->p);
|
||||
|
||||
#ifdef PHOBOS_BUILD
|
||||
player->skincolor = READUINT8(save->p);
|
||||
player->skin = READINT32(save->p);
|
||||
#else
|
||||
if (reloading)
|
||||
{
|
||||
player->skincolor = READUINT8(save->p);
|
||||
player->skin = READINT32(save->p);
|
||||
}
|
||||
#endif
|
||||
|
||||
player->score = READUINT32(save->p);
|
||||
player->dashspeed = READFIXED(save->p); // dashing speed
|
||||
@@ -1089,6 +1109,10 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
||||
if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242)
|
||||
return;
|
||||
|
||||
// do not send over locally spawned mobjs
|
||||
if (mobj->islocal)
|
||||
return;
|
||||
|
||||
if (mobj->spawnpoint && mobj->info->doomednum != -1)
|
||||
{
|
||||
// spawnpoint is not modified but we must save it since it is an identifier
|
||||
@@ -1108,11 +1132,23 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
||||
diff2 = 0;
|
||||
|
||||
// not the default but the most probable
|
||||
#ifdef PHOBOS_BUILD
|
||||
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0 || mobj->pmomz !=0)
|
||||
#else
|
||||
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
|
||||
#endif
|
||||
diff |= MD_MOM;
|
||||
#ifdef PHOBOS_BUILD
|
||||
if (mobj->radius != FixedMul(mapobjectscale, mobj->info->radius))
|
||||
#else
|
||||
if (mobj->radius != mobj->info->radius)
|
||||
#endif
|
||||
diff |= MD_RADIUS;
|
||||
#ifdef PHOBOS_BUILD
|
||||
if (mobj->height != FixedMul(mapobjectscale, mobj->info->height))
|
||||
#else
|
||||
if (mobj->height != mobj->info->height)
|
||||
#endif
|
||||
diff |= MD_HEIGHT;
|
||||
if (mobj->flags != mobj->info->flags)
|
||||
diff |= MD_FLAGS;
|
||||
@@ -1155,11 +1191,19 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
||||
diff |= MD_MOVEFACTOR;
|
||||
if (mobj->fuse)
|
||||
diff |= MD_FUSE;
|
||||
#ifdef PHOBOS_BUILD
|
||||
if (mobj->watertop != INT32_MAX)
|
||||
#else
|
||||
if (mobj->watertop)
|
||||
#endif
|
||||
diff |= MD_WATERTOP;
|
||||
if (mobj->waterbottom)
|
||||
diff |= MD_WATERBOTTOM;
|
||||
#ifdef PHOBOS_BUILD
|
||||
if (mobj->scale != mapobjectscale)
|
||||
#else
|
||||
if (mobj->scale != FRACUNIT)
|
||||
#endif
|
||||
diff |= MD_SCALE;
|
||||
if (mobj->destscale != mobj->scale)
|
||||
diff |= MD_DSCALE;
|
||||
@@ -1236,6 +1280,9 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
||||
WRITEFIXED(save->p, mobj->momx);
|
||||
WRITEFIXED(save->p, mobj->momy);
|
||||
WRITEFIXED(save->p, mobj->momz);
|
||||
#ifdef PHOBOS_BUILD
|
||||
WRITEFIXED(save->p, mobj->pmomz);
|
||||
#endif
|
||||
}
|
||||
if (diff & MD_RADIUS)
|
||||
WRITEFIXED(save->p, mobj->radius);
|
||||
@@ -1297,7 +1344,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|
||||
if (diff2 & MD2_CVMEM)
|
||||
WRITEINT32(save->p, mobj->cvmem);
|
||||
if (diff2 & MD2_SKIN)
|
||||
WRITEUINT8(save->p, (UINT8)((skin_t *)mobj->skin - skins));
|
||||
WRITESKIN(save->p, (skinnum_t)((skin_t *)mobj->skin - skins));
|
||||
if (diff2 & MD2_COLOR)
|
||||
WRITEUINT8(save->p, mobj->color);
|
||||
if (diff2 & MD2_EXTVAL1)
|
||||
@@ -2055,16 +2102,27 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
|
||||
mobj->momx = READFIXED(save->p);
|
||||
mobj->momy = READFIXED(save->p);
|
||||
mobj->momz = READFIXED(save->p);
|
||||
#ifdef PHOBOS_BUILD
|
||||
mobj->pmomz = READFIXED(save->p);
|
||||
#endif
|
||||
} // otherwise they're zero, and the memset took care of it
|
||||
|
||||
if (diff & MD_RADIUS)
|
||||
mobj->radius = READFIXED(save->p);
|
||||
else
|
||||
#ifdef PHOBOS_BUILD
|
||||
mobj->radius = FixedMul(mobj->info->radius, mapobjectscale);
|
||||
#else
|
||||
mobj->radius = mobj->info->radius;
|
||||
#endif
|
||||
if (diff & MD_HEIGHT)
|
||||
mobj->height = READFIXED(save->p);
|
||||
else
|
||||
#ifdef PHOBOS_BUILD
|
||||
mobj->height = FixedMul(mobj->info->height, mapobjectscale);
|
||||
#else
|
||||
mobj->height = mobj->info->height;
|
||||
#endif
|
||||
if (diff & MD_FLAGS)
|
||||
mobj->flags = READUINT32(save->p);
|
||||
else
|
||||
@@ -2136,12 +2194,20 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
|
||||
mobj->fuse = READINT32(save->p);
|
||||
if (diff & MD_WATERTOP)
|
||||
mobj->watertop = READFIXED(save->p);
|
||||
#ifdef PHOBOS_BUILD
|
||||
else
|
||||
mobj->watertop = INT32_MAX;
|
||||
#endif
|
||||
if (diff & MD_WATERBOTTOM)
|
||||
mobj->waterbottom = READFIXED(save->p);
|
||||
if (diff & MD_SCALE)
|
||||
mobj->scale = READFIXED(save->p);
|
||||
else
|
||||
#ifdef PHOBOS_BUILD
|
||||
mobj->scale = mapobjectscale;
|
||||
#else
|
||||
mobj->scale = FRACUNIT;
|
||||
#endif
|
||||
if (diff & MD_DSCALE)
|
||||
mobj->destscale = READFIXED(save->p);
|
||||
else
|
||||
@@ -2155,7 +2221,7 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
|
||||
if (diff2 & MD2_CVMEM)
|
||||
mobj->cvmem = READINT32(save->p);
|
||||
if (diff2 & MD2_SKIN)
|
||||
mobj->skin = &skins[READUINT8(save->p)];
|
||||
mobj->skin = &skins[READSKIN(save->p)];
|
||||
if (diff2 & MD2_COLOR)
|
||||
mobj->color = READUINT8(save->p);
|
||||
if (diff2 & MD2_EXTVAL1)
|
||||
|
||||
+2
-2
@@ -24,8 +24,8 @@
|
||||
typedef struct
|
||||
{
|
||||
UINT8 skincolor;
|
||||
UINT8 skin;
|
||||
UINT8 botskin;
|
||||
skinnum_t skin;
|
||||
skinnum_t botskin;
|
||||
UINT8 botcolor;
|
||||
INT32 score;
|
||||
INT32 lives;
|
||||
|
||||
+117
-85
@@ -180,7 +180,7 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
|
||||
// don't use va() because the calling function probably uses it
|
||||
char mapnum[10];
|
||||
|
||||
sprintf(mapnum, "%hd", gamemap);
|
||||
snprintf(mapnum, sizeof(mapnum), "%hd", gamemap);
|
||||
CON_LogMessage("Map ");
|
||||
CON_LogMessage(mapnum);
|
||||
CON_LogMessage(" is corrupt: ");
|
||||
@@ -266,8 +266,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
||||
mapheaderinfo[num]->actnum[0] = '\0';
|
||||
mapheaderinfo[num]->typeoflevel = 0;
|
||||
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
|
||||
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
|
||||
mapheaderinfo[num]->musname[6] = 0;
|
||||
snprintf(mapheaderinfo[num]->musname, sizeof(mapheaderinfo[num]->musname), "%sM", G_BuildMapName(i));
|
||||
mapheaderinfo[num]->musname[sizeof(mapheaderinfo[num]->musname)-1] = 0;
|
||||
mapheaderinfo[num]->mustrack = 0;
|
||||
mapheaderinfo[num]->muspos = 0;
|
||||
mapheaderinfo[num]->forcecharacter[0] = '\0';
|
||||
@@ -318,15 +318,15 @@ void P_AllocMapHeader(INT16 i)
|
||||
// Loads the vertexes for a level.
|
||||
FUNCINLINE static ATTRINLINE void P_LoadVertices(UINT8 *data)
|
||||
{
|
||||
mapvertex_t *ml = (mapvertex_t *)data;
|
||||
vertex_t *li = vertexes;
|
||||
mapvertex_t *mv = (mapvertex_t *)data;
|
||||
vertex_t *v = vertexes;
|
||||
size_t i;
|
||||
|
||||
// Copy and convert vertex coordinates, internal representation as fixed.
|
||||
for (i = 0; i < numvertexes; i++, li++, ml++)
|
||||
for (i = 0; i < numvertexes; i++, v++, mv++)
|
||||
{
|
||||
li->x = SHORT(ml->x)<<FRACBITS;
|
||||
li->y = SHORT(ml->y)<<FRACBITS;
|
||||
v->x = SHORT(mv->x)<<FRACBITS;
|
||||
v->y = SHORT(mv->y)<<FRACBITS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,65 +479,30 @@ static void P_SetupDirectionalLight(void)
|
||||
static void P_LoadSegs(UINT8 *data)
|
||||
{
|
||||
INT32 rawlinedef, rawside;
|
||||
mapseg_t *ml = (mapseg_t*)data;
|
||||
seg_t *li = segs;
|
||||
mapseg_t *ms = (mapseg_t*)data;
|
||||
seg_t *seg = segs;
|
||||
line_t *ldef;
|
||||
size_t i;
|
||||
|
||||
// Set map lighting settings.
|
||||
P_SetupDirectionalLight();
|
||||
|
||||
for (i = 0; i < numsegs; i++, li++, ml++)
|
||||
for (i = 0; i < numsegs; i++, seg++, ms++)
|
||||
{
|
||||
INT16 v1, v2;
|
||||
|
||||
v1 = SHORT(ml->v1);
|
||||
v2 = SHORT(ml->v2);
|
||||
v1 = SHORT(ms->v1);
|
||||
v2 = SHORT(ms->v2);
|
||||
|
||||
// e6y
|
||||
// check and fix wrong references to non-existent vertexes
|
||||
// see e1m9 @ NIVELES.WAD
|
||||
// http://www.doomworld.com/idgames/index.php?id=12647
|
||||
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
|
||||
{
|
||||
if ((unsigned)v1 >= numvertexes)
|
||||
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
|
||||
if ((unsigned)v2 >= numvertexes)
|
||||
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
|
||||
// moved down for additional checks to avoid overflow
|
||||
// if wrong vertexe's indexes are in SEGS lump
|
||||
// see below for more detailed information
|
||||
|
||||
if (li->sidedef == &sides[li->linedef->sidenum[0]])
|
||||
{
|
||||
li->v1 = lines[ml->linedef].v1;
|
||||
li->v2 = lines[ml->linedef].v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
li->v1 = lines[ml->linedef].v2;
|
||||
li->v2 = lines[ml->linedef].v1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
li->v1 = &vertexes[v1];
|
||||
li->v2 = &vertexes[v2];
|
||||
}
|
||||
seg->angle = (SHORT(ms->angle)) << FRACBITS;
|
||||
seg->offset = (SHORT(ms->offset)) << FRACBITS;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
li->fv1.x = FixedToFloat(li->v1->x);
|
||||
li->fv1.y = FixedToFloat(li->v1->y);
|
||||
//li->fv1.z = FixedToFloat(li->v1->z); // z is unused in gl
|
||||
|
||||
li->fv2.x = FixedToFloat(li->v2->x);
|
||||
li->fv2.y = FixedToFloat(li->v2->y);
|
||||
//li->fv2.z = FixedToFloat(li->v2->z);
|
||||
}
|
||||
#endif
|
||||
li->length = P_SegLength(li);
|
||||
li->angle = (SHORT(ml->angle))<<FRACBITS;
|
||||
li->offset = (SHORT(ml->offset))<<FRACBITS;
|
||||
rawlinedef = SHORT(ml->linedef);
|
||||
rawlinedef = SHORT(ms->linedef);
|
||||
|
||||
//e6y: check for wrong indexes
|
||||
if ((unsigned)rawlinedef >= numlines)
|
||||
@@ -546,8 +511,8 @@ static void P_LoadSegs(UINT8 *data)
|
||||
}
|
||||
|
||||
ldef = &lines[rawlinedef];
|
||||
li->linedef = ldef;
|
||||
rawside = SHORT(ml->side);
|
||||
seg->linedef = ldef;
|
||||
rawside = SHORT(ms->side);
|
||||
|
||||
//e6y: fix wrong side index
|
||||
if (rawside != 0 && rawside != 1)
|
||||
@@ -562,9 +527,9 @@ static void P_LoadSegs(UINT8 *data)
|
||||
I_Error("P_LoadSegs: linedef %d for seg %s references a non-existent sidedef %d", rawlinedef, sizeu1(i), ldef->sidenum[rawside]);
|
||||
}
|
||||
|
||||
li->side = rawside;
|
||||
seg->side = rawside;
|
||||
|
||||
li->sidedef = &sides[ldef->sidenum[rawside]];
|
||||
seg->sidedef = &sides[ldef->sidenum[rawside]];
|
||||
|
||||
/* cph 2006/09/30 - our frontsector can be the second side of the
|
||||
* linedef, so must check for NO_INDEX in case we are incorrectly
|
||||
@@ -572,11 +537,11 @@ static void P_LoadSegs(UINT8 *data)
|
||||
if (ldef->sidenum[rawside] == NO_INDEX)
|
||||
{
|
||||
CorruptMapWarning(va("P_LoadSegs: front of seg %s has no sidedef\n", sizeu1(i)));
|
||||
li->frontsector = NULL;
|
||||
seg->frontsector = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
li->frontsector = sides[ldef->sidenum[rawside]].sector;
|
||||
seg->frontsector = sides[ldef->sidenum[rawside]].sector;
|
||||
}
|
||||
|
||||
if (ldef->flags & ML_TWOSIDED)
|
||||
@@ -584,15 +549,56 @@ static void P_LoadSegs(UINT8 *data)
|
||||
if (ldef->sidenum[rawside^1] == NO_INDEX)
|
||||
{
|
||||
CorruptMapWarning(va("P_LoadSegs: back of seg %s has no sidedef while being marked as double sided\n", sizeu1(i)));
|
||||
li->backsector = NULL;
|
||||
seg->backsector = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
li->backsector = sides[ldef->sidenum[rawside^1]].sector;
|
||||
seg->backsector = sides[ldef->sidenum[rawside^1]].sector;
|
||||
}
|
||||
}
|
||||
|
||||
P_UpdateSegLightOffset(li);
|
||||
// e6y
|
||||
// check and fix wrong references to non-existent vertexes
|
||||
// see e1m9 @ NIVELES.WAD
|
||||
// http://www.doomworld.com/idgames/index.php?id=12647
|
||||
if ((unsigned)v1 >= numvertexes || (unsigned)v2 >= numvertexes)
|
||||
{
|
||||
if ((unsigned)v1 >= numvertexes)
|
||||
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v1));
|
||||
if ((unsigned)v2 >= numvertexes)
|
||||
CorruptMapWarning(va("P_LoadSegs: seg %s references a non-existent vertex %d\n", sizeu1(i), v2));
|
||||
|
||||
if (seg->sidedef == &sides[seg->linedef->sidenum[0]])
|
||||
{
|
||||
seg->v1 = lines[rawlinedef].v1;
|
||||
seg->v2 = lines[rawlinedef].v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
seg->v1 = lines[rawlinedef].v2;
|
||||
seg->v2 = lines[rawlinedef].v1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
seg->v1 = &vertexes[v1];
|
||||
seg->v2 = &vertexes[v2];
|
||||
}
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
seg->fv1.x = FixedToFloat(seg->v1->x);
|
||||
seg->fv1.y = FixedToFloat(seg->v1->y);
|
||||
//seg->fv1.z = FixedToFloat(seg->v1->z); // z is unused in gl
|
||||
|
||||
seg->fv2.x = FixedToFloat(seg->v2->x);
|
||||
seg->fv2.y = FixedToFloat(seg->v2->y);
|
||||
//seg->fv2.z = FixedToFloat(seg->v2->z);
|
||||
}
|
||||
#endif
|
||||
seg->length = P_SegLength(seg);
|
||||
|
||||
P_UpdateSegLightOffset(seg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,10 +616,6 @@ FUNCINLINE static ATTRINLINE void P_LoadSubsectors(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_LoadSectors
|
||||
//
|
||||
|
||||
//
|
||||
// levelflats
|
||||
//
|
||||
@@ -665,13 +667,17 @@ static void P_CheckCyanFlat(levelflat_t *levelflat)
|
||||
const char *flatname = W_CheckNameForNum(levelflat->lumpnum);
|
||||
|
||||
// hack for gba rainbow roads cyan floors
|
||||
if (UNLIKELY(memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
|
||||
if (UNLIKELY(flatname && memcmp(flatname, "GBA_RRF5", 8) == 0 && flatname[8] == 0))
|
||||
{
|
||||
levelflat->cyan = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const UINT8 *flat = R_GetFlat(levelflat->lumpnum);
|
||||
|
||||
if (!flat)
|
||||
return;
|
||||
|
||||
const size_t size = W_LumpLength(levelflat->lumpnum);
|
||||
|
||||
for (size_t steppy = 0; steppy < size; steppy++)
|
||||
@@ -791,6 +797,10 @@ INT32 P_CheckLevelFlat(const char *flatname)
|
||||
return (INT32)i;
|
||||
}
|
||||
|
||||
//
|
||||
// P_LoadSectors
|
||||
//
|
||||
|
||||
static const sector_t sector_default = {
|
||||
.nexttag = -1,
|
||||
.firsttag = -1,
|
||||
@@ -1894,7 +1904,7 @@ static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count)
|
||||
// because making both the WAD and PK3 loading code use
|
||||
// the same functions is trickier than it looks for blockmap
|
||||
// -- Monster Iestyn 09/01/18
|
||||
static boolean P_LoadRawBlockMap(UINT8 *data, size_t count)
|
||||
static boolean P_LoadBlockMap(UINT8 *data, size_t count)
|
||||
{
|
||||
if (!count || count >= 0x20000)
|
||||
return false;
|
||||
@@ -2062,14 +2072,14 @@ static void P_LoadReject(UINT8 *data, size_t rejectsize)
|
||||
if (rejectsize < neededsize)
|
||||
{
|
||||
CorruptMapWarning(va("P_LoadReject: REJECT is %s byte%s too small. REJECT might be invalid!\n", sizeu1(neededsize - rejectsize), (neededsize - rejectsize) == 1 ? "" : "s"));
|
||||
#ifdef COMPAT_VANILLA
|
||||
#ifdef PHOBOS_BUILD
|
||||
rejectmatrix = NULL;
|
||||
return;
|
||||
#else
|
||||
// we can pad this and somewhat prevent desyncs
|
||||
// probs not cool if the reject is from a completely different map
|
||||
// but whatever
|
||||
allocsize = neededsize;
|
||||
#else
|
||||
rejectmatrix = NULL;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2084,6 +2094,13 @@ static void P_LoadMapBSP(const virtres_t* virt)
|
||||
virtlump_t* virtsegs = vres_Find(virt, "SEGS");
|
||||
virtlump_t* virtnodes = vres_Find(virt, "NODES");
|
||||
|
||||
if (!virtssectors)
|
||||
I_Error("SSECTORS lump not found");
|
||||
if (!virtsegs)
|
||||
I_Error("SEGS lump not found");
|
||||
if (!virtnodes)
|
||||
I_Error("NODES lump not found");
|
||||
|
||||
numsubsectors = virtssectors->size / sizeof(mapsubsector_t);
|
||||
numnodes = virtnodes->size / sizeof(mapnode_t);
|
||||
numsegs = virtsegs->size / sizeof(mapseg_t);
|
||||
@@ -2120,7 +2137,7 @@ static void P_LoadMapLUT(const virtres_t* virt)
|
||||
rejectmatrix = NULL;
|
||||
}
|
||||
|
||||
if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size)))
|
||||
if (!(virtblockmap && P_LoadBlockMap(virtblockmap->data, virtblockmap->size)))
|
||||
P_CreateBlockMap();
|
||||
}
|
||||
|
||||
@@ -2193,7 +2210,7 @@ void P_SetupLevelSky(INT32 skynum, boolean global)
|
||||
{
|
||||
char skytexname[12];
|
||||
|
||||
sprintf(skytexname, "SKY%d", skynum);
|
||||
snprintf(skytexname, sizeof(skytexname), "SKY%d", skynum);
|
||||
skytexture = R_TextureNumForName(skytexname);
|
||||
levelskynum = skynum;
|
||||
|
||||
@@ -2413,7 +2430,8 @@ static void P_RunLevelScript(const char *scriptname)
|
||||
lumpnum_t lumpnum;
|
||||
char newname[9];
|
||||
|
||||
strlcpy(newname, scriptname, sizeof(newname));
|
||||
strncpy(newname, scriptname, sizeof(newname)-1);
|
||||
newname[sizeof(newname)-1] = '\0';
|
||||
|
||||
lumpnum = W_CheckNumForName(newname);
|
||||
|
||||
@@ -2423,7 +2441,7 @@ static void P_RunLevelScript(const char *scriptname)
|
||||
return;
|
||||
}
|
||||
|
||||
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
|
||||
COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), W_LumpLength(lumpnum));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2438,23 +2456,26 @@ static void P_ForceCharacter(const char *forcecharskin)
|
||||
if (netgame)
|
||||
{
|
||||
char skincmd[33];
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
sprintf(skincmd, "skin2 %s\n", forcecharskin);
|
||||
snprintf(skincmd, sizeof(skincmd), "skin2 %s\n", forcecharskin);
|
||||
CV_Set(&cv_skin2, forcecharskin);
|
||||
|
||||
if (splitscreen > 1)
|
||||
{
|
||||
sprintf(skincmd, "skin3 %s\n", forcecharskin);
|
||||
snprintf(skincmd, sizeof(skincmd), "skin3 %s\n", forcecharskin);
|
||||
CV_Set(&cv_skin3, forcecharskin);
|
||||
|
||||
if (splitscreen > 2)
|
||||
{
|
||||
sprintf(skincmd, "skin4 %s\n", forcecharskin);
|
||||
snprintf(skincmd, sizeof(skincmd), "skin4 %s\n", forcecharskin);
|
||||
CV_Set(&cv_skin4, forcecharskin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(skincmd, "skin %s\n", forcecharskin);
|
||||
snprintf(skincmd, sizeof(skincmd), "skin %s\n", forcecharskin);
|
||||
COM_BufAddText(skincmd);
|
||||
}
|
||||
else
|
||||
@@ -2511,7 +2532,7 @@ static void P_LoadRecordGhosts(void)
|
||||
|
||||
const char *mapname = G_BuildMapName(gamemap);
|
||||
|
||||
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
|
||||
snprintf(gpath, glen, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
|
||||
|
||||
// Best Time ghost
|
||||
if (cv_ghost_besttime.value)
|
||||
@@ -2867,7 +2888,8 @@ static void P_SetupPlayer(void)
|
||||
if (!demo.playback && multiplayer && D_NumPlayers())
|
||||
{
|
||||
static char buf[256];
|
||||
sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int)(time(NULL)), G_BuildMapName(gamemap));
|
||||
|
||||
snprintf(buf, sizeof(buf), "replay"PATHSEP"online"PATHSEP"%d-%s", (int)(time(NULL)), G_BuildMapName(gamemap));
|
||||
|
||||
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
|
||||
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"online", srb2home), 0755);
|
||||
@@ -2984,6 +3006,9 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
CON_Drawer(); // let the user know what we are going to do
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
|
||||
// Initialize sector node list.
|
||||
P_Initsecnode();
|
||||
|
||||
if (netgame || multiplayer)
|
||||
cv_debug = botskin = 0;
|
||||
|
||||
@@ -3049,7 +3074,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
// Don't include these in the fade!
|
||||
char tx[64];
|
||||
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
|
||||
snprintf(tx, 63, "%s%s%s",
|
||||
snprintf(tx, sizeof(tx)-1, "%s%s%s",
|
||||
mapheader->lvlttl,
|
||||
(strlen(mapheader->zonttl) > 0) ? va(" %s",mapheader->zonttl) : // SRB2kart
|
||||
((mapheader->levelflags & LF_NOZONE) ? "" : " Zone"),
|
||||
@@ -3311,6 +3336,7 @@ static boolean P_CheckSoundReplacements(UINT16 wadnum, char *name, size_t i)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// P_CheckReplacMapReplacements
|
||||
//
|
||||
@@ -3403,7 +3429,13 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
{
|
||||
// check if someone tries to load maps locally lol
|
||||
// do this here so we can skip loading the file anyways
|
||||
if (W_CheckAutoLoadContainsMap(wadfilename))
|
||||
int retmap = W_CheckAutoLoadContainsMap(wadfilename);
|
||||
if (retmap == -1)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "addilelocal: file %s was not found or not valid.\n", wadfilename);
|
||||
return UINT16_MAX;
|
||||
}
|
||||
if (retmap > 0)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "addilelocal: locally added file %s contains map data, this WILL cause crashes and desynchs! not added.\n", wadfilename);
|
||||
return UINT16_MAX;
|
||||
|
||||
+33
-20
@@ -1962,13 +1962,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
if (!dest)
|
||||
return;
|
||||
|
||||
const angle_t ang = (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle;
|
||||
const boolean dontstopmove = (line->flags & ML_EFFECT4) == ML_EFFECT4;
|
||||
|
||||
if (bot)
|
||||
P_Teleport(bot, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, (line->flags & ML_BLOCKMONSTERS) == 0, (line->flags & ML_EFFECT4) == ML_EFFECT4);
|
||||
P_Teleport(bot, dest->x, dest->y, dest->z, ang, (line->flags & ML_BLOCKMONSTERS) == 0, dontstopmove);
|
||||
|
||||
if (line->flags & ML_BLOCKMONSTERS)
|
||||
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, false, (line->flags & ML_EFFECT4) == ML_EFFECT4);
|
||||
{
|
||||
P_Teleport(mo, dest->x, dest->y, dest->z, ang, false, dontstopmove);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, true, (line->flags & ML_EFFECT4) == ML_EFFECT4);
|
||||
P_Teleport(mo, dest->x, dest->y, dest->z, ang, true, dontstopmove);
|
||||
// Play the 'bowrwoosh!' sound
|
||||
S_StartSound(dest, sfx_mixup);
|
||||
}
|
||||
@@ -2161,7 +2167,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
newname[1] = 'C';
|
||||
newname[2] = 'R';
|
||||
|
||||
scrnum = sides[line->sidenum[0]].textureoffset>>FRACBITS;
|
||||
scrnum = sides[line->sidenum[0]].textureoffset >> FRACBITS;
|
||||
if (scrnum < 0 || scrnum > 999)
|
||||
{
|
||||
scrnum = 0;
|
||||
@@ -2169,9 +2175,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
}
|
||||
else
|
||||
{
|
||||
newname[5] = (char)('0' + (char)((scrnum/100)));
|
||||
newname[6] = (char)('0' + (char)((scrnum%100)/10));
|
||||
newname[7] = (char)('0' + (char)(scrnum%10));
|
||||
newname[5] = (char)('0' + (char)((scrnum / 100)));
|
||||
newname[6] = (char)('0' + (char)((scrnum % 100) / 10));
|
||||
newname[7] = (char)('0' + (char)(scrnum % 10));
|
||||
}
|
||||
newname[8] = '\0';
|
||||
|
||||
@@ -2184,14 +2190,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
else
|
||||
{
|
||||
// W_CacheLumpNum may not have null terminator, so we need to do this :blobcatgooglyholditsheadinitshands:
|
||||
size_t len = W_LumpLength(lumpnum);
|
||||
char *script = Z_Malloc(len+1, PU_STATIC, NULL);
|
||||
memcpy(script, W_CacheLumpNum(lumpnum, PU_CACHE), len);
|
||||
script[len] = 0;
|
||||
|
||||
COM_BufInsertText(script);
|
||||
|
||||
Z_Free(script);
|
||||
COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), W_LumpLength(lumpnum));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3401,7 +3400,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
||||
break;
|
||||
case 12: // SRB2kart: Invert Encore Remap
|
||||
break;
|
||||
case 15: // no idea but keep it dont want anything to break
|
||||
case 15: // also Invert Encore Remap....
|
||||
break;
|
||||
}
|
||||
DoneSection2:
|
||||
@@ -4611,7 +4610,7 @@ void P_UpdateSpecials(void)
|
||||
// POINT LIMIT
|
||||
P_CheckPointLimit();
|
||||
|
||||
#ifdef COMPAT_VANILLA
|
||||
#ifndef PHOBOS_BUILD
|
||||
// Dynamic slopeness
|
||||
// we run this here only when not joined midrace
|
||||
// for vanilla compat reasons :chaosleep:
|
||||
@@ -5375,6 +5374,11 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
|
||||
case 11: // Custom global gravity!
|
||||
gravity = sector->floorheight/1000;
|
||||
break;
|
||||
|
||||
case 12: // SRB2kart: Invert Encore Remap
|
||||
case 15: // NOTE: vanilla kart checks only for this for some reason!
|
||||
sector->flags |= SF_INVERTENCORE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Process Section 4
|
||||
@@ -5384,6 +5388,10 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
|
||||
if (G_RaceGametype())
|
||||
circuitmap = true;
|
||||
break;
|
||||
|
||||
case 12: // Camera noclip
|
||||
sector->flags |= SF_NOCLIPCAMERA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5468,11 +5476,11 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
|
||||
sectors[s].gravity = §ors[sec].floorheight; // This allows it to change in realtime!
|
||||
|
||||
if (lines[i].flags & ML_NOCLIMB)
|
||||
sectors[s].verticalflip = true;
|
||||
sectors[s].flags |= SF_GRAVITYFLIP;
|
||||
else
|
||||
sectors[s].verticalflip = false;
|
||||
sectors[s].flags &= ~SF_GRAVITYFLIP;
|
||||
|
||||
CheckForReverseGravity = sectors[s].verticalflip;
|
||||
CheckForReverseGravity = (boolean)(sectors[s].flags & SF_GRAVITYFLIP);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -5565,6 +5573,11 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
|
||||
sectors[s].cullheight = &lines[i]; // This allows it to change in realtime!
|
||||
break;
|
||||
|
||||
case 13: // Heat wave effect
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
sectors[s].flags |= SF_HEATWAVE;
|
||||
break;
|
||||
|
||||
case 50: // Insta-Lower Sector
|
||||
EV_DoFloor(&lines[i], instantLower);
|
||||
break;
|
||||
|
||||
+8
-2
@@ -38,6 +38,8 @@
|
||||
#include "i_video.h" // rendermode
|
||||
#include "m_perfstats.h"
|
||||
|
||||
#include "lua_profile.h"
|
||||
|
||||
// Object place
|
||||
#include "m_cheat.h"
|
||||
|
||||
@@ -622,6 +624,8 @@ void P_Ticker(boolean run)
|
||||
}
|
||||
}
|
||||
|
||||
LUA_ResetTicTimers();
|
||||
|
||||
ps_lua_mobjhooks.value.i = 0;
|
||||
ps_checkposition_calls.value.i = 0;
|
||||
|
||||
@@ -629,6 +633,7 @@ void P_Ticker(boolean run)
|
||||
LUA_HookPreThinkFrame();
|
||||
PS_STOP_TIMING(ps_lua_prethinkframe_time);
|
||||
|
||||
// OK! Now that we got all of that sorted, players can think!
|
||||
PS_START_TIMING(ps_playerthink_time);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
@@ -646,7 +651,7 @@ void P_Ticker(boolean run)
|
||||
if (run)
|
||||
{
|
||||
// Dynamic slopeness
|
||||
#ifdef COMPAT_VANILLA
|
||||
#ifndef PHOBOS_BUILD
|
||||
if (midgamejoin) // only run here if we joined midgame to fix some desynchs
|
||||
#endif
|
||||
P_RunDynamicSlopes();
|
||||
@@ -675,6 +680,7 @@ void P_Ticker(boolean run)
|
||||
PS_STOP_TIMING(ps_lua_thinkframe_time);
|
||||
}
|
||||
|
||||
// Run shield positioning
|
||||
P_RunOverlays();
|
||||
P_RunShadows();
|
||||
|
||||
@@ -796,7 +802,7 @@ void P_Ticker(boolean run)
|
||||
if (!player->mo)
|
||||
continue;
|
||||
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
|
||||
|
||||
if (skyVisiblePerPlayer[i] && skybox)
|
||||
{
|
||||
|
||||
+36
-21
@@ -91,7 +91,7 @@ void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move)
|
||||
mo->momx = FixedMul(move, FINECOSINE(angle));
|
||||
|
||||
if (!twodmo(mo))
|
||||
mo->momy = FixedMul(move,FINESINE(angle));
|
||||
mo->momy = FixedMul(move, FINESINE(angle));
|
||||
}
|
||||
|
||||
void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move)
|
||||
@@ -625,15 +625,23 @@ boolean P_EndingMusic(player_t *player)
|
||||
}
|
||||
|
||||
if (G_RaceGametype() && bestlocalpos == MAXPLAYERS+1)
|
||||
sprintf(buffer, "k*fail"); // F-Zero death results theme
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "k*fail"); // F-Zero death results theme
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bestlocalpos == 1)
|
||||
sprintf(buffer, "k*win");
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "k*win");
|
||||
}
|
||||
else if (isPlayerLosing(bestlocalplayer))
|
||||
sprintf(buffer, "k*lose");
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "k*lose");
|
||||
}
|
||||
else
|
||||
sprintf(buffer, "k*ok");
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "k*ok");
|
||||
}
|
||||
}
|
||||
|
||||
S_SpeedMusic(1.0f);
|
||||
@@ -1009,7 +1017,7 @@ boolean P_IsLocalPlayer(const player_t *player)
|
||||
}
|
||||
|
||||
//
|
||||
// P_IsLocalPlayer
|
||||
// P_IsLocalPlayerNum
|
||||
//
|
||||
// Returns true if playernum is
|
||||
// on the local machine.
|
||||
@@ -3553,7 +3561,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
|
||||
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
|
||||
@@ -3618,7 +3626,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
|
||||
// We're inside it! Yess...
|
||||
polysec = po->lines[0]->backsector;
|
||||
|
||||
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
|
||||
if (polysec->flags & SF_NOCLIPCAMERA)
|
||||
{ // Camera noclip polyobj.
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
continue;
|
||||
@@ -3674,7 +3682,8 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
|
||||
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
if (UNLIKELY((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
|
||||
if ((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && (rover->master->frontsector->flags & SF_NOCLIPCAMERA))
|
||||
{
|
||||
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
|
||||
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
|
||||
@@ -4254,7 +4263,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
||||
|
||||
static boolean P_CameraCheckHeatFirstperson(player_t *player, sector_t *sector, fixed_t pviewheight)
|
||||
{
|
||||
if (P_FindSpecialLineFromTag(13, sector->tag, -1) != -1)
|
||||
if (sector->flags & SF_HEATWAVE)
|
||||
return true;
|
||||
|
||||
if (sector->ffloors)
|
||||
@@ -4272,7 +4281,7 @@ static boolean P_CameraCheckHeatFirstperson(player_t *player, sector_t *sector,
|
||||
if (pviewheight <= P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y))
|
||||
continue;
|
||||
|
||||
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
|
||||
if (rover->master->frontsector->flags & SF_HEATWAVE)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4508,27 +4517,33 @@ static void DoABarrelRoll(player_t *player)
|
||||
static void P_DoFunnyDance(player_t *player)
|
||||
{
|
||||
fixed_t bpm; // 140bpm ish
|
||||
fixed_t work, ang, bounce; // hehe squishy
|
||||
|
||||
if (player->spectator || !player->mo || player->kartstuff[k_respawn] || player->mo->salty.jump) // this looks jank as hell during hop
|
||||
I_Assert(player != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(player->mo));
|
||||
|
||||
if (player->spectator)
|
||||
return;
|
||||
|
||||
player->squishdance.bounce = 0;
|
||||
// this looks jank as hell during hop or respawn
|
||||
if (player->kartstuff[k_respawn] || player->salty.jump)
|
||||
return;
|
||||
|
||||
// bpm = FixedDiv((60*TICRATE)<<FRACBITS, FLOAT_TO_FIXED(mapmusic.bpm)); << maybe can get the tempo and beat detection lib to work for bpm autodetection
|
||||
bpm = FixedDiv((60*TICRATE)<<FRACBITS, FLOAT_TO_FIXED((float)cv_squishdancespeed.value));
|
||||
bpm = ((60*TICRATE) / (cv_squishdancespeed.value)) << FRACBITS;
|
||||
|
||||
player->squishdance.work = (player->squishdance.time << FRACBITS) % bpm;
|
||||
work = (player->squishdance.time << FRACBITS) % bpm;
|
||||
|
||||
if (player->squishdance.time >= (FRACUNIT >> 1)) // prevent overflow jump - takes about 15 minutes
|
||||
player->squishdance.time = (player->squishdance.work >> FRACBITS);
|
||||
player->squishdance.time = (work >> FRACBITS);
|
||||
|
||||
player->squishdance.work = FixedDiv(player->squishdance.work*180, bpm);
|
||||
work = FixedDiv(work*180, bpm);
|
||||
|
||||
player->squishdance.ang = ((FixedAngle(player->squishdance.work) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
player->squishdance.bounce = ((FINESINE(player->squishdance.ang) - FRACUNIT/2) / 2);
|
||||
ang = ((FixedAngle(work) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
bounce = ((FINESINE(ang) - FRACUNIT/2) / 2);
|
||||
|
||||
player->mo->spritexscale -= player->squishdance.bounce;
|
||||
player->mo->spriteyscale += player->squishdance.bounce;
|
||||
player->mo->spritexscale -= bounce;
|
||||
player->mo->spriteyscale += bounce;
|
||||
|
||||
player->squishdance.time++;
|
||||
}
|
||||
|
||||
+4
-5
@@ -48,8 +48,7 @@ boolean g_walloffscreen = false;
|
||||
|
||||
boolean R_NoEncore(sector_t *sector, boolean ceiling)
|
||||
{
|
||||
const INT32 invspecial = GETSECSPECIAL(sector->special, 2);
|
||||
boolean invertencore = (invspecial == 12 || invspecial == 15); // keeping this incase its used
|
||||
const boolean invertEncore = (sector->flags & SF_INVERTENCORE);
|
||||
|
||||
#if 0 // perfect implementation
|
||||
const INT32 sprnspecial = GETSECSPECIAL(sector->special, 3);
|
||||
@@ -59,10 +58,10 @@ boolean R_NoEncore(sector_t *sector, boolean ceiling)
|
||||
#endif
|
||||
&& GETSECSPECIAL(sector->special, 4) != 6) // sneaker panel
|
||||
{
|
||||
return invertencore;
|
||||
return invertEncore;
|
||||
}
|
||||
|
||||
if (invertencore)
|
||||
if (invertEncore)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -395,7 +394,7 @@ static void R_AddLine(seg_t *line)
|
||||
// Find the other side!
|
||||
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, -1);
|
||||
|
||||
if (line->linedef == &lines[line2])
|
||||
if (line2 >= 0 && line->linedef == &lines[line2])
|
||||
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->linedef->tag, line2);
|
||||
|
||||
if (line2 >= 0) // found it!
|
||||
|
||||
+13
-5
@@ -307,10 +307,19 @@ typedef struct pslope_s
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SF_FLIPSPECIAL_FLOOR = 1,
|
||||
SF_FLIPSPECIAL_CEILING = 2,
|
||||
SF_FLIPSPECIAL_BOTH = 3,
|
||||
SF_TRIGGERSPECIAL_TOUCH = 4,
|
||||
// flipspecial - planes with effect
|
||||
SF_FLIPSPECIAL_FLOOR = 1,
|
||||
SF_FLIPSPECIAL_CEILING = 1<<1,
|
||||
SF_FLIPSPECIAL_BOTH = (SF_FLIPSPECIAL_FLOOR|SF_FLIPSPECIAL_CEILING),
|
||||
// triggerspecial - conditions under which plane touch causes effect
|
||||
SF_TRIGGERSPECIAL_TOUCH = 1<<2,
|
||||
|
||||
SF_GRAVITYFLIP = 1<<3,
|
||||
SF_HEATWAVE = 1<<4,
|
||||
SF_NOCLIPCAMERA = 1<<5,
|
||||
|
||||
// invert encore color remap status
|
||||
SF_INVERTENCORE = 1<<6,
|
||||
} sectorflags_t;
|
||||
|
||||
//
|
||||
@@ -391,7 +400,6 @@ typedef struct sector_s
|
||||
|
||||
// This points to the master's floorheight, so it can be changed in realtime!
|
||||
fixed_t *gravity; // per-sector gravity
|
||||
boolean verticalflip; // If gravity < 0, then allow flipped physics
|
||||
sectorflags_t flags;
|
||||
|
||||
// Sprite culling feature
|
||||
|
||||
+10
-12
@@ -174,15 +174,10 @@ static void BlendTab_Translucent(UINT8 *table, int style, UINT8 blendamt)
|
||||
{
|
||||
frontrgba = pGammaCorrectedPalette[fg];
|
||||
|
||||
#if 0 // perfect implementation
|
||||
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF);
|
||||
result.rgba = ASTBlendPixel(result, frontrgba, AST_TRANSLUCENT, blendamt);
|
||||
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue);
|
||||
#else // performance scrabbler
|
||||
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF);
|
||||
result.rgba = ASTBlendPixel(result, frontrgba, AST_TRANSLUCENT, blendamt);
|
||||
|
||||
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut_corrected, result.s.red, result.s.green, result.s.blue); // pGammaCorrectedPalette
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,6 +185,7 @@ static void BlendTab_Translucent(UINT8 *table, int style, UINT8 blendamt)
|
||||
static void BlendTab_Subtractive(UINT8 *table, int style, UINT8 blendamt)
|
||||
{
|
||||
INT16 bg, fg;
|
||||
RGBA_t backrgba, frontrgba, result;
|
||||
|
||||
if (table == NULL)
|
||||
I_Error("BlendTab_Subtractive: input table was NULL!");
|
||||
@@ -202,11 +198,11 @@ static void BlendTab_Subtractive(UINT8 *table, int style, UINT8 blendamt)
|
||||
|
||||
for (bg = 0; bg < 0x100; bg++)
|
||||
{
|
||||
backrgba = pLocalPalette[bg]; // intentionally uses pLocalPalette
|
||||
|
||||
for (fg = 0; fg < 0x100; fg++)
|
||||
{
|
||||
RGBA_t backrgba = V_GetColor(bg);
|
||||
RGBA_t frontrgba = V_GetColor(fg);
|
||||
RGBA_t result;
|
||||
frontrgba = pLocalPalette[fg];
|
||||
|
||||
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF);
|
||||
result.s.red = std::max(0, result.s.red - blendamt);
|
||||
@@ -221,17 +217,19 @@ static void BlendTab_Subtractive(UINT8 *table, int style, UINT8 blendamt)
|
||||
static void BlendTab_Modulative(UINT8 *table)
|
||||
{
|
||||
INT16 bg, fg;
|
||||
RGBA_t backrgba, frontrgba, result;
|
||||
|
||||
if (table == NULL)
|
||||
I_Error("BlendTab_Modulative: input table was NULL!");
|
||||
|
||||
for (bg = 0; bg < 0x100; bg++)
|
||||
{
|
||||
backrgba = pGammaCorrectedPalette[bg];
|
||||
|
||||
for (fg = 0; fg < 0x100; fg++)
|
||||
{
|
||||
RGBA_t backrgba = V_GetColor(bg);
|
||||
RGBA_t frontrgba = V_GetColor(fg);
|
||||
RGBA_t result;
|
||||
frontrgba = pGammaCorrectedPalette[fg];
|
||||
|
||||
result.rgba = ASTBlendPixel(backrgba, frontrgba, AST_MODULATE, 0);
|
||||
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut_corrected, result.s.red, result.s.green, result.s.blue);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (C) 1996 by id Software, Inc.
|
||||
// Copyright (C) 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
|
||||
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
|
||||
// Copyright (C) Copyright 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
|
||||
// Copyright (C) 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
|
||||
// Copyright (C) 2013 by James Haley, Stephen McGranahan, et al.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
|
||||
+7
-39
@@ -61,7 +61,6 @@ fixed_t rw_distance = 0;
|
||||
static INT32 rw_x, rw_stopx;
|
||||
static angle_t rw_centerangle;
|
||||
static fixed_t rw_offset;
|
||||
static fixed_t rw_offset2; // for splats
|
||||
static fixed_t rw_scale, rw_scalestep;
|
||||
static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid;
|
||||
static INT32 worldtop, worldbottom, worldhigh, worldlow;
|
||||
@@ -264,12 +263,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
|
||||
else if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
if (lightnum < 0)
|
||||
walllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS - 1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
walllights = R_GetWallLight(lightnum);
|
||||
}
|
||||
|
||||
if (frontsector->heightsec != -1)
|
||||
@@ -371,12 +365,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
|
||||
|
||||
lightnum = rlight->lightnum;
|
||||
|
||||
if (lightnum < 0)
|
||||
xwalllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
xwalllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
xwalllights = scalelight[lightnum];
|
||||
xwalllights = R_GetWallLight(lightnum);
|
||||
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
@@ -824,12 +813,7 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
|
||||
else if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
if (lightnum < 0)
|
||||
walllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
walllights = R_GetWallLight(lightnum);
|
||||
}
|
||||
|
||||
maskedtexturecol = drawseg->thicksidecol;
|
||||
@@ -971,12 +955,7 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
|
||||
|
||||
lightnum = rlight->lightnum;
|
||||
|
||||
if (lightnum < 0)
|
||||
xwalllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
xwalllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
xwalllights = scalelight[lightnum];
|
||||
xwalllights = R_GetWallLight(lightnum);
|
||||
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
@@ -1467,12 +1446,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
|
||||
else if (P_ApplyLightOffset(lightnum, curline->frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
if (lightnum < 0)
|
||||
xwalllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
xwalllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
xwalllights = scalelight[lightnum];
|
||||
xwalllights = R_GetWallLight(lightnum);
|
||||
|
||||
pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
@@ -1882,7 +1856,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
|
||||
// big room fix
|
||||
if (longboi)
|
||||
rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy);
|
||||
rw_distance = (fixed_t)R_CalcSegDist(curline, viewx, viewy);
|
||||
|
||||
ds_p->x1 = rw_x = start;
|
||||
ds_p->x2 = stop;
|
||||
@@ -2551,7 +2525,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
rw_offset = -rw_offset;
|
||||
|
||||
/// don't use texture offset for splats
|
||||
rw_offset2 = rw_offset + curline->offset;
|
||||
rw_offset += sidedef->textureoffset + curline->offset;
|
||||
rw_centerangle = ANGLE_90 + viewangle - rw_normalangle;
|
||||
|
||||
@@ -2564,12 +2537,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
if (lightnum < 0)
|
||||
walllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS - 1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
walllights = R_GetWallLight(lightnum);
|
||||
}
|
||||
|
||||
// if a floor / ceiling plane is on the wrong side
|
||||
|
||||
@@ -22,6 +22,11 @@ extern "C" {
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
FUNCINLINE static ATTRINLINE lighttable_t** R_GetWallLight(INT32 llevel)
|
||||
{
|
||||
return scalelight[CLAMP(llevel, 0, LIGHTLEVELS-1)];
|
||||
}
|
||||
|
||||
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
|
||||
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
|
||||
void R_StoreWallRange(INT32 start, INT32 stop);
|
||||
|
||||
+6
-6
@@ -42,8 +42,8 @@ INT32 numallskins = 0;
|
||||
INT32 numlocalskins = 0;
|
||||
skin_t skins[MAXSKINS];
|
||||
|
||||
UINT8 skinstats[9][9][MAXSKINS];
|
||||
UINT8 skinstatscount[9][9] = {
|
||||
skinnum_t skinstats[9][9][MAXSKINS];
|
||||
skinnum_t skinstatscount[9][9] = {
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
@@ -55,7 +55,7 @@ UINT8 skinstatscount[9][9] = {
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
UINT8 skinsorted[MAXSKINS] = {};
|
||||
skinnum_t skinsorted[MAXSKINS] = {};
|
||||
skin_t localskins[MAXLOCALSKINS] = {};
|
||||
skin_t allskins[MAXSKINS+MAXLOCALSKINS] = {};
|
||||
|
||||
@@ -398,8 +398,8 @@ static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump)
|
||||
static int skinSortFunc(const void *a, const void *b) // tbh i have no clue what the naming conventions for local functions are
|
||||
{
|
||||
int diff = 0;
|
||||
const UINT8 val_a = *(const UINT8 *)a;
|
||||
const UINT8 val_b = *(const UINT8 *)b;
|
||||
const skinnum_t val_a = *(const skinnum_t *)a;
|
||||
const skinnum_t val_b = *(const skinnum_t *)b;
|
||||
const skin_t *in1 = &skins[val_a];
|
||||
const skin_t *in2 = &skins[val_b];
|
||||
|
||||
@@ -474,7 +474,7 @@ static int skinSortFunc(const void *a, const void *b) // tbh i have no clue what
|
||||
void sortSkinGrid(void)
|
||||
{
|
||||
//CONS_Printf("Sorting skin list (%d)...\n", cv_skinselectgridsort.value);
|
||||
qs22j(skinsorted, numskins, sizeof(UINT8), skinSortFunc);
|
||||
qs22j(skinsorted, numskins, sizeof(skinnum_t), skinSortFunc);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
+3
-3
@@ -71,9 +71,9 @@ extern INT32 numskins;
|
||||
extern INT32 numlocalskins;
|
||||
extern INT32 numallskins;
|
||||
extern skin_t skins[MAXSKINS];
|
||||
extern UINT8 skinstats[9][9][MAXSKINS];
|
||||
extern UINT8 skinstatscount[9][9];
|
||||
extern UINT8 skinsorted[MAXSKINS];
|
||||
extern skinnum_t skinstats[9][9][MAXSKINS];
|
||||
extern skinnum_t skinstatscount[9][9];
|
||||
extern skinnum_t skinsorted[MAXSKINS];
|
||||
|
||||
extern skin_t localskins[MAXLOCALSKINS];
|
||||
extern skin_t allskins[MAXSKINS+MAXLOCALSKINS];
|
||||
|
||||
+5
-20
@@ -1062,12 +1062,7 @@ static void R_SplitSprite(vissprite_t *sprite)
|
||||
{
|
||||
INT32 lightnum = R_GetSoftLightlevel(*sector->lightlist[i].lightlevel);
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
spritelights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
spritelights = scalelight[lightnum];
|
||||
spritelights = R_GetWallLight(lightnum);
|
||||
|
||||
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
|
||||
|
||||
@@ -1745,12 +1740,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
}
|
||||
}
|
||||
|
||||
if (lightnum < 0)
|
||||
lights_array = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
lights_array = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
lights_array = scalelight[lightnum];
|
||||
lights_array = R_GetWallLight(lightnum);
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
@@ -2087,16 +2077,11 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
||||
|
||||
if (!sec->numlights)
|
||||
{
|
||||
if (sec->heightsec == -1) lightlevel = sec->lightlevel;
|
||||
if (sec->heightsec == -1)
|
||||
lightlevel = sec->lightlevel;
|
||||
|
||||
lightnum = R_GetSoftLightlevel(lightlevel);
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
spritelights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
spritelights = scalelight[lightnum];
|
||||
spritelights = R_GetWallLight(lightnum);
|
||||
}
|
||||
|
||||
// Handle all things in sector.
|
||||
|
||||
+11
-11
@@ -334,7 +334,7 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx)
|
||||
char namebuf[9];
|
||||
lumpnum_t sfxlump;
|
||||
|
||||
sprintf(namebuf, "ds%s", sfx->name);
|
||||
snprintf(namebuf, sizeof(namebuf), "ds%s", sfx->name);
|
||||
|
||||
sfxlump = W_CheckNumForName(namebuf);
|
||||
if (sfxlump != LUMPERROR)
|
||||
@@ -433,7 +433,7 @@ static boolean S_CheckSameSoundLimit(sfxenum_t sfx_id)
|
||||
return true;
|
||||
|
||||
for (cnum = 0; cnum < numofchannels; cnum++)
|
||||
if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)sfx_id)
|
||||
if (channels[cnum].sfxinfo == &S_sfx[sfx_id])
|
||||
scount++;
|
||||
|
||||
//CONS_Printf("same sound count: %d for sfx: %d\n", scount, sfx_id);
|
||||
@@ -864,18 +864,18 @@ void S_SetSfxVolume(INT32 volume)
|
||||
if (volume < 0 || volume > 31)
|
||||
CONS_Alert(CONS_WARNING, "sfxvolume should be between 0-31\n");
|
||||
|
||||
CV_SetValue(&cv_soundvolume, volume&0x1F);
|
||||
CV_SetValue(&cv_soundvolume, volume & 0x1F);
|
||||
actualsfxvolume = cv_soundvolume.value; // check for change of var
|
||||
|
||||
// now hardware volume
|
||||
I_SetSfxVolume(volume&0x1F);
|
||||
I_SetSfxVolume(volume & 0x1F);
|
||||
}
|
||||
|
||||
void S_ClearSfx(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 1; i < NUMSFX; i++)
|
||||
I_FreeSfx(S_sfx + i);
|
||||
I_FreeSfx(&S_sfx[i]);
|
||||
}
|
||||
|
||||
static void S_StopChannel(INT32 cnum)
|
||||
@@ -1067,12 +1067,12 @@ INT32 S_OriginPlaying(void *origin)
|
||||
|
||||
// Searches through the channels and checks if a given id
|
||||
// is playing anywhere.
|
||||
INT32 S_IdPlaying(sfxenum_t id)
|
||||
INT32 S_IdPlaying(sfxenum_t sfx_id)
|
||||
{
|
||||
INT32 cnum;
|
||||
|
||||
for (cnum = 0; cnum < numofchannels; cnum++)
|
||||
if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)id)
|
||||
if (channels[cnum].sfxinfo == &S_sfx[sfx_id])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -1080,7 +1080,7 @@ INT32 S_IdPlaying(sfxenum_t id)
|
||||
|
||||
// Searches through the channels and checks for
|
||||
// origin x playing sound id y.
|
||||
INT32 S_SoundPlaying(void *origin, sfxenum_t id)
|
||||
INT32 S_SoundPlaying(void *origin, sfxenum_t sfx_id)
|
||||
{
|
||||
INT32 cnum;
|
||||
|
||||
@@ -1089,8 +1089,8 @@ INT32 S_SoundPlaying(void *origin, sfxenum_t id)
|
||||
|
||||
for (cnum = 0; cnum < numofchannels; cnum++)
|
||||
{
|
||||
if (channels[cnum].origin == origin
|
||||
&& (size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)id)
|
||||
if (channels[cnum].origin == origin &&
|
||||
channels[cnum].sfxinfo == &S_sfx[sfx_id])
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2193,7 +2193,7 @@ static void Command_Tunes_f(void)
|
||||
track = (UINT16)atoi(COM_Argv(2))-1;
|
||||
|
||||
if (tunenum)
|
||||
snprintf(mapmusic.name, 7, "%sM", G_BuildMapName(tunenum));
|
||||
snprintf(mapmusic.name, sizeof(mapmusic.name), "%sM", G_BuildMapName(tunenum));
|
||||
else
|
||||
strlcpy(mapmusic.name, tunearg, sizeof(mapmusic.name));
|
||||
|
||||
|
||||
+2
-2
@@ -286,8 +286,8 @@ void S_SetSfxVolume(INT32 volume);
|
||||
void S_SetMusicVolume(INT32 volume);
|
||||
|
||||
INT32 S_OriginPlaying(void *origin);
|
||||
INT32 S_IdPlaying(sfxenum_t id);
|
||||
INT32 S_SoundPlaying(void *origin, sfxenum_t id);
|
||||
INT32 S_IdPlaying(sfxenum_t sfx_id);
|
||||
INT32 S_SoundPlaying(void *origin, sfxenum_t sfx_id);
|
||||
|
||||
void S_StartSoundName(void *mo, const char *soundname);
|
||||
|
||||
|
||||
+16
-3
@@ -177,6 +177,10 @@ if(${SDL2_FOUND})
|
||||
)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
|
||||
target_link_libraries(SRB2SDL2 PRIVATE pthread execinfo)
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM} MATCHES Windows AND ${CMAKE_C_COMPILER_ID} MATCHES "GNU" AND ${SRB2_SYSTEM_BITS} EQUAL 32)
|
||||
target_link_libraries(SRB2SDL2 PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../libs/drmingw/lib/win32/libexchndl.a"
|
||||
@@ -229,20 +233,29 @@ if(${SDL2_FOUND})
|
||||
-DHAVE_THREADS
|
||||
)
|
||||
|
||||
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE)
|
||||
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE AND NOT SRB2_CONFIG_ASAN AND NOT SRB2_CONFIG_UBSAN AND NOT SRB2_CONFIG_TSAN)
|
||||
set_property(TARGET SRB2SDL2 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
|
||||
if(SRB2_CONFIG_ASAN)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=address)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=address -fno-omit-frame-pointer -fno-common)
|
||||
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
|
||||
endif()
|
||||
|
||||
if(SRB2_CONFIG_UBSAN)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=undefined -fno-omit-frame-pointer)
|
||||
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
|
||||
endif()
|
||||
|
||||
if(SRB2_CONFIG_TSAN)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=thread -fno-omit-frame-pointer)
|
||||
target_link_options(SRB2SDL2 PRIVATE -fsanitize=thread)
|
||||
endif()
|
||||
|
||||
if(NOT SRB2_CONFIG_MUMBLE)
|
||||
target_compile_options(SRB2SDL2 PRIVATE -DNOMUMBLE)
|
||||
endif()
|
||||
|
||||
## strip debug symbols into separate file when using gcc
|
||||
# if(CMAKE_COMPILER_IS_GNUCC)
|
||||
# if(${CMAKE_BUILD_TYPE} MATCHES Debug)
|
||||
|
||||
+74
-35
@@ -57,10 +57,13 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (__unix__) || defined (UNIXCOMMON)
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
@@ -577,7 +580,7 @@ void I_OutputMsg(const char *fmt, ...)
|
||||
I_Error("I_OutputMsg: Out of memory!\n");
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsprintf(txt, fmt, argptr);
|
||||
vsnprintf(txt, len+1, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
#ifdef HAVE_TTF
|
||||
@@ -585,7 +588,7 @@ void I_OutputMsg(const char *fmt, ...)
|
||||
DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt);
|
||||
#endif
|
||||
|
||||
len = strlen(txt);
|
||||
len = strnlen(txt, len+1);
|
||||
|
||||
#ifdef LOGMESSAGES
|
||||
if (logstream)
|
||||
@@ -983,13 +986,13 @@ void I_InitJoystick(UINT8 index)
|
||||
|
||||
{
|
||||
char dbpath[1024];
|
||||
sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb.txt", srb2path);
|
||||
snprintf(dbpath, sizeof(dbpath), "%s" PATHSEP "gamecontrollerdb.txt", srb2path);
|
||||
SDL_GameControllerAddMappingsFromFile(dbpath);
|
||||
}
|
||||
|
||||
{
|
||||
char dbpath[1024];
|
||||
sprintf(dbpath, "%s" PATHSEP "gamecontrollerdb_user.txt", srb2home);
|
||||
snprintf(dbpath, sizeof(dbpath), "%s" PATHSEP "gamecontrollerdb_user.txt", srb2home);
|
||||
SDL_GameControllerAddMappingsFromFile(dbpath);
|
||||
}
|
||||
|
||||
@@ -1018,6 +1021,8 @@ void I_InitJoystick(UINT8 index)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // no dont do this
|
||||
// reset everything just in case
|
||||
JoyInfo[index].dev = NULL;
|
||||
JoyInfo[index].oldjoy = -1;
|
||||
#if (SDL_VERSION_ATLEAST(2,32,4))
|
||||
@@ -1025,6 +1030,7 @@ void I_InitJoystick(UINT8 index)
|
||||
#endif
|
||||
JoyInfo[index].hasled = false;
|
||||
JoyInfo[index].hasrumble = false;
|
||||
#endif
|
||||
|
||||
if (cv_usejoystick[index].value)
|
||||
newcontroller = SDL_GameControllerOpen(cv_usejoystick[index].value-1);
|
||||
@@ -1151,8 +1157,7 @@ const char *I_GetJoyName(INT32 joyindex)
|
||||
|
||||
if (tempname)
|
||||
{
|
||||
memcpy(joyname, tempname, 255);
|
||||
joyname[255] = '\0';
|
||||
snprintf(joyname, sizeof(joyname), "%s", tempname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1279,7 +1284,7 @@ static void I_SetupMumble(void)
|
||||
int shmfd;
|
||||
char memname[256];
|
||||
|
||||
snprintf(memname, 256, "/MumbleLink.%d", getuid());
|
||||
snprintf(memname, sizeof(memname), "/MumbleLink.%d", getuid());
|
||||
shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR);
|
||||
|
||||
if (shmfd < 0)
|
||||
@@ -1396,19 +1401,31 @@ void I_Sleep(UINT32 ms)
|
||||
|
||||
void I_SleepDuration(precise_t duration)
|
||||
{
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__) || defined(__OpenBSD__)
|
||||
UINT64 precision = I_GetPrecisePrecision();
|
||||
precise_t dest = I_GetPreciseTime() + duration;
|
||||
#ifdef __OpenBSD__
|
||||
precise_t slack = (precision / 50); // 20 ms slack
|
||||
#else
|
||||
precise_t slack = (precision / 5000); // 0.2 ms slack
|
||||
#endif
|
||||
if (duration > slack)
|
||||
{
|
||||
duration -= slack;
|
||||
struct timespec ts = {
|
||||
.tv_sec = static_cast<__time_t>(duration / precision),
|
||||
#ifdef __BIONIC__
|
||||
.tv_nsec = static_cast<long>(duration * 1000000000 / precision % 1000000000),
|
||||
#else
|
||||
.tv_nsec = static_cast<__syscall_slong_t>(duration * 1000000000 / precision % 1000000000),
|
||||
#endif
|
||||
};
|
||||
int status;
|
||||
#ifdef __OpenBSD__
|
||||
do status = nanosleep(&ts, &ts);
|
||||
#else
|
||||
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
|
||||
#endif
|
||||
while (status == EINTR);
|
||||
}
|
||||
|
||||
@@ -1693,16 +1710,20 @@ static void I_PrintSignal(INT32 signal_num, boolean core_dumped, char *signal_ms
|
||||
if (core_dumped)
|
||||
{
|
||||
if (sigmsg)
|
||||
sprintf(signal_msg, "%s (core dumped)", sigmsg);
|
||||
{
|
||||
snprintf(signal_msg, 512, "%s (core dumped)", sigmsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(signal_msg, " (core dumped)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(signal_msg, "%s", sigmsg);
|
||||
snprintf(signal_msg, 512, "%s", sigmsg);
|
||||
}
|
||||
|
||||
sprintf(signal_name, "%s", signame);
|
||||
snprintf(signal_name, 128, "%s", signame);
|
||||
}
|
||||
|
||||
int I_OpenURL(const char *url)
|
||||
@@ -1880,7 +1901,7 @@ FUNCNORETURN static ATTRNORETURN void newsignalhandler_Warn(const char *pr)
|
||||
{
|
||||
char text[128];
|
||||
|
||||
snprintf(text, sizeof text,
|
||||
snprintf(text, sizeof(text),
|
||||
"Error while setting up signal reporting: %s: %s",
|
||||
pr,
|
||||
strerror(errno)
|
||||
@@ -2096,7 +2117,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
|
||||
if (errorcount > 20)
|
||||
{
|
||||
va_start(argptr, error);
|
||||
vsnprintf(buffer, 8192, error, argptr);
|
||||
vsnprintf(buffer, sizeof(buffer), error, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
sigttl = "SRB2Kart " VERSIONSTRING " Recursive Error";
|
||||
@@ -2110,7 +2131,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
|
||||
|
||||
// Display error message in the console before we start shutting it down
|
||||
va_start(argptr, error);
|
||||
vsnprintf(buffer, 8192, error, argptr);
|
||||
vsnprintf(buffer, sizeof(buffer), error, argptr);
|
||||
va_end(argptr);
|
||||
I_OutputMsg("\nI_Error(): %s\n", buffer);
|
||||
|
||||
@@ -2253,6 +2274,7 @@ void I_ShutdownSystem(void)
|
||||
for (c = MAX_QUIT_FUNCS-1; c >= 0; c--)
|
||||
if (quit_funcs[c])
|
||||
(*quit_funcs[c])();
|
||||
|
||||
#ifdef LOGMESSAGES
|
||||
if (logstream)
|
||||
{
|
||||
@@ -2337,7 +2359,8 @@ char *I_GetUserName(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
strncpy(username, p, MAXPLAYERNAME);
|
||||
|
||||
snprintf(username, sizeof(username), "%s", p);
|
||||
}
|
||||
|
||||
if (!fastcmp(username, ""))
|
||||
@@ -2361,6 +2384,24 @@ INT32 I_mkdir(const char *dirname, INT32 unixright)
|
||||
#endif
|
||||
}
|
||||
|
||||
INT32 I_ChDir(const char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (SetCurrentDirectoryA(path) ? 0 : -1);
|
||||
#else
|
||||
return chdir(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *I_GetCwd(char *buf, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (GetCurrentDirectoryA((DWORD)size, buf) ? buf : NULL);
|
||||
#else
|
||||
return getcwd(buf, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *I_GetEnv(const char *name)
|
||||
{
|
||||
#ifdef NEED_SDL_GETENV
|
||||
@@ -2382,13 +2423,15 @@ INT32 I_PutEnv(char *variable)
|
||||
INT32 I_ClipboardCopy(const char *data, size_t size)
|
||||
{
|
||||
char storage[256];
|
||||
|
||||
if (size > 255)
|
||||
size = 255;
|
||||
memcpy(storage, data, size);
|
||||
storage[size] = 0;
|
||||
|
||||
snprintf(storage, sizeof(storage), "%.*s", (int)size, data);
|
||||
|
||||
if (SDL_SetClipboardText(storage))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2401,7 +2444,7 @@ const char *I_ClipboardPaste(void)
|
||||
return NULL;
|
||||
|
||||
clipboard_contents = SDL_GetClipboardText();
|
||||
strlcpy(clipboard_modified, clipboard_contents, 256);
|
||||
snprintf(clipboard_modified, sizeof(clipboard_modified), "%s", clipboard_contents);
|
||||
SDL_free(clipboard_contents);
|
||||
|
||||
while (*i)
|
||||
@@ -2417,6 +2460,7 @@ const char *I_ClipboardPaste(void)
|
||||
*i = '?'; // Nonprintable chars become question marks
|
||||
++i;
|
||||
}
|
||||
|
||||
return (const char *)&clipboard_modified;
|
||||
}
|
||||
|
||||
@@ -2430,28 +2474,23 @@ const char *I_ClipboardPaste(void)
|
||||
*/
|
||||
static boolean isWadPathOk(const char *path)
|
||||
{
|
||||
char *wad3path = static_cast<char*>(malloc(256));
|
||||
char wad3path[256];
|
||||
|
||||
if (!wad3path)
|
||||
return false;
|
||||
|
||||
sprintf(wad3path, pandf, path, WADKEYWORD);
|
||||
snprintf(wad3path, sizeof(wad3path), pandf, path, WADKEYWORD);
|
||||
|
||||
if (FIL_ReadFileOK(wad3path))
|
||||
{
|
||||
free(wad3path);
|
||||
return true;
|
||||
}
|
||||
|
||||
free(wad3path);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void pathonly(char *s)
|
||||
static void pathonly(char *s, size_t size)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
for (j = strlen(s); j != (size_t)-1; j--)
|
||||
for (j = strnlen(s, size); j != (size_t)-1; j--)
|
||||
{
|
||||
if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/'))
|
||||
{
|
||||
@@ -2478,11 +2517,12 @@ static const char *searchWad(const char *searchDir)
|
||||
static char tempsw[256] = "";
|
||||
filestatus_t fstemp;
|
||||
|
||||
strcpy(tempsw, WADKEYWORD);
|
||||
snprintf(tempsw, sizeof(tempsw), "%s", WADKEYWORD);
|
||||
fstemp = filesearch(tempsw, searchDir, NULL, true, 20);
|
||||
|
||||
if (fstemp == FS_FOUND)
|
||||
{
|
||||
pathonly(tempsw);
|
||||
pathonly(tempsw, sizeof(tempsw));
|
||||
return tempsw;
|
||||
}
|
||||
|
||||
@@ -2520,7 +2560,7 @@ static const char *locateWad(void)
|
||||
|
||||
#ifndef NOCWD
|
||||
// examine current dir
|
||||
strcpy(returnWadPath, ".");
|
||||
snprintf(returnWadPath, sizeof(returnWadPath), "%s", ".");
|
||||
I_OutputMsg(",%s", returnWadPath);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return NULL;
|
||||
@@ -2532,7 +2572,7 @@ static const char *locateWad(void)
|
||||
// examine user jart directory
|
||||
if ((envstr = I_GetEnv("HOME")) != NULL)
|
||||
{
|
||||
sprintf(returnWadPath, "%s" PATHSEP DEFAULTDIR, envstr);
|
||||
snprintf(returnWadPath, sizeof(returnWadPath), "%s" PATHSEP DEFAULTDIR, envstr);
|
||||
CHECKWADPATH(returnWadPath);
|
||||
}
|
||||
#endif
|
||||
@@ -2546,7 +2586,7 @@ static const char *locateWad(void)
|
||||
// examine default dirs
|
||||
for (i = 0; wadDefaultPaths[i]; i++)
|
||||
{
|
||||
strcpy(returnWadPath, wadDefaultPaths[i]);
|
||||
snprintf(returnWadPath, sizeof(returnWadPath), "%s", wadDefaultPaths[i]);
|
||||
CHECKWADPATH(returnWadPath);
|
||||
}
|
||||
|
||||
@@ -2574,12 +2614,11 @@ extern "C" const char *I_LocateWad(void)
|
||||
// change to the directory where we found srb2.srb
|
||||
#if defined (_WIN32)
|
||||
waddir = _fullpath(NULL, waddir, MAX_PATH);
|
||||
SetCurrentDirectoryA(waddir);
|
||||
#else
|
||||
waddir = realpath(waddir, NULL);
|
||||
if (waddir == NULL || chdir(waddir) == -1)
|
||||
I_OutputMsg("Couldn't change working directory\n");
|
||||
#endif
|
||||
if (waddir == NULL || I_ChDir(waddir) == -1)
|
||||
I_OutputMsg("Couldn't change working directory\n");
|
||||
}
|
||||
|
||||
return waddir;
|
||||
|
||||
+8
-2
@@ -183,13 +183,17 @@ void I_TTFDrawText(TTF_Font *font, TextQuality quality, INT32 fgR, INT32 fgG, IN
|
||||
TTFRect.x = TTFRectCheck.x;
|
||||
TTFRect.y = TTFRectCheck.y;
|
||||
}
|
||||
|
||||
// Copy the character to the text buffer.
|
||||
sprintf(textbuffer, "%s%c", textbuffer, c);
|
||||
snprintf(textbuffer, sizeof(textbuffer), "%s%c", textbuffer, c);
|
||||
|
||||
// Hack to allow TTF_SizeText to work properly.
|
||||
sprintf(linebuffer, "%c", c);
|
||||
snprintf(linebuffer, sizeof(linebuffer), "%c", c);
|
||||
|
||||
// If we have reached the end of the screen, move to the next available line.
|
||||
TTF_SizeText(currentfont, linebuffer, &w, &h);
|
||||
TTFRectCheck.x += w;
|
||||
|
||||
if (TTFRectCheck.x >= res.width)
|
||||
{
|
||||
// Render cached text to the SDL surface.
|
||||
@@ -204,8 +208,10 @@ void I_TTFDrawText(TTF_Font *font, TextQuality quality, INT32 fgR, INT32 fgG, IN
|
||||
TTFRect.y = TTFRectCheck.y;
|
||||
}
|
||||
}
|
||||
|
||||
// Add 1 to the pointer reference for the character to process.
|
||||
textmsg++;
|
||||
|
||||
// Copy contents of the now-old buffer to somewhere else, so it can be referenced in next loop.
|
||||
prevc = c;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1538,9 +1538,9 @@ const char *VID_GetModeName(INT32 modeNum)
|
||||
if (modeNum > MAXWINMODES)
|
||||
return NULL;
|
||||
|
||||
sprintf(&vidModeName[modeNum][0], "%dx%d",
|
||||
windowedModes[modeNum][0],
|
||||
windowedModes[modeNum][1]);
|
||||
snprintf(&vidModeName[modeNum][0], sizeof(vidModeName[modeNum]), "%dx%d",
|
||||
windowedModes[modeNum][0],
|
||||
windowedModes[modeNum][1]);
|
||||
|
||||
return &vidModeName[modeNum][0];
|
||||
}
|
||||
|
||||
@@ -868,7 +868,7 @@ boolean I_SetSongSpeed(float speed)
|
||||
{
|
||||
// deprecated in 0.5.0
|
||||
char modspd[13];
|
||||
sprintf(modspd, "%g", speed);
|
||||
snprintf(modspd, sizeof(modspd), "%g", speed);
|
||||
openmpt_module_ctl_set(openmpt_mhandle, "play.tempo_factor", modspd);
|
||||
}
|
||||
#else
|
||||
|
||||
+3
-3
@@ -410,7 +410,7 @@ static void ST_drawDebugInfo(void)
|
||||
}
|
||||
|
||||
if (cv_debug & DBG_MEMORY)
|
||||
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)));
|
||||
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TotalUsage()>>10)));
|
||||
}
|
||||
|
||||
static void ST_drawLevelTitle(void)
|
||||
@@ -568,7 +568,7 @@ static void ST_overlayDrawer(void)
|
||||
{
|
||||
if (!(multiplayer && demo.playback))
|
||||
{
|
||||
if(!P_IsLocalPlayer(stplyr))
|
||||
if (!P_IsLocalPlayer(stplyr))
|
||||
{
|
||||
/*char name[MAXPLAYERNAME+1];
|
||||
// shorten the name if its more than twelve characters.
|
||||
@@ -591,7 +591,7 @@ static void ST_overlayDrawer(void)
|
||||
char name[MAXPLAYERNAME+12];
|
||||
|
||||
INT32 y = (stplyrnum == 0) ? 4 : BASEVIDHEIGHT/2-12;
|
||||
sprintf(name, "VIEWPOINT: %s", player_names[stplyr-players]);
|
||||
snprintf(name, sizeof(name), "VIEWPOINT: %s", player_names[stplyr-players]);
|
||||
V_DrawRightAlignedThinString(BASEVIDWIDTH-40, y, V_HUDTRANSHALF|V_ALLOWLOWERCASE|K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOBOTTOM|V_SNAPTORIGHT), name);
|
||||
}
|
||||
else if (splitscreen)
|
||||
|
||||
Loaded 100 of 106 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user