Compare commits
261
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 | ||
|
|
31517ebebe | ||
|
|
3a2e009d01 | ||
|
|
38e50a3cfb | ||
|
|
97555bc263 | ||
|
|
848115d105 | ||
|
|
3668c2c4f3 | ||
|
|
d5f68bf2aa | ||
|
|
3ae968f060 | ||
|
|
d73f79509e | ||
|
|
19e9eedce3 | ||
|
|
8880057ff2 | ||
|
|
9692484d2e | ||
|
|
df3a64339c | ||
|
|
5a966aa317 | ||
|
|
a132db9e6e | ||
|
|
0acfc96812 | ||
|
|
f09c61cee9 | ||
|
|
735c4b67dc | ||
|
|
267a758447 | ||
|
|
6892c212d1 | ||
|
|
a1127068df | ||
|
|
7ee93d889e | ||
|
|
ee9c9e2839 | ||
|
|
28c4061a26 | ||
|
|
d0f02f1530 | ||
|
|
53fbbecbcd | ||
|
|
587f24ae85 | ||
|
|
ba0b414062 | ||
|
|
b27b4bfd7a | ||
|
|
7971f76885 | ||
|
|
7048eeacc3 | ||
|
|
8a62f4e978 | ||
|
|
f5fdf917bd | ||
|
|
b9ac91c74f | ||
|
|
b408a098bd | ||
|
|
90ab1f4994 | ||
|
|
96484c94db | ||
|
|
c805fa9f33 | ||
|
|
29159ca5cd | ||
|
|
b6b70ae8f0 | ||
|
|
2b0e4b7468 | ||
|
|
c374bd75fc | ||
|
|
ec70e8aa29 | ||
|
|
3ad6159e85 | ||
|
|
2ae1e0f56e | ||
|
|
2302d4efbd | ||
|
|
be08c9cd1f | ||
|
|
7b91666db9 | ||
|
|
ba5c85ba8a | ||
|
|
05e8771fbc | ||
|
|
59b7b0529f | ||
|
|
3fa8ab442a | ||
|
|
fdd8381258 | ||
|
|
41cbce3ed3 | ||
|
|
63e4c5a63d | ||
|
|
bba86fe4af | ||
|
|
1dee3060dd | ||
|
|
56c2178bde | ||
|
|
e445669521 | ||
|
|
7a309bc0b8 | ||
|
|
8b6ebfbad4 | ||
|
|
5775c12b16 | ||
|
|
78ebc14d88 | ||
|
|
38a248193e | ||
|
|
934f2d347c | ||
|
|
551d7d4d89 | ||
|
|
a2184d2bef | ||
|
|
d638baeda6 | ||
|
|
4a06e8a6d1 | ||
|
|
e2a3992787 | ||
|
|
ec06150432 | ||
|
|
2413a3503c | ||
|
|
d9e339cb56 | ||
|
|
408db7a2eb | ||
|
|
e12ecabcf0 | ||
|
|
65c2d2733d | ||
|
|
00aa023e9e | ||
|
|
f43a4a2eb6 | ||
|
|
4eb108e0a6 | ||
|
|
ea76af5a81 | ||
|
|
4b8f998c85 | ||
|
|
d687be4997 | ||
|
|
1bcadf3c46 | ||
|
|
80e4d02c51 | ||
|
|
352d1faacf | ||
|
|
7f9d70285d | ||
|
|
496477fa9a | ||
|
|
530bb50709 | ||
|
|
8bb04a68a8 | ||
|
|
820ab4b2bc | ||
|
|
af6abb5458 | ||
|
|
5c373b6251 | ||
|
|
24bac9c133 | ||
|
|
73c7a5a0c4 | ||
|
|
49d6374505 | ||
|
|
2ba4757c6a | ||
|
|
3606b0ae66 | ||
|
|
ba75523d48 | ||
|
|
71640202ed | ||
|
|
5fb5af05be | ||
|
|
4f036c9312 | ||
|
|
d99c272a79 | ||
|
|
c4ed75fbc6 | ||
|
|
91927e324b | ||
|
|
13dc0db9a9 | ||
|
|
8aafde4c9d | ||
|
|
266a4effb7 | ||
|
|
948c9399de | ||
|
|
db4aedf498 | ||
|
|
f12d5a246d | ||
|
|
6efe56808a | ||
|
|
ec047151e3 | ||
|
|
b1100d6215 | ||
|
|
cb8df4c3d0 | ||
|
|
fbae43f61a | ||
|
|
7ea95b4495 | ||
|
|
07c780dc9c | ||
|
|
f6d3ab1f3a | ||
|
|
2c8099e228 | ||
|
|
7c84dd5661 | ||
|
|
cabd8baae5 | ||
|
|
593540a3f9 | ||
|
|
407af1d25c |
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
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@ include Makefile.d/haiku.mk
|
||||
else ifdef SOLARIS # FIXME: UNTESTED
|
||||
UNIX=1
|
||||
platform=solaris
|
||||
else ifdef CYGWIN32 # FIXME: UNTESTED
|
||||
platform=cygwin
|
||||
else ifdef MINGW
|
||||
ifdef MINGW64
|
||||
NONX86=1
|
||||
|
||||
@@ -15,16 +15,6 @@ sources+=$(call List,sdl/Sourcefile)
|
||||
|
||||
NOUPNP=1
|
||||
|
||||
# FIXME: UNTESTED
|
||||
#ifdef PANDORA
|
||||
#include sdl/SRB2Pandora/Makefile.cfg
|
||||
#endif #ifdef PANDORA
|
||||
|
||||
# FIXME: UNTESTED
|
||||
#ifdef CYGWIN32
|
||||
#include sdl/MakeCYG.cfg
|
||||
#endif #ifdef CYGWIN32
|
||||
|
||||
ifndef NOHW
|
||||
sources+=sdl/ogl_sdl.c
|
||||
endif
|
||||
|
||||
@@ -99,3 +99,4 @@ lua_skinlib.c
|
||||
lua_thinkerlib.c
|
||||
lua_udatalib.c
|
||||
lua_glib.c
|
||||
lua_profile.cpp
|
||||
@@ -34,8 +34,8 @@ size_t I_GetFreeMem(size_t *total)
|
||||
/* return si.freeram; */
|
||||
char buf[1024];
|
||||
char *memTag;
|
||||
UINT32 freeKBytes;
|
||||
UINT32 totalKBytes;
|
||||
size_t freeKBytes;
|
||||
size_t totalKBytes;
|
||||
INT32 n;
|
||||
INT32 meminfo_fd = -1;
|
||||
|
||||
@@ -46,7 +46,7 @@ size_t I_GetFreeMem(size_t *total)
|
||||
if (n < 0)
|
||||
{
|
||||
// Error
|
||||
*total = 0L;
|
||||
*total = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ size_t I_GetFreeMem(size_t *total)
|
||||
if (NULL == (memTag = strstr(buf, MEMTOTAL)))
|
||||
{
|
||||
// Error
|
||||
*total = 0L;
|
||||
*total = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ size_t I_GetFreeMem(size_t *total)
|
||||
if (NULL == (memTag = strstr(buf, MEMFREE)))
|
||||
{
|
||||
// Error
|
||||
*total = 0L;
|
||||
*total = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+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);
|
||||
|
||||
+6
-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.
|
||||
@@ -114,6 +114,7 @@ void* PoolAllocator::allocate()
|
||||
|
||||
FreeBlock* ret = head_;
|
||||
head_ = head_->next;
|
||||
allocated_blocks_++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -125,6 +126,7 @@ void PoolAllocator::deallocate(void* p)
|
||||
FreeBlock* block = reinterpret_cast<FreeBlock*>(p);
|
||||
block->next = head_;
|
||||
head_ = block;
|
||||
allocated_blocks_--;
|
||||
}
|
||||
|
||||
void PoolAllocator::release()
|
||||
@@ -144,6 +146,7 @@ void PoolAllocator::release()
|
||||
|
||||
first_chunk_ = nullptr;
|
||||
head_ = nullptr;
|
||||
allocated_blocks_ = 0;
|
||||
}
|
||||
|
||||
static LinearMemory g_frame_memory {4 * 1024 * 1024};
|
||||
|
||||
+7
-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.
|
||||
@@ -37,6 +37,7 @@ class PoolAllocator final
|
||||
FreeBlock* head_;
|
||||
size_t block_size_;
|
||||
size_t blocks_;
|
||||
size_t allocated_blocks_;
|
||||
int32_t tag_;
|
||||
|
||||
ChunkFooter* allocate_chunk();
|
||||
@@ -47,6 +48,7 @@ public:
|
||||
, head_(nullptr)
|
||||
, block_size_(block_size)
|
||||
, blocks_(blocks)
|
||||
, allocated_blocks_(0)
|
||||
, tag_(tag)
|
||||
{}
|
||||
PoolAllocator(const PoolAllocator&) = delete;
|
||||
@@ -59,6 +61,8 @@ public:
|
||||
void* allocate();
|
||||
void deallocate(void* p);
|
||||
constexpr size_t block_size() const noexcept { return block_size_; };
|
||||
constexpr size_t allocated_blocks() const noexcept { return allocated_blocks_; };
|
||||
constexpr size_t allocated_bytes() const noexcept { return allocated_blocks_ * block_size_; };
|
||||
|
||||
void release();
|
||||
};
|
||||
|
||||
@@ -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.
|
||||
|
||||
+156
-80
@@ -110,7 +110,7 @@ SINT8 joinnode = 0; // used for CL_VIEWSERVER
|
||||
boolean player_muted[MAXPLAYERS] = {};
|
||||
|
||||
// Server specific vars
|
||||
UINT8 playernode[MAXPLAYERS] = {};
|
||||
UINT8 playernode[MAXPLAYERS] = {UINT8_MAX};
|
||||
|
||||
// Minimum timeout for sending the savegame
|
||||
// The actual timeout will be longer depending on the savegame length
|
||||
@@ -841,11 +841,13 @@ static void resynch_write_ctf(resynchend_pak *rst)
|
||||
rst->flagplayer[i] = (SINT8)j;
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == MAXPLAYERS) // fine, no I_Error
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "One of the flags has gone completely missing...\n");
|
||||
rst->flagplayer[i] = -2;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1123,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;
|
||||
@@ -1135,6 +1137,7 @@ static void CV_SavePlayerNames(UINT8 **p)
|
||||
WRITEUINT8(*p, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
WRITESTRING(*p, player_names[i]);
|
||||
}
|
||||
}
|
||||
@@ -1148,13 +1151,17 @@ static void CV_LoadPlayerNames(UINT8 **p)
|
||||
for (; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
READSTRING(*p, tmp_name);
|
||||
|
||||
if (tmp_name[0] == 0)
|
||||
continue;
|
||||
|
||||
if (tmp_name[MAXPLAYERNAME]) // overflow detected
|
||||
I_Error("Received bad server config packet when trying to join");
|
||||
|
||||
memcpy(player_names[i], tmp_name, MAXPLAYERNAME+1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void CL_DrawAddonTypes(void)
|
||||
{
|
||||
@@ -1449,6 +1456,7 @@ static void CL_DrawConnectionStatus(void)
|
||||
if (playerinfo[i].node < 255)
|
||||
{
|
||||
strncpy(player_name, playerinfo[i].name, MAXPLAYERNAME);
|
||||
player_name[MAXPLAYERNAME] = '\0';
|
||||
|
||||
// if we get a skin color
|
||||
// try to colourize the player name
|
||||
@@ -1622,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
|
||||
@@ -1648,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);
|
||||
|
||||
@@ -1762,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;
|
||||
|
||||
@@ -1807,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;
|
||||
@@ -1917,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);
|
||||
@@ -1936,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));
|
||||
@@ -1951,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;
|
||||
@@ -1958,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)
|
||||
@@ -2028,6 +2047,7 @@ static void SV_SendSaveGame(INT32 node, boolean resending)
|
||||
P_SaveNetGame(&save, resending);
|
||||
|
||||
length = save.p - save.buffer;
|
||||
|
||||
if (length > SAVEGAMESIZE)
|
||||
{
|
||||
Z_Free(save.buffer);
|
||||
@@ -2086,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);
|
||||
@@ -2124,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);
|
||||
|
||||
@@ -2180,7 +2200,8 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
||||
if (unlink(tmpsave) == -1)
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||
consistancy[gametic%BACKUPTICS] = Consistancy();
|
||||
CON_ToggleOff();
|
||||
if (!reloading)
|
||||
CON_ToggleOff();
|
||||
|
||||
#ifdef SATURNPAK
|
||||
// Tell the server we have received and reloaded the gamestate
|
||||
@@ -2202,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);
|
||||
@@ -2938,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;
|
||||
@@ -3326,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)
|
||||
@@ -3344,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
|
||||
@@ -3360,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)
|
||||
@@ -3437,14 +3476,16 @@ static void ResetNode(INT32 node);
|
||||
//
|
||||
void CL_ClearPlayer(INT32 playernum)
|
||||
{
|
||||
// Handle mobj_t pointers.
|
||||
if (players[playernum].mo)
|
||||
{
|
||||
// Don't leave a NiGHTS ghost!
|
||||
if (UNLIKELY((players[playernum].pflags & PF_NIGHTSMODE) && players[playernum].mo->tracer))
|
||||
if (nightsplayer(&players[playernum]) && players[playernum].mo->tracer)
|
||||
P_RemoveMobj(players[playernum].mo->tracer);
|
||||
P_RemoveMobj(players[playernum].mo);
|
||||
}
|
||||
|
||||
// Wipe the struct.
|
||||
memset(&players[playernum], 0, sizeof(player_t));
|
||||
}
|
||||
|
||||
@@ -3501,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;
|
||||
|
||||
@@ -3758,6 +3799,10 @@ static void Command_Ban(void)
|
||||
if (pn == -1 || pn == 0)
|
||||
return;
|
||||
|
||||
// player does not exist
|
||||
if (!playeringame[pn])
|
||||
return;
|
||||
|
||||
WRITEUINT8(p, pn);
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
@@ -3875,6 +3920,10 @@ static void Command_Kick(void)
|
||||
if (pn == -1 || pn == 0)
|
||||
return;
|
||||
|
||||
// player does not exist
|
||||
if (!playeringame[pn])
|
||||
return;
|
||||
|
||||
// Special case if we are trying to kick a player who is downloading the game state:
|
||||
// trigger a timeout instead of kicking them, because a kick would only
|
||||
// take effect after they have finished downloading
|
||||
@@ -3924,6 +3973,13 @@ static void Got_KickCmd(const UINT8 **p, INT32 playernum)
|
||||
pnum = READUINT8(*p);
|
||||
msg = READUINT8(*p);
|
||||
|
||||
if (pnum >= MAXPLAYERS)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal kick command received from %s for player %d\n"), player_names[playernum], pnum);
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: this does not work at all on dedi, servernode == 0 which is prevented from kick/ban command
|
||||
if (pnum == serverplayer && IsPlayerAdmin(playernum))
|
||||
{
|
||||
CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n"));
|
||||
@@ -3978,6 +4034,16 @@ static void Got_KickCmd(const UINT8 **p, INT32 playernum)
|
||||
msg = KICK_MSG_CON_FAIL;
|
||||
}
|
||||
|
||||
// without this the server will remove itself and thus self destruct on dedicated
|
||||
if (server && (playernode[pnum] == UINT8_MAX || !playeringame[pnum]))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Attempting to kick player %d which is not in game received from %s\n"), pnum, player_names[playernum]);
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure we dont read garbage anywhere
|
||||
memset(reason, 0, sizeof(buf));
|
||||
|
||||
if (msg == KICK_MSG_CUSTOM_BAN || msg == KICK_MSG_CUSTOM_KICK)
|
||||
{
|
||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||
@@ -4438,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));
|
||||
@@ -4798,7 +4864,7 @@ void CL_RemoveSplitscreenPlayer(UINT8 p)
|
||||
// is there a game running
|
||||
boolean Playing(void)
|
||||
{
|
||||
return (server && serverrunning) || (client && cl_mode == CL_CONNECTED);
|
||||
return ((server && serverrunning) || (client && cl_mode == CL_CONNECTED));
|
||||
}
|
||||
|
||||
boolean SV_SpawnServer(void)
|
||||
@@ -5128,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);
|
||||
@@ -5377,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?
|
||||
@@ -5399,10 +5467,12 @@ static void PT_ServerCFG(SINT8 node)
|
||||
{
|
||||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||
if ((gametype = netbuffer->u.servercfg.gametype) >= NUMGAMETYPES)
|
||||
I_Error("Bad gametype in cliserv!");
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5428,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++)
|
||||
@@ -5444,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?
|
||||
@@ -5497,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)
|
||||
@@ -6839,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();
|
||||
@@ -7198,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;
|
||||
|
||||
+23
-21
@@ -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
|
||||
@@ -275,20 +276,6 @@ static void D_Renderview(void)
|
||||
|
||||
R_ApplyLevelInterpolators(R_GetTimeFrac(RTF_LEVEL));
|
||||
|
||||
if (rendermode == render_soft && cv_homremoval.value)
|
||||
{
|
||||
if (cv_homremoval.value == 1)
|
||||
{
|
||||
// Clear the software screen buffer to remove HOM
|
||||
memset(vid.screens[0], 31, vid.width * vid.height);
|
||||
}
|
||||
else if (cv_homremoval.value == 2)
|
||||
{
|
||||
//'development' HOM removal -- makes it blindingly obvious if HOM is spotted.
|
||||
memset(vid.screens[0], 32+(timeinmap&15), vid.width * vid.height);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (!P_MobjWasRemoved(players[displayplayers[i]].mo) || players[displayplayers[i]].playerstate == PST_DEAD)
|
||||
@@ -658,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);
|
||||
@@ -1157,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_Printf("Autoload: file %s contains map data! skipping...", wadsToAutoload);
|
||||
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;
|
||||
@@ -1253,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)
|
||||
@@ -1353,20 +1351,24 @@ static void IdentifyVersion(void)
|
||||
//
|
||||
// search for maps
|
||||
//
|
||||
static void D_CheckMapReplacements(boolean checkreplaced)
|
||||
static void D_CheckMapReplacements(boolean pwad)
|
||||
{
|
||||
INT32 i;
|
||||
char *name;
|
||||
UINT16 wadnum;
|
||||
lumpinfo_t *lumpinfo;
|
||||
size_t numfiles;
|
||||
|
||||
for (wadnum = 0; wadnum < mainwads; wadnum++)
|
||||
wadnum = pwad ? (mainwads+1) : 0;
|
||||
numfiles = pwad ? numwadfiles : mainwads;
|
||||
|
||||
for (; wadnum < numfiles; wadnum++)
|
||||
{
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
P_CheckMapReplacements(name, checkreplaced);
|
||||
P_CheckMapReplacements(name, pwad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+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");
|
||||
}
|
||||
|
||||
|
||||
+120
-28
@@ -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};
|
||||
|
||||
@@ -566,6 +583,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
||||
"MODIFYVOTE",
|
||||
"PICKVOTE",
|
||||
"REMOVEPLAYER",
|
||||
"DISCORD",
|
||||
"LUACMD",
|
||||
"LUAVAR"
|
||||
};
|
||||
@@ -599,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);
|
||||
@@ -847,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);
|
||||
@@ -930,11 +959,11 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
COM_AddCommand("displayplayer", Command_Displayplayer_f);
|
||||
|
||||
CV_RegisterVar(&cv_audbuffersize);
|
||||
|
||||
CV_RegisterVar(&cv_palette);
|
||||
CV_RegisterVar(&cv_palettenum);
|
||||
|
||||
CV_RegisterVar(&cv_lua_profile);
|
||||
|
||||
// m_menu.c
|
||||
CV_RegisterVar(&cv_chatheight);
|
||||
CV_RegisterVar(&cv_chatwidth);
|
||||
@@ -942,6 +971,9 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_chatspamprotection);
|
||||
CV_RegisterVar(&cv_consolechat);
|
||||
CV_RegisterVar(&cv_chatnotifications);
|
||||
CV_RegisterVar(&cv_chat_xoffset);
|
||||
CV_RegisterVar(&cv_chat_yoffset);
|
||||
CV_RegisterVar(&cv_chat_showlimit);
|
||||
CV_RegisterVar(&cv_chatbacktint);
|
||||
CV_RegisterVar(&cv_chatcentertext);
|
||||
CV_RegisterVar(&cv_songcredits);
|
||||
@@ -1007,9 +1039,17 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
CV_RegisterVar(&cv_usejoystick[i]);
|
||||
CV_RegisterVar(&cv_joyscale[i]);
|
||||
CV_RegisterVar(&cv_rumble[i]);
|
||||
CV_RegisterVar(&cv_rumblestrength[i]);
|
||||
CV_RegisterVar(&cv_gamepadled[i]);
|
||||
|
||||
CV_RegisterVar(&cv_rumble[i]);
|
||||
CV_RegisterVar(&cv_rumble_strength[i]);
|
||||
CV_RegisterVar(&cv_rumble_spinout[i]);
|
||||
CV_RegisterVar(&cv_rumble_sneakerboost[i]);
|
||||
CV_RegisterVar(&cv_rumble_offroad[i]);
|
||||
CV_RegisterVar(&cv_rumble_bananadrag[i]);
|
||||
CV_RegisterVar(&cv_rumble_stairjank[i]);
|
||||
CV_RegisterVar(&cv_rumble_brakedrift[i]);
|
||||
CV_RegisterVar(&cv_rumble_driftcharge[i]);
|
||||
}
|
||||
|
||||
CV_RegisterVar(&cv_gamepadifunfocused);
|
||||
@@ -1029,6 +1069,7 @@ void D_RegisterClientCommands(void)
|
||||
CV_RegisterVar(&cv_midimusicvolume);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_numChannels);
|
||||
CV_RegisterVar(&cv_audbuffersize);
|
||||
|
||||
#ifdef HAVE_OPENMPT
|
||||
CV_RegisterVar(&cv_modfilter);
|
||||
@@ -1265,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;
|
||||
}
|
||||
@@ -1550,8 +1592,8 @@ static void SendNameAndColor(UINT8 splitplayer)
|
||||
// TODO: make those cvars arrays
|
||||
consvar_t *playercolor, *playername, *playerskin;
|
||||
consvar_t *colorvars[] = {&cv_playercolor, &cv_playercolor2, &cv_playercolor3, &cv_playercolor4};
|
||||
consvar_t *namevars[] = {&cv_playername, &cv_playername2, &cv_playername3, &cv_playername4};
|
||||
consvar_t *skinvars[] = {&cv_skin, &cv_skin2, &cv_skin3, &cv_skin4};
|
||||
consvar_t *namevars[] = {&cv_playername, &cv_playername2, &cv_playername3, &cv_playername4};
|
||||
consvar_t *skinvars[] = {&cv_skin, &cv_skin2, &cv_skin3, &cv_skin4};
|
||||
|
||||
playercolor = colorvars[splitplayer];
|
||||
playername = namevars[splitplayer];
|
||||
@@ -1657,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);
|
||||
}
|
||||
|
||||
@@ -1665,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)
|
||||
@@ -1687,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)
|
||||
@@ -1795,7 +1839,7 @@ INT32 D_LookupPlayer(const char *s)
|
||||
|
||||
if ((playernum = atoi(s)))
|
||||
{
|
||||
playernum = max(min(playernum, MAXPLAYERS-1), 0);/* not out of range */
|
||||
playernum = max(min(playernum, MAXPLAYERS-1), 0); /* not out of range */
|
||||
return playernum;
|
||||
}
|
||||
|
||||
@@ -2319,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 */
|
||||
@@ -2737,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");
|
||||
}
|
||||
@@ -4299,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];
|
||||
@@ -4338,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])
|
||||
@@ -5178,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
|
||||
@@ -5490,7 +5580,6 @@ static void Name_OnChange(void)
|
||||
}
|
||||
|
||||
SendNameAndColor(0);
|
||||
|
||||
}
|
||||
|
||||
static void Name2_OnChange(void)
|
||||
@@ -5681,19 +5770,22 @@ static void Command_SkinSearch(void)
|
||||
size_t i;
|
||||
UINT16 s;
|
||||
UINT16 ic = 0;
|
||||
//skin_t *skininput = &skins[s];
|
||||
for (i = 1; i < COM_Argc(); i++){
|
||||
for( s = 0 ; s < numallskins ; s++ )
|
||||
|
||||
for (i = 1; i < COM_Argc(); i++)
|
||||
{
|
||||
for (s = 0; s < numskins; s++)
|
||||
{
|
||||
skin_t *skininput = &skins[s];
|
||||
if (strcasestr(skininput->realname,COM_Argv(i)))
|
||||
|
||||
if (strcasestr(skininput->realname, COM_Argv(i)))
|
||||
{
|
||||
ic++;
|
||||
CONS_Printf("%d. %s%s:\x80 %s\n", ic,HU_SkinColorToConsoleColor(skininput->prefcolor),skininput->realname,skininput->name);
|
||||
CONS_Printf("%d. %s%s:\x80 %s\n", ic, HU_SkinColorToConsoleColor(skininput->prefcolor), skininput->realname, skininput->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
CONS_Printf("Total %d skins.\n", ic);
|
||||
|
||||
CONS_Printf("Total %d skins.\n", ic);
|
||||
}
|
||||
|
||||
/** Sends a color change for the console player, unless that player is moving.
|
||||
|
||||
@@ -149,6 +149,7 @@ extern consvar_t cv_showminimapnames;
|
||||
extern consvar_t cv_showminimapfinished;
|
||||
extern consvar_t cv_minihead;
|
||||
extern consvar_t cv_showminimapangle;
|
||||
extern consvar_t cv_spinoutroll;
|
||||
|
||||
extern consvar_t cv_showlapemblem;
|
||||
|
||||
@@ -188,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;
|
||||
|
||||
+14
-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,11 +567,16 @@ 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
|
||||
|
||||
SINT8 driftlevel; // just for controller rumble for now
|
||||
|
||||
UINT8 stairjank;
|
||||
} player_t;
|
||||
|
||||
#endif
|
||||
+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)
|
||||
|
||||
+128
-56
@@ -68,6 +68,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
||||
#include <time.h>
|
||||
#if defined (__linux__)
|
||||
#include <sys/vfs.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <mach/mach.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
@@ -156,8 +162,7 @@ const char *wadSearchPaths[] = {
|
||||
|
||||
/** \brief WAD file to look for
|
||||
*/
|
||||
#define WADKEYWORD1 "srb2.srb"
|
||||
#define WADKEYWORD2 "srb2.wad"
|
||||
#define WADKEYWORD "srb2.srb"
|
||||
/** \brief holds wad path
|
||||
*/
|
||||
static char returnWadPath[256];
|
||||
@@ -520,17 +525,24 @@ void I_OutputMsg(const char *fmt, ...)
|
||||
{
|
||||
size_t len;
|
||||
char *txt;
|
||||
va_list argptr;
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr,fmt);
|
||||
if (!fmt)
|
||||
return;
|
||||
|
||||
va_start(argptr, fmt);
|
||||
len = vsnprintf(NULL, 0, fmt, argptr);
|
||||
va_end(argptr);
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
txt = malloc(len+1);
|
||||
va_start(argptr,fmt);
|
||||
vsprintf(txt, fmt, argptr);
|
||||
txt = (char*)(malloc(len+1));
|
||||
|
||||
if (!txt)
|
||||
I_Error("I_OutputMsg: Out of memory!\n");
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(txt, len+1, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
#ifdef HAVE_TTF
|
||||
@@ -538,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)
|
||||
@@ -956,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();
|
||||
@@ -1041,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;
|
||||
}
|
||||
@@ -1049,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1332,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)
|
||||
@@ -1413,6 +1433,12 @@ static void I_Fork(void)
|
||||
}
|
||||
#endif/*NEWSIGNALHANDLER*/
|
||||
|
||||
int I_OpenURL(const char *url)
|
||||
{
|
||||
(void)url;
|
||||
return -1;
|
||||
}
|
||||
|
||||
INT32 I_StartupSystem(void)
|
||||
{
|
||||
I_StartupConsole();
|
||||
@@ -1512,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);
|
||||
@@ -1525,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);
|
||||
|
||||
@@ -1746,7 +1772,8 @@ char *I_GetUserName(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
strncpy(username, p, MAXPLAYERNAME);
|
||||
|
||||
snprintf(username, sizeof(username), "%s", p);
|
||||
}
|
||||
|
||||
if (!fastcmp(username, ""))
|
||||
@@ -1770,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);
|
||||
@@ -1802,42 +1847,34 @@ const char *I_ClipboardPaste(void)
|
||||
*/
|
||||
static boolean isWadPathOk(const char *path)
|
||||
{
|
||||
char *wad3path = malloc(256);
|
||||
char wad3path[256];
|
||||
|
||||
if (!wad3path)
|
||||
return false;
|
||||
|
||||
sprintf(wad3path, pandf, path, WADKEYWORD1);
|
||||
snprintf(wad3path, sizeof(wad3path), pandf, path, WADKEYWORD);
|
||||
|
||||
if (FIL_ReadFileOK(wad3path))
|
||||
{
|
||||
free(wad3path);
|
||||
return true;
|
||||
}
|
||||
|
||||
sprintf(wad3path, pandf, path, WADKEYWORD2);
|
||||
|
||||
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] == '/'))
|
||||
{
|
||||
if (s[j] == ':') s[j+1] = 0;
|
||||
else s[j] = 0;
|
||||
if (s[j] == ':')
|
||||
s[j+1] = 0;
|
||||
else
|
||||
s[j] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief search for srb2.srb in the given path
|
||||
@@ -1853,11 +1890,12 @@ static const char *searchWad(const char *searchDir)
|
||||
static char tempsw[256] = "";
|
||||
filestatus_t fstemp;
|
||||
|
||||
strcpy(tempsw, WADKEYWORD1);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1895,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;
|
||||
@@ -1907,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
|
||||
@@ -1921,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);
|
||||
}
|
||||
|
||||
@@ -1949,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;
|
||||
@@ -1974,17 +2011,22 @@ const char *I_LocateWad(void)
|
||||
static long get_entry(const char* name, const char* buf)
|
||||
{
|
||||
long val;
|
||||
char* hit = strstr(buf, name);
|
||||
if (hit == NULL) {
|
||||
const char* hit = strstr(buf, name);
|
||||
|
||||
if (hit == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val = strtol(hit + strlen(name), NULL, 10);
|
||||
if (errno != 0) {
|
||||
|
||||
if (errno != 0)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
@@ -2009,13 +2051,13 @@ size_t I_GetFreeMem(size_t *total)
|
||||
*total = 32 << 20;
|
||||
return 32 << 20;
|
||||
#elif defined (_WIN32)
|
||||
MEMORYSTATUS info;
|
||||
MEMORYSTATUSEX info;
|
||||
|
||||
info.dwLength = sizeof (MEMORYSTATUS);
|
||||
GlobalMemoryStatus( &info );
|
||||
info.dwLength = sizeof (MEMORYSTATUSEX);
|
||||
GlobalMemoryStatusEx( &info );
|
||||
if (total)
|
||||
*total = (size_t)info.dwTotalPhys;
|
||||
return (size_t)info.dwAvailPhys;
|
||||
*total = (size_t)info.ullTotalPhys;
|
||||
return (size_t)info.ullAvailPhys;
|
||||
#elif defined (__OS2__)
|
||||
UINT32 pr_arena;
|
||||
|
||||
@@ -2048,7 +2090,7 @@ size_t I_GetFreeMem(size_t *total)
|
||||
{
|
||||
// Error
|
||||
if (total)
|
||||
*total = 0L;
|
||||
*total = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2057,12 +2099,12 @@ size_t I_GetFreeMem(size_t *total)
|
||||
{
|
||||
// Error
|
||||
if (total)
|
||||
*total = 0L;
|
||||
*total = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memTag += sizeof (MEMTOTAL);
|
||||
totalKBytes = (size_t)atoi(memTag);
|
||||
totalKBytes = strtoul(memTag, NULL, 10);
|
||||
|
||||
if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL)
|
||||
{
|
||||
@@ -2076,7 +2118,7 @@ size_t I_GetFreeMem(size_t *total)
|
||||
{
|
||||
// Error
|
||||
if (total)
|
||||
*total = 0L;
|
||||
*total = 0;
|
||||
return 0;
|
||||
}
|
||||
freeKBytes = MemAvailable;
|
||||
@@ -2084,16 +2126,46 @@ size_t I_GetFreeMem(size_t *total)
|
||||
else
|
||||
{
|
||||
memTag += sizeof (MEMAVAILABLE);
|
||||
freeKBytes = atoi(memTag);
|
||||
freeKBytes = strtoul(memTag, NULL, 10);
|
||||
}
|
||||
|
||||
if (total)
|
||||
*total = totalKBytes << 10;
|
||||
return freeKBytes << 10;
|
||||
#elif defined(__APPLE__)
|
||||
/* macOS */
|
||||
mach_port_t host = mach_host_self();
|
||||
kern_return_t kr;
|
||||
mach_msg_type_number_t count;
|
||||
vm_size_t v_page_size;
|
||||
struct vm_statistics64 vm_stats;
|
||||
uint64_t total_mem, free_mem;
|
||||
size_t size;
|
||||
|
||||
size = sizeof(total_mem);
|
||||
if (sysctlbyname("hw.memsize", &total_mem, &size, NULL, 0) < 0)
|
||||
total_mem = 0;
|
||||
|
||||
kr = host_page_size(host, &v_page_size);
|
||||
if (kr != KERN_SUCCESS)
|
||||
v_page_size = 4096;
|
||||
|
||||
count = HOST_VM_INFO64_COUNT;
|
||||
kr = host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&vm_stats, &count);
|
||||
if (kr == KERN_SUCCESS)
|
||||
free_mem = (uint64_t)(vm_stats.free_count + vm_stats.inactive_count) * v_page_size;
|
||||
else
|
||||
free_mem = 0;
|
||||
|
||||
if (total)
|
||||
*total = (size_t)total_mem;
|
||||
return (size_t)free_mem;
|
||||
#else
|
||||
// Guess 48 MB.
|
||||
if (total)
|
||||
{
|
||||
*total = 48<<20;
|
||||
}
|
||||
return 48<<20;
|
||||
#endif
|
||||
}
|
||||
|
||||
+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
|
||||
+31
-2
@@ -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,6 +616,21 @@ 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!
|
||||
|
||||
#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 __
|
||||
/// Detect if a client is on Saturn in the clientconfig.
|
||||
/// To seperately allow them to join or block joining from vanilla clients.
|
||||
|
||||
@@ -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);
|
||||
|
||||
+121
-145
@@ -63,7 +63,6 @@
|
||||
|
||||
// for replay dates
|
||||
#include <time.h>
|
||||
#include <locale.h>
|
||||
|
||||
// menu demo things
|
||||
UINT32 demoDelayTime = 15*TICRATE;
|
||||
@@ -447,7 +446,8 @@ void G_WriteDemoExtraData(void)
|
||||
{
|
||||
static UINT8 timeout = 0;
|
||||
|
||||
if (timeout) timeout--;
|
||||
if (timeout)
|
||||
timeout--;
|
||||
|
||||
if (demo_writerng == 1 || (demo_writerng == 2 && timeout == 0))
|
||||
{
|
||||
@@ -467,6 +467,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
||||
|
||||
if (!demobuf.p || !demo.deferstart)
|
||||
return;
|
||||
|
||||
ziptic = READUINT8(demobuf.p);
|
||||
|
||||
if (ziptic & ZT_FWD)
|
||||
@@ -488,11 +489,12 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
||||
|
||||
// what in the actual fuck is this???
|
||||
// SRB2kart: Copy-pasted from ticcmd building, removes that crappy demo cam
|
||||
if (((players[displayplayers[0]].mo && players[displayplayers[0]].speed > 0) // Moving
|
||||
const player_t *player = &players[displayplayers[0]];
|
||||
if (((player->mo && player->speed > 0) // Moving
|
||||
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|
||||
|| (players[displayplayers[0]].kartstuff[k_respawn]) // Respawning
|
||||
|| (players[displayplayers[0]].spectator || objectplacing)) // Not a physical player
|
||||
&& !(players[displayplayers[0]].kartstuff[k_spinouttimer] && players[displayplayers[0]].kartstuff[k_sneakertimer])) // Spinning and boosting cancels out spinout
|
||||
|| (player->kartstuff[k_respawn]) // Respawning
|
||||
|| (player->spectator || objectplacing)) // Not a physical player
|
||||
&& !(player->kartstuff[k_spinouttimer] && player->kartstuff[k_sneakertimer])) // Spinning and boosting cancels out spinout
|
||||
localangle[0] += (cmd->angleturn<<16);
|
||||
|
||||
if (!(demoflags & DF_GHOST) && *demobuf.p == DEMOMARKER)
|
||||
@@ -713,7 +715,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
||||
if (!(demoflags & DF_GHOST))
|
||||
return; // No ghost data to write.
|
||||
|
||||
if (ghost->player && ghost->player->pflags & PF_NIGHTSMODE && ghost->tracer)
|
||||
if (ghost->player && nightsplayer(ghost->player) && ghost->tracer)
|
||||
{
|
||||
// We're talking about the NiGHTS thing, not the normal platforming thing!
|
||||
ziptic |= GZT_NIGHTS;
|
||||
@@ -931,7 +933,7 @@ void G_ConsAllGhostTics(void)
|
||||
void G_ConsGhostTic(INT32 playernum)
|
||||
{
|
||||
UINT8 ziptic;
|
||||
fixed_t px,py,pz,gx,gy,gz;
|
||||
fixed_t px, py, pz, gx, gy, gz;
|
||||
mobj_t *testmo;
|
||||
fixed_t syncleeway;
|
||||
boolean nightsfail = false;
|
||||
@@ -976,7 +978,7 @@ void G_ConsGhostTic(INT32 playernum)
|
||||
|
||||
if (ziptic & GZT_NIGHTS)
|
||||
{
|
||||
if (!testmo || !testmo->player || !(testmo->player->pflags & PF_NIGHTSMODE) || !testmo->tracer)
|
||||
if (!testmo || !testmo->player || !nightsplayer(testmo->player) || !testmo->tracer)
|
||||
nightsfail = true;
|
||||
else
|
||||
testmo = testmo->tracer;
|
||||
@@ -1344,7 +1346,7 @@ fadeghost:
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK);
|
||||
mobj = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height, 3*FRACUNIT), MT_THOK);
|
||||
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
|
||||
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
|
||||
mobj->tics = -1; // nope.
|
||||
@@ -1518,7 +1520,9 @@ void G_PreviewRewind(tic_t previewtime)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
player_t *player = &players[i];
|
||||
|
||||
if (!playeringame[i] || player->spectator)
|
||||
{
|
||||
if (info->playerinfo[i].player.mo)
|
||||
{
|
||||
@@ -1530,35 +1534,35 @@ void G_PreviewRewind(tic_t previewtime)
|
||||
|
||||
if (!info->playerinfo[i].ingame || !info->playerinfo[i].player.mo)
|
||||
{
|
||||
if (players[i].mo)
|
||||
players[i].mo->flags2 |= MF2_DONTDRAW;
|
||||
if (player->mo)
|
||||
player->mo->flags2 |= MF2_DONTDRAW;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!players[i].mo)
|
||||
if (!player->mo)
|
||||
continue; //@TODO spawn temp object to act as a player display
|
||||
|
||||
players[i].mo->flags2 &= ~MF2_DONTDRAW;
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
|
||||
P_UnsetThingPosition(players[i].mo);
|
||||
P_UnsetThingPosition(player->mo);
|
||||
#define TWEEN(pr) info->playerinfo[i].mobj.pr + FixedMul((INT32) (next_info->playerinfo[i].mobj.pr - info->playerinfo[i].mobj.pr), tweenvalue)
|
||||
players[i].mo->x = TWEEN(x);
|
||||
players[i].mo->y = TWEEN(y);
|
||||
players[i].mo->z = TWEEN(z);
|
||||
players[i].mo->angle = TWEEN(angle);
|
||||
player->mo->x = TWEEN(x);
|
||||
player->mo->y = TWEEN(y);
|
||||
player->mo->z = TWEEN(z);
|
||||
player->mo->angle = TWEEN(angle);
|
||||
#undef TWEEN
|
||||
P_SetThingPosition(players[i].mo);
|
||||
P_SetThingPosition(player->mo);
|
||||
|
||||
players[i].frameangle = info->playerinfo[i].player.frameangle + FixedMul((INT32) (next_info->playerinfo[i].player.frameangle - info->playerinfo[i].player.frameangle), tweenvalue);
|
||||
player->frameangle = info->playerinfo[i].player.frameangle + FixedMul((INT32) (next_info->playerinfo[i].player.frameangle - info->playerinfo[i].player.frameangle), tweenvalue);
|
||||
|
||||
players[i].mo->sprite = info->playerinfo[i].mobj.sprite;
|
||||
players[i].mo->frame = info->playerinfo[i].mobj.frame;
|
||||
player->mo->sprite = info->playerinfo[i].mobj.sprite;
|
||||
player->mo->frame = info->playerinfo[i].mobj.frame;
|
||||
|
||||
players[i].realtime = info->playerinfo[i].player.realtime;
|
||||
player->realtime = info->playerinfo[i].player.realtime;
|
||||
|
||||
for (j = 0; j < NUMKARTSTUFF; j++)
|
||||
players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
|
||||
player->kartstuff[j] = info->playerinfo[i].player.kartstuff[j];
|
||||
}
|
||||
|
||||
for (i = splitscreen; i >= 0; i--)
|
||||
@@ -1691,7 +1695,7 @@ void G_BeginRecording(void)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(name,0,sizeof(name));
|
||||
memset(name, 0, sizeof(name));
|
||||
|
||||
demobuf.p = demobuf.buffer;
|
||||
demoflags = DF_GHOST|(multiplayer ? DF_MULTIPLAYER : (modeattacking<<DF_ATTACKSHIFT));
|
||||
@@ -1705,9 +1709,9 @@ void G_BeginRecording(void)
|
||||
|
||||
// Setup header.
|
||||
memcpy(demobuf.p, DEMOHEADER, 12); demobuf.p += 12;
|
||||
WRITEUINT8(demobuf.p,VERSION);
|
||||
WRITEUINT8(demobuf.p,SUBVERSION);
|
||||
WRITEUINT16(demobuf.p,DEMOVERSION);
|
||||
WRITEUINT8(demobuf.p, VERSION);
|
||||
WRITEUINT8(demobuf.p, SUBVERSION);
|
||||
WRITEUINT16(demobuf.p, DEMOVERSION);
|
||||
|
||||
// Full replay title
|
||||
demobuf.p += 64;
|
||||
@@ -1718,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));
|
||||
@@ -1736,7 +1740,7 @@ void G_BeginRecording(void)
|
||||
|
||||
// game data
|
||||
memcpy(demobuf.p, "PLAY", 4); demobuf.p += 4;
|
||||
WRITEINT16(demobuf.p,gamemap);
|
||||
WRITEINT16(demobuf.p, gamemap);
|
||||
memcpy(demobuf.p, mapmd5, 16); demobuf.p += 16;
|
||||
|
||||
WRITEUINT8(demobuf.p, demoflags);
|
||||
@@ -1768,8 +1772,8 @@ void G_BeginRecording(void)
|
||||
break;
|
||||
case ATTACKING_RECORD: // 1
|
||||
demotime_p = demobuf.p;
|
||||
WRITEUINT32(demobuf.p,UINT32_MAX); // time
|
||||
WRITEUINT32(demobuf.p,UINT32_MAX); // lap
|
||||
WRITEUINT32(demobuf.p, UINT32_MAX); // time
|
||||
WRITEUINT32(demobuf.p, UINT32_MAX); // lap
|
||||
break;
|
||||
default: // 3
|
||||
break;
|
||||
@@ -1826,9 +1830,9 @@ void G_BeginRecording(void)
|
||||
if (demoflags & DF_LUAVARS)
|
||||
LUA_Archive(&demobuf, false);
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
memset(&ghostext,0,sizeof(ghostext));
|
||||
memset(&oldcmd, 0, sizeof(oldcmd));
|
||||
memset(&oldghost, 0, sizeof(oldghost));
|
||||
memset(&ghostext, 0, sizeof(ghostext));
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
@@ -1868,19 +1872,19 @@ void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT
|
||||
// Name
|
||||
memset(temp, 0, 16);
|
||||
strncpy(temp, name, 16);
|
||||
memcpy(demobuf.p,temp,16);
|
||||
memcpy(demobuf.p, temp, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Skin
|
||||
memset(temp, 0, 16);
|
||||
strncpy(temp, skins[skinnum].name, 16);
|
||||
memcpy(demobuf.p,temp,16);
|
||||
memcpy(demobuf.p, temp, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Color
|
||||
memset(temp, 0, 16);
|
||||
strncpy(temp, KartColor_Names[color], 16);
|
||||
memcpy(demobuf.p,temp,16);
|
||||
memcpy(demobuf.p, temp, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Score/time/whatever
|
||||
@@ -2207,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;
|
||||
}
|
||||
|
||||
@@ -2217,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;
|
||||
}
|
||||
|
||||
@@ -2242,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;
|
||||
}
|
||||
|
||||
@@ -2262,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;
|
||||
}
|
||||
|
||||
@@ -2283,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
|
||||
@@ -2330,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);
|
||||
|
||||
@@ -2339,7 +2343,8 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
extrainfo_p += 16;
|
||||
|
||||
// Skin
|
||||
memcpy(temp,extrainfo_p,16);
|
||||
memcpy(temp, extrainfo_p, 16);
|
||||
temp[16] = '\0';
|
||||
extrainfo_p += 16;
|
||||
pdemo->standings[count].skin = UINT8_MAX;
|
||||
|
||||
@@ -2353,12 +2358,13 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||
}
|
||||
|
||||
// Color
|
||||
memcpy(temp,extrainfo_p,16);
|
||||
memcpy(temp, extrainfo_p, 16);
|
||||
temp[16] = '\0';
|
||||
extrainfo_p += 16;
|
||||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
if (fasticmp(KartColor_Names[i],temp)) // SRB2kart
|
||||
if (fasticmp(KartColor_Names[i], temp)) // SRB2kart
|
||||
{
|
||||
pdemo->standings[count].color = i;
|
||||
break;
|
||||
@@ -2380,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;
|
||||
|
||||
@@ -2391,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)
|
||||
@@ -2451,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;
|
||||
}
|
||||
|
||||
@@ -2529,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;
|
||||
}
|
||||
|
||||
@@ -2539,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
|
||||
@@ -2548,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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2628,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);
|
||||
@@ -2640,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);
|
||||
@@ -2661,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();
|
||||
@@ -2687,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();
|
||||
@@ -2698,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();
|
||||
@@ -2715,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();
|
||||
@@ -2742,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;
|
||||
@@ -2816,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();
|
||||
@@ -2827,15 +2803,15 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
if (demo.version == 0x0001)
|
||||
{
|
||||
// Player name
|
||||
memcpy(player_names[0],demobuf.p,16);
|
||||
memcpy(player_names[0], demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Skin
|
||||
memcpy(skin,demobuf.p,16);
|
||||
memcpy(skin, demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Color
|
||||
memcpy(color,demobuf.p,16);
|
||||
memcpy(color, demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
demobuf.p += 5; // Backwards compat - some stats
|
||||
@@ -2848,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();
|
||||
@@ -2858,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();
|
||||
@@ -2868,7 +2844,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
// Set color
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
if (fasticmp(KartColor_Names[i],color)) // SRB2kart
|
||||
if (fasticmp(KartColor_Names[i], color)) // SRB2kart
|
||||
{
|
||||
players[0].skincolor = i;
|
||||
break;
|
||||
@@ -2881,16 +2857,16 @@ 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();
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
memset(&ghostext,0,sizeof(ghostext));
|
||||
memset(&oldcmd, 0, sizeof(oldcmd));
|
||||
memset(&oldghost, 0, sizeof(oldghost));
|
||||
memset(&ghostext, 0, sizeof(ghostext));
|
||||
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo version does not match game version. Desyncs may occur.\n"));
|
||||
|
||||
@@ -2919,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();
|
||||
@@ -2968,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();
|
||||
@@ -2980,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();
|
||||
@@ -2994,16 +2970,16 @@ void G_DoPlayDemo(char *defdemoname)
|
||||
players[p].spectator = spectator;
|
||||
|
||||
// Name
|
||||
memcpy(player_names[p],demobuf.p,16);
|
||||
memcpy(player_names[p], demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
// Skin
|
||||
memcpy(skin,demobuf.p,16);
|
||||
memcpy(skin, demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
SetPlayerSkin(p, skin);
|
||||
|
||||
// Color
|
||||
memcpy(color,demobuf.p,16);
|
||||
memcpy(color, demobuf.p, 16);
|
||||
demobuf.p += 16;
|
||||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
@@ -3221,15 +3197,15 @@ void G_AddGhost(char *defdemoname)
|
||||
if (ghostversion == 0x0001)
|
||||
{
|
||||
// Player name (TODO: Display this somehow if it doesn't match cv_playername!)
|
||||
memcpy(name, p,16);
|
||||
memcpy(name, p, 16);
|
||||
p += 16;
|
||||
|
||||
// Skin
|
||||
memcpy(skin, p,16);
|
||||
memcpy(skin, p, 16);
|
||||
p += 16;
|
||||
|
||||
// Color
|
||||
memcpy(color, p,16);
|
||||
memcpy(color, p, 16);
|
||||
p += 16;
|
||||
|
||||
// Ghosts do not have a player structure to put this in.
|
||||
@@ -3381,7 +3357,7 @@ void G_AddGhost(char *defdemoname)
|
||||
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
{
|
||||
if (fasticmp(KartColor_Names[i],color)) // SRB2kart
|
||||
if (fasticmp(KartColor_Names[i], color)) // SRB2kart
|
||||
{
|
||||
gh->mo->color = (UINT8)i;
|
||||
break;
|
||||
@@ -3473,7 +3449,7 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
||||
if (ghostversion == 0x0001)
|
||||
{
|
||||
// Player name
|
||||
memcpy(dummystaffname, p,16);
|
||||
memcpy(dummystaffname, p, 16);
|
||||
dummystaffname[16] = '\0';
|
||||
return; // Not really a failure but whatever
|
||||
}
|
||||
|
||||
+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;
|
||||
|
||||
+6
-4
@@ -118,10 +118,11 @@ extern consvar_t cv_driftsparkpulse;
|
||||
extern consvar_t cv_gravstretch;
|
||||
extern consvar_t cv_sloperoll;
|
||||
extern consvar_t cv_sliptideroll;
|
||||
extern consvar_t cv_stairjank;
|
||||
extern consvar_t cv_stairjanksfx;
|
||||
extern consvar_t cv_slamsound;
|
||||
extern consvar_t cv_sloperolldist;
|
||||
extern consvar_t cv_sparkroll;
|
||||
extern consvar_t cv_spinoutroll;
|
||||
|
||||
extern consvar_t cv_squishdance, cv_squishdancespeed;
|
||||
|
||||
@@ -227,10 +228,11 @@ void G_SaveGameData(boolean force);
|
||||
|
||||
void G_SaveGame(UINT32 slot);
|
||||
|
||||
#define G_GametypeHasTeams() (G_IsGameType(GT_TEAMMATCH) || G_IsGameType(GT_CTF))
|
||||
#define G_RaceGametype() (G_IsGameType(GT_RACE))
|
||||
#define G_BattleGametype() (G_IsGameType(GT_MATCH))
|
||||
#define G_RaceGametype() (G_IsGameType(GT_RACE))
|
||||
#define G_TagGametype() (G_IsGameType(GT_TAG) || G_IsGameType(GT_HIDEANDSEEK))
|
||||
|
||||
#define G_GametypeHasTeams() (UNLIKELY(G_IsGameType(GT_TEAMMATCH) || G_IsGameType(GT_CTF)))
|
||||
#define G_TagGametype() (UNLIKELY(G_IsGameType(GT_TAG) || G_IsGameType(GT_HIDEANDSEEK)))
|
||||
|
||||
FUNCINLINE static ATTRINLINE boolean G_IsGameType(int type)
|
||||
{
|
||||
|
||||
+50
-13
@@ -66,13 +66,30 @@ consvar_t cv_rumble[MAXSPLITSCREENPLAYERS] = {
|
||||
|
||||
static CV_PossibleValue_t rumblestrength_cons_t[] = {{FRACUNIT/4, "MIN"}, {FRACUNIT*4, "MAX"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS] = {
|
||||
consvar_t cv_rumble_strength[MAXSPLITSCREENPLAYERS] = {
|
||||
{"rumblestrength", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumblestrength2", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumblestrength3", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL},
|
||||
{"rumblestrength4", "1.0", CV_SAVE|CV_FLOAT, rumblestrength_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
#define IMPL_RUMBLE_TYPE(type)\
|
||||
consvar_t cv_rumble_##type [MAXSPLITSCREENPLAYERS] = {\
|
||||
{"rumble_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},\
|
||||
{"rumble2_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},\
|
||||
{"rumble3_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL},\
|
||||
{"rumble4_" #type, "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}\
|
||||
};
|
||||
|
||||
IMPL_RUMBLE_TYPE(spinout);
|
||||
IMPL_RUMBLE_TYPE(sneakerboost);
|
||||
IMPL_RUMBLE_TYPE(offroad);
|
||||
IMPL_RUMBLE_TYPE(bananadrag);
|
||||
IMPL_RUMBLE_TYPE(stairjank);
|
||||
IMPL_RUMBLE_TYPE(brakedrift);
|
||||
IMPL_RUMBLE_TYPE(driftcharge);
|
||||
|
||||
|
||||
static CV_PossibleValue_t gamepadled_cons_t[] = {{0, "Off"}, {1, "Skincolor"}, {2, "Mobjcolor"}, {0, NULL}};
|
||||
consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS] = {
|
||||
{"gamepadled", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, gamepadled_cons_t, led_off_handle, 0, NULL, NULL, 0, 0, NULL},
|
||||
@@ -1036,8 +1053,8 @@ void G_PlayerDeviceRumble(INT32 playernum, UINT16 low_strength, UINT16 high_stre
|
||||
// doesent need to be super precise
|
||||
// but ensure this is within range (0-65535)
|
||||
// placed here so it applies to lua aswell
|
||||
low_strength = (UINT16)min(FixedMul(low_strength, cv_rumblestrength[playernum].value), UINT16_MAX);
|
||||
high_strength = (UINT16)min(FixedMul(high_strength, cv_rumblestrength[playernum].value), UINT16_MAX);
|
||||
low_strength = (UINT16)min(FixedMul(low_strength, cv_rumble_strength[playernum].value), UINT16_MAX);
|
||||
high_strength = (UINT16)min(FixedMul(high_strength, cv_rumble_strength[playernum].value), UINT16_MAX);
|
||||
|
||||
I_GamepadRumble(playernum, low_strength, high_strength, duration);
|
||||
}
|
||||
@@ -1059,7 +1076,7 @@ void G_DeviceRumbleTick(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
if (dedicated || numcontrollers == 0 || gamestate != GS_LEVEL)
|
||||
if (dedicated || numcontrollers == 0 || gamestate != GS_LEVEL || demo.playback)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1090,6 +1107,11 @@ void G_DeviceRumbleTick(void)
|
||||
|
||||
const player_t *player = P_GetLocalPlayerForNum(i);
|
||||
|
||||
if (!player)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// allow lua to do some crap for spectators
|
||||
if (player->spectator || !player->mo)
|
||||
{
|
||||
@@ -1105,17 +1127,20 @@ void G_DeviceRumbleTick(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_spinouttimer])
|
||||
if (cv_rumble_spinout[i].value
|
||||
&& player->kartstuff[k_spinouttimer])
|
||||
{
|
||||
//low = high = FRACUNIT / 6;
|
||||
low = high = FixedMul((RUMBLE_VERYSTRONG), (FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2)))); // try do some some kinda fadeout, 3*TICRATE / 2 is the "default" spinout time
|
||||
}
|
||||
else if (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2)))
|
||||
else if (cv_rumble_sneakerboost[i].value
|
||||
&& (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2))))
|
||||
{
|
||||
low = high = RUMBLE_STRONG;
|
||||
}
|
||||
else if ((player->kartstuff[k_offroad])
|
||||
&& player->speed != 0
|
||||
else if (cv_rumble_offroad[i].value
|
||||
&& (player->kartstuff[k_offroad])
|
||||
&& (player->speed != 0)
|
||||
&& P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
// weaken this depending on if you got hyu or invinc
|
||||
@@ -1132,26 +1157,37 @@ void G_DeviceRumbleTick(void)
|
||||
low = high = RUMBLE_MODERATE;
|
||||
}
|
||||
}
|
||||
else if ((player->kartstuff[k_bananadrag] > TICRATE)
|
||||
&& player->speed != 0
|
||||
else if (cv_rumble_bananadrag[i].value
|
||||
&& (player->kartstuff[k_bananadrag] > TICRATE)
|
||||
&& (player->speed != 0)
|
||||
&& P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (leveltime & 1) // this is actually funny lel
|
||||
high = RUMBLE_MODERATE;
|
||||
}
|
||||
else if (cv_rumble_stairjank[i].value
|
||||
&& (player->stairjank > 8)
|
||||
&& (player->speed != 0)
|
||||
&& P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
low = high = RUMBLE_VERYWEAK;
|
||||
}
|
||||
|
||||
if (player->kartstuff[k_brakedrift])
|
||||
if (cv_rumble_brakedrift[i].value
|
||||
&& player->kartstuff[k_brakedrift])
|
||||
{
|
||||
high = CLAMP((high + RUMBLE_VERYWEAK), 0, UINT16_MAX);
|
||||
}
|
||||
|
||||
// pulse when gettin new driftlevel
|
||||
// let this come last
|
||||
if (player->kartstuff[k_driftcharge]
|
||||
if (cv_rumble_driftcharge[i].value
|
||||
&& player->kartstuff[k_driftcharge]
|
||||
&& player->driftlevel)
|
||||
{
|
||||
high = CLAMP((high + RUMBLE_VERYWEAK), 0, UINT16_MAX);
|
||||
|
||||
// make it rumble slightly longer the higher your driftlevel!
|
||||
if (player->driftlevel == 2)
|
||||
lenght = 114;
|
||||
else if (player->driftlevel == 3)
|
||||
@@ -1214,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;
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -100,9 +100,10 @@ typedef enum
|
||||
gc_custom2, // Lua scriptable
|
||||
gc_custom3, // Lua scriptable
|
||||
gc_director,
|
||||
gc_freecam, // Toggle for freecam while ingame
|
||||
gc_camfloat, // alternative button for raising cam
|
||||
gc_camsink, // alternative button for sinking
|
||||
// freecam specific controls
|
||||
gc_freecam, // Toggle for freecam while ingame
|
||||
gc_camfloat, // alternative button for raising camera
|
||||
gc_camsink, // alternative button for sinking camera
|
||||
gc_strafeleft,
|
||||
gc_straferight,
|
||||
num_gamecontrols
|
||||
@@ -112,10 +113,19 @@ typedef enum
|
||||
extern consvar_t cv_mousexsens, cv_mouseysens;
|
||||
extern consvar_t cv_controlperkey;
|
||||
extern consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern consvar_t cv_gamepadled[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern consvar_t cv_rumble[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble_strength[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble_spinout[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble_sneakerboost[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble_offroad[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble_bananadrag[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble_stairjank[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble_brakedrift[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumble_driftcharge[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern consvar_t cv_gamepadifunfocused;
|
||||
extern consvar_t cv_gamepadledifunfocused;
|
||||
extern consvar_t cv_rumbleifunfocused;
|
||||
|
||||
+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)
|
||||
@@ -183,6 +183,7 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||
|
||||
UINT32 downloaded1 = poly1->texture ? poly1->texture->downloaded : 0; // there should be a opengl texture name here, usable for comparisons
|
||||
UINT32 downloaded2 = poly2->texture ? poly2->texture->downloaded : 0;
|
||||
|
||||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
@@ -213,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)
|
||||
|
||||
+380
-246
File diff suppressed because it is too large.
Load diff
+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);
|
||||
|
||||
@@ -96,7 +96,6 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z;
|
||||
fixed_t x2, y2, z2;
|
||||
} polyvertex_t;
|
||||
|
||||
// a convex 'plane' polygon, clockwise order
|
||||
|
||||
@@ -54,7 +54,7 @@ void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32
|
||||
// --------
|
||||
extern extrasubsector_t *extrasubsectors;
|
||||
#ifdef PARANOIA
|
||||
extern size_t addsubsector;
|
||||
extern size_t num_extra_subsector;
|
||||
#endif
|
||||
|
||||
void HWR_FreeExtraSubsectors(void);
|
||||
|
||||
+314
-150
@@ -84,11 +84,6 @@ float gl_viewsin = 0.0f, gl_viewcos = 0.0f;
|
||||
static float gl_viewludsin, gl_viewludcos;
|
||||
static angle_t gl_aimingangle;
|
||||
|
||||
static float yaw = 0.0f;
|
||||
static float inv_yaw = 0.0f;
|
||||
static float cos_inv_yaw = 0.0f;
|
||||
static float sin_inv_yaw = 0.0f;
|
||||
|
||||
static constexpr float deg2radians = (M_PIf / 180.0f);
|
||||
|
||||
seg_t *gl_curline = NULL;
|
||||
@@ -519,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;
|
||||
@@ -537,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;
|
||||
@@ -615,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;
|
||||
@@ -726,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];
|
||||
@@ -747,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;
|
||||
|
||||
@@ -1001,8 +995,9 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
const fixed_t v2y = FloatToFixed(wallVerts[1].z);
|
||||
|
||||
const UINT8 alpha = Surf->PolyColor.s.alpha;
|
||||
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, gl_curline, NULL);
|
||||
FUINT lightnum = sector->lightlevel;
|
||||
extracolormap_t *colormap = NULL;
|
||||
lightnum = HWR_CalcWallLight(lightnum, gl_curline, NULL);
|
||||
|
||||
realtop = top = wallVerts[3].y;
|
||||
realbot = bot = wallVerts[0].y;
|
||||
@@ -1071,11 +1066,11 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
else
|
||||
solid = false;
|
||||
|
||||
height = FixedToFloat(P_GetLightZAt(&list[i], v1x, v1y));
|
||||
endheight = FixedToFloat(P_GetLightZAt(&list[i], v2x, v2y));
|
||||
|
||||
if (solid)
|
||||
{
|
||||
height = FixedToFloat(P_GetLightZAt(&list[i], v1x, v1y));
|
||||
endheight = FixedToFloat(P_GetLightZAt(&list[i], v2x, v2y));
|
||||
|
||||
bheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v1x, v1y));
|
||||
endbheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v2x, v2y));
|
||||
|
||||
@@ -1105,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::max(bheight, realbot);
|
||||
endbot = std::max(endbheight, endrealbot);
|
||||
bot = std::min(std::max(bheight, realbot), top);
|
||||
endbot = std::min(std::max(endbheight, endrealbot), endtop);
|
||||
|
||||
Surf->PolyColor.s.alpha = alpha;
|
||||
|
||||
@@ -1240,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
|
||||
@@ -1390,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;
|
||||
|
||||
@@ -1401,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
|
||||
@@ -1411,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)
|
||||
@@ -1429,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
|
||||
@@ -1441,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)
|
||||
{
|
||||
@@ -1454,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);
|
||||
}
|
||||
@@ -1465,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))
|
||||
{
|
||||
@@ -1537,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))
|
||||
{
|
||||
@@ -2050,11 +2069,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = HWR_CalcWallLight(lightnum, gl_curline, colormap);
|
||||
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(lightnum, colormap);
|
||||
|
||||
lightnum = HWR_CalcWallLight(lightnum, gl_curline, colormap);
|
||||
|
||||
if (other_sector->numlights)
|
||||
HWR_SplitWall(other_sector, wallVerts, 0, false, &Surf, roverflags, rover, blendmode);
|
||||
else
|
||||
@@ -2311,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!
|
||||
@@ -2667,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)
|
||||
{
|
||||
@@ -2679,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)
|
||||
{
|
||||
@@ -2702,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2784,9 +2806,9 @@ static void HWR_Subsector(size_t num)
|
||||
ffloor_t *rover;
|
||||
|
||||
#ifdef PARANOIA // no risk while developing, enough debugging nights!
|
||||
if (num >= addsubsector)
|
||||
if (num >= num_extra_subsector)
|
||||
I_Error("HWR_Subsector: ss %s with numss = %s, addss = %s\n",
|
||||
sizeu1(num), sizeu2(numsubsectors), sizeu3(addsubsector));
|
||||
sizeu1(num), sizeu2(numsubsectors), sizeu3(num_extra_subsector));
|
||||
#endif
|
||||
|
||||
if (num < numsubsectors)
|
||||
@@ -2963,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,
|
||||
@@ -3240,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(
|
||||
@@ -3449,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++)
|
||||
{
|
||||
@@ -3488,6 +3526,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
fixed_t v1x, v1y, v2x, v2y;
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
const boolean billboarding = (cv_glspritebillboarding.value && !cv_glshearing.value && !papersprite);
|
||||
|
||||
gpatch = spr->gpatch;
|
||||
|
||||
// cache the patch in the graphics card memory
|
||||
@@ -3498,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! //
|
||||
@@ -3671,8 +3708,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
|
||||
// Found a break
|
||||
// The heights are clamped to ensure the polygon doesn't cross itself.
|
||||
bot = std::max(bheight, realbot);
|
||||
endbot = std::max(endbheight, endrealbot);
|
||||
bot = std::clamp(bheight, realbot, top);
|
||||
endbot = std::clamp(endbheight, endrealbot, endtop);
|
||||
|
||||
wallVerts[3].t = towtop + ((realtop - top) * towmult);
|
||||
wallVerts[2].t = towtop + ((endrealtop - endtop) * towmult);
|
||||
@@ -3685,7 +3722,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
wallVerts[1].y = endbot;
|
||||
|
||||
// The x and y only need to be adjusted in the case that it's not a papersprite
|
||||
if (cv_glspritebillboarding.value && !cv_glshearing.value && !papersprite)
|
||||
if (billboarding)
|
||||
{
|
||||
// Get the x and z of the vertices so billboarding draws correctly
|
||||
realheight = realbot - realtop;
|
||||
@@ -3707,11 +3744,11 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
wallVerts[1].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult;
|
||||
}
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !(sprmo->frame & FF_FULLBRIGHT));
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !R_ThingIsFullBright(sprmo));
|
||||
|
||||
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;
|
||||
@@ -3738,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);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
@@ -3761,7 +3798,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||
if (!sprmo->subsector)
|
||||
return;
|
||||
|
||||
const boolean papersprite = (sprmo->frame & FF_PAPERSPRITE);
|
||||
const boolean papersprite = R_ThingIsPaperSprite(sprmo);
|
||||
const sector_t *sector = sprmo->subsector->sector;
|
||||
|
||||
if (sector->numlights)
|
||||
@@ -3827,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! //
|
||||
@@ -3920,7 +3954,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
const precipmobj_t *sprmo = spr->precip;
|
||||
precipmobj_t *sprmo = spr->precip;
|
||||
|
||||
if (!sprmo->subsector)
|
||||
return;
|
||||
@@ -3966,11 +4000,10 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
|
||||
if (sector->numlights)
|
||||
{
|
||||
INT32 light;
|
||||
// Always use the light at the top instead of whatever I was doing before
|
||||
INT32 light = R_GetPlaneLight(sector, sprmo->z, false); // sprmo->z + sprmo->height
|
||||
|
||||
light = R_GetPlaneLight(sector, sprmo->z, false); // Always use the light at the top instead of whatever I was doing before
|
||||
|
||||
if (!(sprmo->frame & FF_FULLBRIGHT))
|
||||
if (!R_PrecipThingIsFullBright(sprmo))
|
||||
lightlevel = static_cast<INT32>(*sector->lightlist[light].lightlevel);
|
||||
|
||||
if (sector->lightlist[light].extra_colormap)
|
||||
@@ -3978,7 +4011,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(sprmo->frame & FF_FULLBRIGHT))
|
||||
if (!R_PrecipThingIsFullBright(sprmo))
|
||||
lightlevel = static_cast<INT32>(sector->lightlevel);
|
||||
|
||||
if (sector->extra_colormap)
|
||||
@@ -4281,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);
|
||||
@@ -4562,7 +4598,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
return;
|
||||
}
|
||||
|
||||
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
|
||||
const boolean papersprite = R_ThingIsPaperSprite(thing);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FixedToFloat(interp.x);
|
||||
@@ -4576,8 +4612,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
return;
|
||||
|
||||
const boolean mirrored = thing->mirrored;
|
||||
const boolean vflip = (thing->eflags & MFE_VERTICALFLIP);
|
||||
const boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored);
|
||||
const boolean vflip = R_ThingVerticallyFlipped(thing);
|
||||
const boolean hflip = (!R_ThingHorizontallyFlipped(thing) != !mirrored);
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
#ifdef RANGECHECK
|
||||
@@ -4630,7 +4666,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
#ifdef ROTSPRITE
|
||||
// determine here if sprite should rotate for optimization
|
||||
const boolean sliprollrotate = (cv_sliptideroll.value && (thing->player && thing->player->sliproll));
|
||||
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || sliprollrotate);
|
||||
const boolean shouldrotate = (interp.sloperoll || interp.slopepitch || interp.roll || interp.pitch || thing->rollangle || thing->temprollangle || sliprollrotate);
|
||||
#endif
|
||||
|
||||
if (sprframe->rotate != SRF_SINGLE || papersprite
|
||||
@@ -4688,7 +4724,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
// this is very messy, but it on-the-fly calculates rotations for all the
|
||||
// pitch and roll variables
|
||||
pitchnroll = R_RotationAngle(ang, camang, &interp);
|
||||
rollangle = thing->rollangle;
|
||||
rollangle = (thing->rollangle - thing->temprollangle);
|
||||
|
||||
if (rollangle || pitchnroll || sliprollrotate)
|
||||
{
|
||||
@@ -4764,9 +4800,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
|
||||
// if the sprite is out of our view, dont need to draw it X)
|
||||
if (!gld_SphereInFrustum(
|
||||
(FixedToFloat(interp.x)) + cos_inv_yaw * (x1 + x2) / 2.0f,
|
||||
(FixedToFloat(interp.x)) + gl_viewsin * (x1 + x2) / 2.0f,
|
||||
FixedToFloat(interp.z) + (y1 + y2) / 2.0f,
|
||||
FixedToFloat(interp.y) - sin_inv_yaw * (x1 + x2) / 2.0f,
|
||||
FixedToFloat(interp.y) - (-gl_viewcos) * (x1 + x2) / 2.0f,
|
||||
//1.5 == sqrt(2) + small delta for MF_FOREGROUND
|
||||
std::max<float>(FixedToFloat(spr_width) * spritexscale,
|
||||
FixedToFloat(spr_height) * spriteyscale) / 2.0f * 1.5f))
|
||||
@@ -4984,9 +5020,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||
y2 *= thing_scale;
|
||||
|
||||
if (!gld_SphereInFrustum(
|
||||
(FixedToFloat(interp.x)) + cos_inv_yaw * (x1 + x2) / 2.0f,
|
||||
(FixedToFloat(interp.x)) + gl_viewsin * (x1 + x2) / 2.0f,
|
||||
FixedToFloat(interp.z) + (y1 + y2) / 2.0f,
|
||||
FixedToFloat(interp.y) - sin_inv_yaw * (x1 + x2) / 2.0f,
|
||||
FixedToFloat(interp.y) - (-gl_viewcos) * (x1 + x2) / 2.0f,
|
||||
//1.5 == sqrt(2) + small delta for MF_FOREGROUND
|
||||
std::max<float>(FixedToFloat(spr_width) * thing_scale,
|
||||
FixedToFloat(spr_height) * thing_scale) / 2.0f * 1.5f))
|
||||
@@ -5116,24 +5152,22 @@ void HWR_BuildSkyDome(void)
|
||||
int c, r;
|
||||
signed char yflip;
|
||||
static constexpr int row_count = 4;
|
||||
int col_count = 4;
|
||||
static constexpr int col_count = (4 * 16);
|
||||
float delta;
|
||||
|
||||
gl_sky_t *sky = &gl_sky;
|
||||
gl_skyvertex_t *vertex_p;
|
||||
const texture_t *texture = textures[texturetranslation[skytexture]];
|
||||
|
||||
col_count *= 16;
|
||||
|
||||
if ((sky->columns != col_count) || (sky->rows != row_count))
|
||||
HWR_ClearSkyDome();
|
||||
|
||||
sky->columns = col_count;
|
||||
sky->rows = row_count;
|
||||
sky->vertex_count = 2 * sky->rows * (sky->columns * 2 + 2) + sky->columns * 2;
|
||||
sky->vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2;
|
||||
|
||||
if (!sky->loops)
|
||||
sky->loops = static_cast<gl_skyloopdef_t*>(malloc((sky->rows * 2 + 2) * sizeof(sky->loops[0])));
|
||||
sky->loops = static_cast<gl_skyloopdef_t*>(malloc((row_count * 2 + 2) * sizeof(sky->loops[0])));
|
||||
|
||||
// create vertex array
|
||||
if (!sky->data)
|
||||
@@ -5186,15 +5220,10 @@ void HWR_BuildSkyDome(void)
|
||||
// precompute to save a bit of division
|
||||
static constexpr float FINEDEGREE = (360.0f/static_cast<float>(FINEANGLES));
|
||||
|
||||
static void HWR_DrawSkyBackground(void)
|
||||
static void HWR_DrawSkyDome(void)
|
||||
{
|
||||
FTransform dometransform;
|
||||
|
||||
if (HWR_IsWireframeMode())
|
||||
return;
|
||||
|
||||
GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
|
||||
memcpy(&dometransform, &atransform, sizeof(FTransform));
|
||||
|
||||
dometransform.x = dometransform.y = dometransform.z = 0.0;
|
||||
@@ -5219,6 +5248,124 @@ static void HWR_DrawSkyBackground(void)
|
||||
GL_RenderSkyDome(&gl_sky);
|
||||
}
|
||||
|
||||
// the following is karts old sky code from before the skydome stuff
|
||||
// this appears to differ a bit from srb2´s old sky code
|
||||
static void HWR_DrawSkyTexture(void)
|
||||
{
|
||||
FOutVector v[4];
|
||||
angle_t angle;
|
||||
float dimensionmultiply;
|
||||
float aspectratio;
|
||||
float angleturn;
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture], false);
|
||||
|
||||
aspectratio = (float)vid.width/(float)vid.height;
|
||||
|
||||
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
|
||||
// because it's called just after clearing the screen
|
||||
// and thus, the near clipping plane is set to 3.99
|
||||
// Sryder: Just use the near clipping plane value then
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
v[0].x = v[3].x = -ZCLIP_PLANE-1;
|
||||
v[1].x = v[2].x = ZCLIP_PLANE+1;
|
||||
v[0].y = v[1].y = -ZCLIP_PLANE-1;
|
||||
v[2].y = v[3].y = ZCLIP_PLANE+1;
|
||||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1;
|
||||
|
||||
// X
|
||||
|
||||
// NOTE: This doesn't work right with texture widths greater than 1024
|
||||
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
|
||||
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
|
||||
|
||||
//angle = (viewangle + ANGLE_45);
|
||||
angle = (viewangle + xtoviewangle[0]);
|
||||
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
|
||||
|
||||
if (atransform.fliptype == TRANSFORM_MIRROR ||
|
||||
atransform.fliptype == TRANSFORM_MIRRORFLIP)
|
||||
{
|
||||
angle = InvAngle(angle);
|
||||
dimensionmultiply *= -1;
|
||||
}
|
||||
|
||||
v[0].s = v[3].s = ((float)angle / ((float)(ANGLE_90-1)*dimensionmultiply));
|
||||
v[2].s = v[1].s = (-1.0f/dimensionmultiply)+((float) angle / ((float)(ANGLE_90-1)*dimensionmultiply));
|
||||
|
||||
// Y
|
||||
angle = aimingangle;
|
||||
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
|
||||
|
||||
if (splitscreen == 1)
|
||||
{
|
||||
dimensionmultiply *= 2;
|
||||
angle *= 2;
|
||||
}
|
||||
|
||||
// Middle of the sky should always be at angle 0
|
||||
// need to keep correct aspect ratio with X
|
||||
if (atransform.fliptype == TRANSFORM_FLIP ||
|
||||
atransform.fliptype == TRANSFORM_MIRRORFLIP)
|
||||
{
|
||||
// During vertical flip the sky should be flipped and it's y movement should also be flipped obviously
|
||||
v[3].t = v[2].t = -(0.5f-(0.5f/dimensionmultiply));
|
||||
v[0].t = v[1].t = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply));
|
||||
}
|
||||
else
|
||||
{
|
||||
v[3].t = v[2].t = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply));
|
||||
v[0].t = v[1].t = -(0.5f-(0.5f/dimensionmultiply));
|
||||
}
|
||||
|
||||
angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply;
|
||||
|
||||
if (cv_glshearing.value)
|
||||
{
|
||||
// Doesn't really make sense, but what can I do?
|
||||
angle_t dy = FixedAngle(FixedMul(360*FRACUNIT, FixedDiv(AIMINGTODY(aimingangle), 900*FRACUNIT)));
|
||||
v[3].t = v[2].t -= ((float) dy / angleturn);
|
||||
v[0].t = v[1].t -= ((float) dy / angleturn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa
|
||||
{
|
||||
angle = InvAngle(angle);
|
||||
v[3].t = v[2].t += ((float) angle / angleturn);
|
||||
v[0].t = v[1].t += ((float) angle / angleturn);
|
||||
}
|
||||
else
|
||||
{
|
||||
v[3].t = v[2].t -= ((float) angle / angleturn);
|
||||
v[0].t = v[1].t -= ((float) angle / angleturn);
|
||||
}
|
||||
}
|
||||
|
||||
// since sky is drawn as a "flat quad" this way, we have to unset any view transformations for it to work
|
||||
GL_SetTransform(NULL);
|
||||
GL_UnSetShader();
|
||||
GL_DrawPolygon(NULL, v, 4, 0);
|
||||
}
|
||||
|
||||
static void HWR_DrawSkyBackground(void)
|
||||
{
|
||||
if (HWR_IsWireframeMode())
|
||||
return;
|
||||
|
||||
GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
|
||||
if (cv_skydome.value)
|
||||
HWR_DrawSkyDome();
|
||||
else
|
||||
HWR_DrawSkyTexture();
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// HWR_ClearView : clear the viewwindow, with maximum z value. also clears stencil buffer.
|
||||
// -----------------+
|
||||
@@ -5284,12 +5431,6 @@ void HWR_SetTransform(float fpov)
|
||||
HWR_SetTransformAiming(&atransform);
|
||||
atransform.angley = static_cast<float>(viewangle >> ANGLETOFINESHIFT)*(FINEDEGREE);
|
||||
|
||||
yaw = 270.0f - atransform.angley;
|
||||
inv_yaw = 180.0f - yaw;
|
||||
const float inv_yaw_radians = inv_yaw * deg2radians;
|
||||
cos_inv_yaw = cosf(inv_yaw_radians);
|
||||
sin_inv_yaw = sinf(inv_yaw_radians);
|
||||
|
||||
// only needed for sprite billboarding
|
||||
if (cv_glspritebillboarding.value && !cv_glshearing.value)
|
||||
{
|
||||
@@ -5352,6 +5493,8 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
|
||||
{
|
||||
gl_portallist_t portallist;
|
||||
|
||||
const boolean wireframe = HWR_IsWireframeMode();
|
||||
|
||||
player_t *viewplayer = &players[displayplayers[viewssnum]];
|
||||
const float fpov = FixedToFloat(R_GetPlayerFov(viewplayer));
|
||||
|
||||
@@ -5412,7 +5555,7 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
|
||||
}
|
||||
}
|
||||
|
||||
if (HWR_IsWireframeMode())
|
||||
if (wireframe)
|
||||
GL_SetSpecialState(HWD_SET_WIREFRAME, 1);
|
||||
|
||||
// FIXME: perfstats does not account for portal rendering!
|
||||
@@ -5427,7 +5570,8 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
|
||||
|
||||
if constexpr (Type == RenderViewpointType::kPortal)
|
||||
{
|
||||
gl_collect_skywalls = (allow_portals && !rootportal && portallist.base && (!skyboxmo[0] || !cv_skybox.value)); // if portals have been drawn in the main view, then render skywalls differently
|
||||
// if portals have been drawn in the main view, then render skywalls differently
|
||||
gl_collect_skywalls = (allow_portals && !rootportal && portallist.base && (!skyboxmo[0] || !cv_skybox.value));
|
||||
|
||||
// HAYA: Save the old portal state, and turn portals off while normally rendering the BSP tree.
|
||||
// This fixes specific effects not working, such as horizon lines.
|
||||
@@ -5497,7 +5641,7 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, int stencil_level, bool
|
||||
|
||||
HWR_RenderDrawNodes();
|
||||
|
||||
if (HWR_IsWireframeMode())
|
||||
if (wireframe)
|
||||
GL_SetSpecialState(HWD_SET_WIREFRAME, 0);
|
||||
|
||||
HWR_FreePortalList(portallist); // always call this just in case
|
||||
@@ -5886,6 +6030,10 @@ static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD
|
||||
|
||||
static void HWR_DoPostProcessor(void)
|
||||
{
|
||||
// no flashes or screen waving if we want less vfx!
|
||||
if (cv_reducevfx.value)
|
||||
return;
|
||||
|
||||
// Armageddon Blast Flash!
|
||||
// Could this even be considered postprocessor?
|
||||
if (!HWR_ShouldUsePaletteRendering())
|
||||
@@ -5925,7 +6073,7 @@ static void HWR_DoPostProcessor(void)
|
||||
return;
|
||||
|
||||
// Not supported in splitscreen - someone want to add support?
|
||||
if (splitscreen || cv_reducevfx.value)
|
||||
if (splitscreen)
|
||||
return;
|
||||
|
||||
//UINT8 viewnum = R_GetViewNumber();
|
||||
@@ -5983,44 +6131,60 @@ static void HWR_DoPostProcessor(void)
|
||||
// Flipping of the screen isn't done here anymore
|
||||
}
|
||||
|
||||
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
|
||||
//
|
||||
// wipes
|
||||
//
|
||||
static lumpnum_t wipelumpnum;
|
||||
|
||||
// puts wipe lumpname in wipename[9]
|
||||
static boolean HWR_WipeCheck(UINT8 wipenum, UINT8 scrnnum)
|
||||
{
|
||||
static char lumpname[9] = "FADEmmss";
|
||||
lumpnum_t lumpnum;
|
||||
size_t lsize;
|
||||
|
||||
// screen textures disabled completely
|
||||
if (cv_glscreentextures.value == 0)
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wipenum > 99 || scrnnum > 99) // not a valid wipe number
|
||||
// not a valid wipe number
|
||||
if (wipenum > 99 || scrnnum > 99)
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap
|
||||
return; // shouldn't end up here really, the loop should've stopped running beforehand
|
||||
return false; // shouldn't end up here really, the loop should've stopped running beforehand
|
||||
}
|
||||
|
||||
// puts the numbers into the lumpname
|
||||
sprintf(&lumpname[4], "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
|
||||
lumpnum = W_CheckNumForName(lumpname);
|
||||
snprintf(&lumpname[4], sizeof(lumpname) - 4, "%.2hu%.2hu", (UINT16)wipenum, (UINT16)scrnnum);
|
||||
wipelumpnum = W_CheckNumForName(lumpname);
|
||||
|
||||
if (lumpnum == LUMPERROR) // again, shouldn't be here really
|
||||
// again, shouldn't be here really
|
||||
if (wipelumpnum == LUMPERROR)
|
||||
{
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
lsize = W_LumpLength(lumpnum);
|
||||
lsize = W_LumpLength(wipelumpnum);
|
||||
|
||||
if (!(lsize == 256000 || lsize == 64000 || lsize == 16000 || lsize == 4000))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Fade mask lump %s of incorrect size, ignored\n", lumpname);
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap
|
||||
return; // again, shouldn't get here if it is a bad size
|
||||
return false; // again, shouldn't get here if it is a bad size
|
||||
}
|
||||
|
||||
HWR_GetFadeMask(lumpnum);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
|
||||
{
|
||||
if (!HWR_WipeCheck(wipenum, scrnnum))
|
||||
{
|
||||
// just draw a black screen instead of rapidly flashing a white screen
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
return;
|
||||
}
|
||||
|
||||
HWR_GetFadeMask(wipelumpnum);
|
||||
GL_DoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END);
|
||||
}
|
||||
|
||||
|
||||
+12
-10
@@ -1146,15 +1146,18 @@ 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;
|
||||
INT32 tics = spr->mobj->tics;
|
||||
//mdlframe_t *next = NULL;
|
||||
|
||||
//const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj)); // :chaosleep:
|
||||
const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP);
|
||||
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP));
|
||||
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
|
||||
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
spriteinfo_t *sprinfo;
|
||||
@@ -1218,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;
|
||||
@@ -1244,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)
|
||||
@@ -1400,12 +1403,11 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
|
||||
const angle_t sliptideroll = ((cv_sliptideroll.value && spr->mobj->player) ? spr->mobj->player->sliproll : 0);
|
||||
const SINT8 flipfactor = flip ? -1 : 1;
|
||||
const angle_t thingrollangle = (spr->mobj->rollangle - spr->mobj->temprollangle);
|
||||
|
||||
if (spr->mobj->rollangle || sliptideroll)
|
||||
if (thingrollangle || sliptideroll)
|
||||
{
|
||||
angle_t rollang = sliptideroll
|
||||
? (spr->mobj->rollangle) + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])
|
||||
: (spr->mobj->rollangle);
|
||||
angle_t rollang = sliptideroll ? (thingrollangle + (sliptideroll * spr->mobj->player->kartstuff[k_aizdriftstrat])) : thingrollangle;
|
||||
|
||||
rollang *= flipfactor;
|
||||
|
||||
@@ -1481,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);
|
||||
|
||||
|
||||
@@ -1,549 +0,0 @@
|
||||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief Windows specific part of the OpenGL API for Doom Legacy
|
||||
///
|
||||
/// TODO:
|
||||
/// - check if windowed mode works
|
||||
/// - support different pixel formats
|
||||
|
||||
|
||||
#if defined (_WIN32)
|
||||
|
||||
//#define WIN32_LEAN_AND_MEAN
|
||||
#define RPC_NO_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include "r_opengl.h"
|
||||
|
||||
|
||||
// **************************************************************************
|
||||
// GLOBALS
|
||||
// **************************************************************************
|
||||
|
||||
#ifdef DEBUG_TO_FILE
|
||||
static unsigned long nb_frames = 0;
|
||||
static clock_t my_clock;
|
||||
FILE *gllogstream;
|
||||
#endif
|
||||
|
||||
static HDC hDC = NULL; // the window's device context
|
||||
static HGLRC hGLRC = NULL; // the OpenGL rendering context
|
||||
static HWND hWnd = NULL;
|
||||
static BOOL WasFullScreen = FALSE;
|
||||
static void UnSetRes(void);
|
||||
|
||||
#ifdef USE_WGL_SWAP
|
||||
PFNWGLEXTSWAPCONTROLPROC wglSwapIntervalEXT = NULL;
|
||||
#endif
|
||||
|
||||
PFNglClear pglClear;
|
||||
PFNglGetIntegerv pglGetIntegerv;
|
||||
PFNglGetString pglGetString;
|
||||
|
||||
#define MAX_VIDEO_MODES 32
|
||||
static vmode_t video_modes[MAX_VIDEO_MODES];
|
||||
INT32 oglflags = 0;
|
||||
|
||||
// **************************************************************************
|
||||
// FUNCTIONS
|
||||
// **************************************************************************
|
||||
|
||||
// -----------------+
|
||||
// APIENTRY DllMain : DLL Entry Point,
|
||||
// : open/close debug log
|
||||
// Returns :
|
||||
// -----------------+
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
|
||||
DWORD fdwReason, // reason for calling function
|
||||
LPVOID lpvReserved) // reserved
|
||||
{
|
||||
// Perform actions based on the reason for calling.
|
||||
UNREFERENCED_PARAMETER(lpvReserved);
|
||||
switch (fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
// Initialize once for each new process.
|
||||
// Return FALSE to fail DLL load.
|
||||
#ifdef DEBUG_TO_FILE
|
||||
gllogstream = fopen("ogllog.txt", "wt");
|
||||
if (gllogstream == NULL)
|
||||
return FALSE;
|
||||
#endif
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
// Do thread-specific initialization.
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
// Do thread-specific cleanup.
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
// Perform any necessary cleanup.
|
||||
#ifdef DEBUG_TO_FILE
|
||||
if (gllogstream)
|
||||
{
|
||||
fclose(gllogstream);
|
||||
gllogstream = NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE; // Successful DLL_PROCESS_ATTACH.
|
||||
}
|
||||
|
||||
#ifdef STATIC_OPENGL
|
||||
#define pwglGetProcAddress wglGetProcAddress;
|
||||
#define pwglCreateContext wglCreateContext;
|
||||
#define pwglDeleteContext wglDeleteContext;
|
||||
#define pwglMakeCurrent wglMakeCurrent;
|
||||
#else
|
||||
static HMODULE OGL32;
|
||||
typedef void *(WINAPI *PFNwglGetProcAddress) (const char *);
|
||||
static PFNwglGetProcAddress pwglGetProcAddress;
|
||||
typedef HGLRC (WINAPI *PFNwglCreateContext) (HDC hdc);
|
||||
static PFNwglCreateContext pwglCreateContext;
|
||||
typedef BOOL (WINAPI *PFNwglDeleteContext) (HGLRC hglrc);
|
||||
static PFNwglDeleteContext pwglDeleteContext;
|
||||
typedef BOOL (WINAPI *PFNwglMakeCurrent) (HDC hdc, HGLRC hglrc);
|
||||
static PFNwglMakeCurrent pwglMakeCurrent;
|
||||
#endif
|
||||
|
||||
#ifndef STATIC_OPENGL
|
||||
void *GetGLFunc(const char *proc)
|
||||
{
|
||||
void *func = NULL;
|
||||
if (pwglGetProcAddress)
|
||||
func = pwglGetProcAddress(proc);
|
||||
if (!func)
|
||||
func = GetProcAddress(OGL32, proc);
|
||||
return func;
|
||||
}
|
||||
#endif
|
||||
|
||||
boolean LoadGL(void)
|
||||
{
|
||||
#ifndef STATIC_OPENGL
|
||||
OGL32 = LoadLibrary("OPENGL32.DLL");
|
||||
|
||||
if (!OGL32)
|
||||
return 0;
|
||||
|
||||
pwglGetProcAddress = GetGLFunc("wglGetProcAddress");
|
||||
pwglCreateContext = GetGLFunc("wglCreateContext");
|
||||
pwglDeleteContext = GetGLFunc("wglDeleteContext");
|
||||
pwglMakeCurrent = GetGLFunc("wglMakeCurrent");
|
||||
#endif
|
||||
return SetupGLfunc();
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// SetupPixelFormat : Set the device context's pixel format
|
||||
// Note : Because we currently use only the desktop's BPP format, all the
|
||||
// : video modes in Doom Legacy OpenGL are of the same BPP, thus the
|
||||
// : PixelFormat is set only once.
|
||||
// : Setting the pixel format more than once on the same window
|
||||
// : doesn't work. (ultimately for different pixel formats, we
|
||||
// : should close the window, and re-create it)
|
||||
// -----------------+
|
||||
int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepthBits)
|
||||
{
|
||||
static DWORD iLastPFD = 0;
|
||||
INT32 nPixelFormat;
|
||||
PIXELFORMATDESCRIPTOR pfd =
|
||||
{
|
||||
sizeof (PIXELFORMATDESCRIPTOR), // size
|
||||
1, // version
|
||||
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
|
||||
PFD_TYPE_RGBA, // color type
|
||||
32 /*WantColorBits*/, // cColorBits : prefered color depth
|
||||
0, 0, // cRedBits, cRedShift
|
||||
0, 0, // cGreenBits, cGreenShift
|
||||
0, 0, // cBlueBits, cBlueShift
|
||||
0, 0, // cAlphaBits, cAlphaShift
|
||||
0, // cAccumBits
|
||||
0, 0, 0, 0, // cAccum Red/Green/Blue/Alpha Bits
|
||||
0, // cDepthBits (0,16,24,32)
|
||||
0, // cStencilBits
|
||||
0, // cAuxBuffers
|
||||
PFD_MAIN_PLANE, // iLayerType
|
||||
0, // reserved, must be zero
|
||||
0, 0, 0, // dwLayerMask, dwVisibleMask, dwDamageMask
|
||||
};
|
||||
|
||||
DWORD iPFD = (WantColorBits<<16) | (WantStencilBits<<8) | WantDepthBits;
|
||||
|
||||
pfd.cDepthBits = (BYTE)WantDepthBits;
|
||||
pfd.cStencilBits = (BYTE)WantStencilBits;
|
||||
|
||||
if (iLastPFD)
|
||||
{
|
||||
DBG_Printf("WARNING : SetPixelFormat() called twise not supported by all drivers !\n");
|
||||
}
|
||||
|
||||
// set the pixel format only if different than the current
|
||||
if (iPFD == iLastPFD)
|
||||
return 2;
|
||||
else
|
||||
iLastPFD = iPFD;
|
||||
|
||||
DBG_Printf("SetupPixelFormat() - %d ColorBits - %d StencilBits - %d DepthBits\n",
|
||||
WantColorBits, WantStencilBits, WantDepthBits);
|
||||
|
||||
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
|
||||
|
||||
if (nPixelFormat == 0)
|
||||
DBG_Printf("ChoosePixelFormat() FAILED\n");
|
||||
|
||||
if (SetPixelFormat(hDC, nPixelFormat, &pfd) == 0)
|
||||
{
|
||||
DBG_Printf("SetPixelFormat() FAILED\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// -----------------+
|
||||
// SetRes : Set a display mode
|
||||
// Notes : pcurrentmode is actually not used
|
||||
// -----------------+
|
||||
static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
|
||||
{
|
||||
LPCSTR renderer;
|
||||
BOOL WantFullScreen = !(lvid->u.windowed); //(lvid->u.windowed ? 0 : CDS_FULLSCREEN);
|
||||
|
||||
UNREFERENCED_PARAMETER(pcurrentmode);
|
||||
DBG_Printf ("SetMode(): %dx%d %d bits (%s)\n",
|
||||
lvid->width, lvid->height, lvid->bpp*8,
|
||||
WantFullScreen ? "fullscreen" : "windowed");
|
||||
|
||||
hWnd = lvid->WndParent;
|
||||
|
||||
// BP : why flush texture ?
|
||||
// if important flush also the first one (white texture) and restore it !
|
||||
Flush(); // Flush textures.
|
||||
|
||||
// TODO: if not fullscreen, skip display stuff and just resize viewport stuff ...
|
||||
|
||||
// Exit previous mode
|
||||
//if (hGLRC) //Hurdler: TODO: check if this is valid
|
||||
// UnSetRes();
|
||||
if (WasFullScreen)
|
||||
ChangeDisplaySettings(NULL, CDS_FULLSCREEN); //switch in and out of fullscreen
|
||||
|
||||
// Change display settings.
|
||||
if (WantFullScreen)
|
||||
{
|
||||
DEVMODE dm;
|
||||
ZeroMemory(&dm, sizeof (dm));
|
||||
dm.dmSize = sizeof (dm);
|
||||
dm.dmPelsWidth = lvid->width;
|
||||
dm.dmPelsHeight = lvid->height;
|
||||
dm.dmBitsPerPel = lvid->bpp*8;
|
||||
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
|
||||
if (ChangeDisplaySettings(&dm, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
|
||||
return -2;
|
||||
if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) !=DISP_CHANGE_SUCCESSFUL)
|
||||
return -3;
|
||||
|
||||
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP|WS_VISIBLE);
|
||||
// faB : book says to put these, surely for windowed mode
|
||||
//WS_CLIPCHILDREN|WS_CLIPSIBLINGS);
|
||||
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, lvid->width, lvid->height, SWP_NOACTIVATE|SWP_NOZORDER);
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT bounds;
|
||||
INT32 x, y;
|
||||
INT32 w = lvid->width, h = lvid->height;
|
||||
GetWindowRect(hWnd, &bounds);
|
||||
bounds.right = bounds.left+w;
|
||||
bounds.bottom = bounds.top+h;
|
||||
AdjustWindowRectEx(&bounds, GetWindowLong(hWnd, GWL_STYLE), (GetMenu(hWnd) != NULL), 0);
|
||||
w = bounds.right-bounds.left;
|
||||
h = bounds.bottom-bounds.top;
|
||||
x = (GetSystemMetrics(SM_CXSCREEN)-w)/2;
|
||||
y = (GetSystemMetrics(SM_CYSCREEN)-h)/2;
|
||||
SetWindowPos(hWnd, NULL, x, y, w, h, SWP_NOACTIVATE|SWP_NOZORDER);
|
||||
}
|
||||
|
||||
if (!hDC)
|
||||
hDC = GetDC(hWnd);
|
||||
if (!hDC)
|
||||
{
|
||||
DBG_Printf("GetDC() FAILED\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
INT32 res;
|
||||
|
||||
// Set res.
|
||||
res = SetupPixelFormat(lvid->bpp*8, 0, 16);
|
||||
|
||||
if (res == 0)
|
||||
return 0;
|
||||
else if (res == 1)
|
||||
{
|
||||
// Exit previous mode
|
||||
if (hGLRC)
|
||||
UnSetRes();
|
||||
hGLRC = pwglCreateContext(hDC);
|
||||
if (!hGLRC)
|
||||
{
|
||||
DBG_Printf("pwglCreateContext() FAILED\n");
|
||||
return 0;
|
||||
}
|
||||
if (!pwglMakeCurrent(hDC, hGLRC))
|
||||
{
|
||||
DBG_Printf("wglMakeCurrent() FAILED\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gl_extensions = pglGetString(GL_EXTENSIONS);
|
||||
// Get info and extensions.
|
||||
//BP: why don't we make it earlier ?
|
||||
//Hurdler: we cannot do that before intialising gl context
|
||||
renderer = (LPCSTR)pglGetString(GL_RENDERER);
|
||||
DBG_Printf("Vendor : %s\n", pglGetString(GL_VENDOR));
|
||||
DBG_Printf("Renderer : %s\n", renderer);
|
||||
DBG_Printf("Version : %s\n", pglGetString(GL_VERSION));
|
||||
DBG_Printf("Extensions : %s\n", gl_extensions);
|
||||
|
||||
// BP: disable advenced feature that don't work on somes hardware
|
||||
// Hurdler: Now works on G400 with bios 1.6 and certified drivers 6.04
|
||||
if (strstr(renderer, "810")) oglflags |= GLF_NOZBUFREAD;
|
||||
DBG_Printf("oglflags : 0x%X\n", oglflags);
|
||||
|
||||
#ifdef USE_WGL_SWAP
|
||||
if (isExtAvailable("WGL_EXT_swap_control",gl_extensions))
|
||||
wglSwapIntervalEXT = GetGLFunc("wglSwapIntervalEXT");
|
||||
else
|
||||
wglSwapIntervalEXT = NULL;
|
||||
#endif
|
||||
|
||||
if (isExtAvailable("GL_EXT_texture_filter_anisotropic",gl_extensions))
|
||||
pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy);
|
||||
else
|
||||
maximumAnisotropy = 0;
|
||||
|
||||
SetupGLFunc13();
|
||||
|
||||
screen_depth = (GLbyte)(lvid->bpp*8);
|
||||
if (screen_depth > 16)
|
||||
textureformatGL = GL_RGBA;
|
||||
else
|
||||
textureformatGL = GL_RGB5_A1;
|
||||
|
||||
GL_SetModelView(lvid->width, lvid->height);
|
||||
GL_SetStates();
|
||||
// we need to clear the depth buffer. Very important!!!
|
||||
pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
lvid->buffer = NULL; // unless we use the software view
|
||||
lvid->direct = NULL; // direct access to video memory, old DOS crap
|
||||
|
||||
WasFullScreen = WantFullScreen;
|
||||
|
||||
return 1; // on renvoie une valeur pour dire que cela s'est bien pass�
|
||||
}
|
||||
|
||||
|
||||
// -----------------+
|
||||
// UnSetRes : Restore the original display mode
|
||||
// -----------------+
|
||||
static void UnSetRes(void)
|
||||
{
|
||||
DBG_Printf("UnSetRes()\n");
|
||||
|
||||
pwglMakeCurrent(hDC, NULL);
|
||||
pwglDeleteContext(hGLRC);
|
||||
hGLRC = NULL;
|
||||
if (WasFullScreen)
|
||||
ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
|
||||
}
|
||||
|
||||
|
||||
// -----------------+
|
||||
// GetModeList : Return the list of available display modes.
|
||||
// Returns : pvidmodes - points to list of detected OpenGL video modes
|
||||
// : numvidmodes - number of detected OpenGL video modes
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
#if 1
|
||||
INT32 iMode;
|
||||
/*
|
||||
faB test code
|
||||
|
||||
Commented out because there might be a problem with combo (Voodoo2 + other card),
|
||||
we need to get the 3D card's display modes only.
|
||||
*/
|
||||
(*pvidmodes) = &video_modes[0];
|
||||
|
||||
// Get list of device modes
|
||||
for (i = 0,iMode = 0; iMode < MAX_VIDEO_MODES; i++)
|
||||
{
|
||||
DEVMODE Tmp;
|
||||
ZeroMemory(&Tmp, sizeof (Tmp));
|
||||
Tmp.dmSize = sizeof (Tmp);
|
||||
if (!EnumDisplaySettings(NULL, i, &Tmp))
|
||||
break;
|
||||
|
||||
// add video mode
|
||||
if (Tmp.dmBitsPerPel == 16 &&
|
||||
(iMode == 0 || !
|
||||
(Tmp.dmPelsWidth == video_modes[iMode-1].width &&
|
||||
Tmp.dmPelsHeight == video_modes[iMode-1].height)
|
||||
)
|
||||
)
|
||||
{
|
||||
video_modes[iMode].pnext = &video_modes[iMode+1];
|
||||
video_modes[iMode].windowed = 0; // fullscreen is the default
|
||||
video_modes[iMode].misc = 0;
|
||||
video_modes[iMode].name = malloc(12 * sizeof (CHAR));
|
||||
sprintf(video_modes[iMode].name, "%dx%d", (INT32)Tmp.dmPelsWidth, (INT32)Tmp.dmPelsHeight);
|
||||
DBG_Printf ("Mode: %s\n", video_modes[iMode].name);
|
||||
video_modes[iMode].width = Tmp.dmPelsWidth;
|
||||
video_modes[iMode].height = Tmp.dmPelsHeight;
|
||||
video_modes[iMode].bytesperpixel = Tmp.dmBitsPerPel/8;
|
||||
video_modes[iMode].rowbytes = Tmp.dmPelsWidth * video_modes[iMode].bytesperpixel;
|
||||
video_modes[iMode].pextradata = NULL;
|
||||
video_modes[iMode].setmode = SetRes;
|
||||
iMode++;
|
||||
}
|
||||
}
|
||||
(*numvidmodes) = iMode;
|
||||
#else
|
||||
|
||||
// classic video modes (fullscreen/windowed)
|
||||
// Added some. Tails
|
||||
INT32 res[][2] = {
|
||||
{ 320, 200},
|
||||
{ 320, 240},
|
||||
{ 400, 300},
|
||||
{ 512, 384},
|
||||
{ 640, 400},
|
||||
{ 640, 480},
|
||||
{ 800, 600},
|
||||
{ 960, 600},
|
||||
{1024, 768},
|
||||
{1152, 864},
|
||||
{1280, 800},
|
||||
{1280, 960},
|
||||
{1280,1024},
|
||||
{1600,1000},
|
||||
{1680,1050},
|
||||
{1920,1200},
|
||||
};
|
||||
|
||||
HDC bpphdc;
|
||||
INT32 iBitsPerPel;
|
||||
|
||||
DBG_Printf ("HWRAPI GetModeList()\n");
|
||||
|
||||
bpphdc = GetDC(NULL); // on obtient le bpp actuel
|
||||
iBitsPerPel = GetDeviceCaps(bpphdc, BITSPIXEL);
|
||||
|
||||
ReleaseDC(NULL, bpphdc);
|
||||
|
||||
(*pvidmodes) = &video_modes[0];
|
||||
(*numvidmodes) = sizeof (res) / sizeof (res[0]);
|
||||
for (i = 0; i < (*numvidmodes); i++)
|
||||
{
|
||||
video_modes[i].pnext = &video_modes[i+1];
|
||||
video_modes[i].windowed = 0; // fullscreen is the default
|
||||
video_modes[i].misc = 0;
|
||||
video_modes[i].name = malloc(12 * sizeof (CHAR));
|
||||
sprintf(video_modes[i].name, "%dx%d", res[i][0], res[i][1]);
|
||||
DBG_Printf ("Mode: %s\n", video_modes[i].name);
|
||||
video_modes[i].width = res[i][0];
|
||||
video_modes[i].height = res[i][1];
|
||||
video_modes[i].bytesperpixel = iBitsPerPel/8;
|
||||
video_modes[i].rowbytes = res[i][0] * video_modes[i].bytesperpixel;
|
||||
video_modes[i].pextradata = NULL;
|
||||
video_modes[i].setmode = SetRes;
|
||||
}
|
||||
#endif
|
||||
video_modes[(*numvidmodes)-1].pnext = NULL;
|
||||
}
|
||||
|
||||
|
||||
// -----------------+
|
||||
// Shutdown : Shutdown OpenGL, restore the display mode
|
||||
// -----------------+
|
||||
EXPORT void HWRAPI(Shutdown) (void)
|
||||
{
|
||||
#ifdef DEBUG_TO_FILE
|
||||
long nb_centiemes;
|
||||
|
||||
DBG_Printf ("HWRAPI Shutdown()\n");
|
||||
nb_centiemes = ((clock()-my_clock)*100)/CLOCKS_PER_SEC;
|
||||
DBG_Printf("Nb frames: %li; Nb sec: %2.2f -> %2.1f fps\n",
|
||||
nb_frames, nb_centiemes/100.0f, (100*nb_frames)/(double)nb_centiemes);
|
||||
#endif
|
||||
|
||||
Flush();
|
||||
|
||||
// Exit previous mode
|
||||
if (hGLRC)
|
||||
UnSetRes();
|
||||
|
||||
if (hDC)
|
||||
{
|
||||
ReleaseDC(hWnd, hDC);
|
||||
hDC = NULL;
|
||||
}
|
||||
FreeLibrary(OGL32);
|
||||
DBG_Printf ("HWRAPI Shutdown(DONE)\n");
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// FinishUpdate : Swap front and back buffers
|
||||
// -----------------+
|
||||
void GL_FinishUpdate (INT32 waitvbl)
|
||||
{
|
||||
#ifdef USE_WGL_SWAP
|
||||
static INT32 oldwaitvbl = 0;
|
||||
#else
|
||||
UNREFERENCED_PARAMETER(waitvbl);
|
||||
#endif
|
||||
// DBG_Printf ("FinishUpdate()\n");
|
||||
#ifdef DEBUG_TO_FILE
|
||||
if ((++nb_frames)==2) // on ne commence pas � la premi�re frame
|
||||
my_clock = clock();
|
||||
#endif
|
||||
|
||||
#ifdef USE_WGL_SWAP
|
||||
if (oldwaitvbl != waitvbl && wglSwapIntervalEXT)
|
||||
wglSwapIntervalEXT(waitvbl);
|
||||
oldwaitvbl = waitvbl;
|
||||
#endif
|
||||
|
||||
SwapBuffers(hDC);
|
||||
}
|
||||
#endif
|
||||
@@ -776,15 +776,15 @@ static int GLFramebuffer_CheckExt(void)
|
||||
// gl versions from 2.1 may still support framebuffer objects
|
||||
|
||||
// maybe, just maybe, we support the standart extensions
|
||||
if (GL_isExtAvailable("GL_ARB_framebuffer_no_attachments", gl_extensions)
|
||||
&& GL_isExtAvailable("GL_ARB_framebuffer_object", gl_extensions)
|
||||
&& GL_isExtAvailable("GL_ARB_framebuffer_sRGB", gl_extensions))
|
||||
if (GL_isExtAvailable("GL_ARB_framebuffer_no_attachments", gl_extensions) &&
|
||||
GL_isExtAvailable("GL_ARB_framebuffer_object", gl_extensions) &&
|
||||
GL_isExtAvailable("GL_ARB_framebuffer_sRGB", gl_extensions))
|
||||
return FBO_ARB;
|
||||
|
||||
// nope, try the older 2.1 extensions
|
||||
if (GL_isExtAvailable("GL_EXT_framebuffer_no_attachments", gl_extensions)
|
||||
&& GL_isExtAvailable("GL_EXT_framebuffer_object", gl_extensions)
|
||||
&& GL_isExtAvailable("GL_EXT_framebuffer_sRGB", gl_extensions))
|
||||
if (GL_isExtAvailable("GL_EXT_framebuffer_no_attachments", gl_extensions) &&
|
||||
GL_isExtAvailable("GL_EXT_framebuffer_object", gl_extensions) &&
|
||||
GL_isExtAvailable("GL_EXT_framebuffer_sRGB", gl_extensions))
|
||||
{
|
||||
// perhaps we may even support a stencil attachment
|
||||
if (GL_isExtAvailable("GL_EXT_packed_depth_stencil", gl_extensions))
|
||||
@@ -885,7 +885,7 @@ void SetupGLFunc4(void)
|
||||
{ \
|
||||
GL_MSG_Warning("failed to get OpenGL FBO function: %s\n", #func); \
|
||||
GL_DBG_Printf("\nFBO: No framebuffer object support\n"); \
|
||||
supportFBO = false; \
|
||||
supportFBO = FBO_NONE; \
|
||||
return; \
|
||||
} \
|
||||
|
||||
@@ -1465,6 +1465,19 @@ void GL_ReadScreenTexture(int tex, UINT8 *restrict dest, INT32 scale)
|
||||
if (tex != HWD_SCREENTEXTURE_GENERIC2)
|
||||
GL_DrawScreenTexture(tex, NULL, 0);
|
||||
|
||||
#ifdef USE_FBO_OGL
|
||||
// FIXME: this is incredibly stupid
|
||||
// but the final screen texture will NOT be drawn in the downsample fbo
|
||||
if (tex == HWD_SCREENTEXTURE_GENERIC2 &&
|
||||
UseScreenFBO() && HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
GL_SetShader(HWR_GetShaderFromTarget(SHADER_PALETTE_POSTPROCESS));
|
||||
GL_EnableShader();
|
||||
GL_DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0);
|
||||
GL_UnSetShader();
|
||||
}
|
||||
#endif
|
||||
|
||||
image = malloc(screen_width*screen_height*3);
|
||||
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
pglReadPixels(0, 0, screen_width, screen_height, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||||
@@ -1918,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;
|
||||
@@ -2490,7 +2504,7 @@ void GL_RenderSkyDome(gl_sky_t *sky)
|
||||
GL_Shader_SetUniforms(NULL, NULL, NULL, NULL);
|
||||
|
||||
// Build the sky dome! Yes!
|
||||
if (sky->rebuild)
|
||||
if (sky->rebuild || !sky->vbo)
|
||||
{
|
||||
// delete VBO when already exists
|
||||
if (sky->vbo)
|
||||
@@ -2915,7 +2929,7 @@ void GL_CreateModelVBOs(model_t *model)
|
||||
}
|
||||
}
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char*)(i))
|
||||
#define BUFFER_OFFSET(i) ((void*)(i))
|
||||
|
||||
void GL_DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
|
||||
{
|
||||
@@ -3208,8 +3222,8 @@ void GL_SetTransform(FTransform *stransform)
|
||||
{
|
||||
float dy = stransform->viewaiming * 2;
|
||||
|
||||
if (stransform->fliptype == TRANSFORM_FLIP
|
||||
|| stransform->fliptype == TRANSFORM_MIRRORFLIP)
|
||||
if (stransform->fliptype == TRANSFORM_FLIP ||
|
||||
stransform->fliptype == TRANSFORM_MIRRORFLIP)
|
||||
dy *= -1.0f;
|
||||
|
||||
pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f);
|
||||
@@ -3234,7 +3248,7 @@ void GL_SetTransform(FTransform *stransform)
|
||||
#ifdef USE_FBO_OGL
|
||||
static void GL_Framebuffer_DeleteAttachments(void)
|
||||
{
|
||||
if (!supportFBO || !framebufferobject.init)
|
||||
if (supportFBO == FBO_NONE || !framebufferobject.init)
|
||||
return;
|
||||
|
||||
// Unbind the framebuffer
|
||||
@@ -3254,7 +3268,7 @@ static void GL_Framebuffer_DeleteAttachments(void)
|
||||
|
||||
static void GL_Framebuffer_Generate(void)
|
||||
{
|
||||
if (!supportFBO || framebufferobject.init || !UseScreenFBO())
|
||||
if (supportFBO == FBO_NONE || framebufferobject.init || !UseScreenFBO())
|
||||
return;
|
||||
|
||||
// Generate the framebuffer
|
||||
@@ -3269,15 +3283,15 @@ 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);
|
||||
Clamp2D(GL_TEXTURE_WRAP_T);
|
||||
pglBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Attach the framebuffer texture to the framebuffer
|
||||
pglFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, framebufferobject.tex, 0);
|
||||
pglBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// Generate the renderbuffer
|
||||
@@ -3319,7 +3333,7 @@ static void GL_Framebuffer_Generate(void)
|
||||
|
||||
// if this fails, dont retry it a gazillion times
|
||||
// this wouldnt recover
|
||||
supportFBO = false;
|
||||
supportFBO = FBO_NONE;
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||
return;
|
||||
}
|
||||
@@ -3332,7 +3346,7 @@ static void GL_Framebuffer_Generate(void)
|
||||
|
||||
void GL_Framebuffer_Unbind(void)
|
||||
{
|
||||
if (!supportFBO || !framebufferobject.init)
|
||||
if (supportFBO == FBO_NONE || !framebufferobject.init)
|
||||
return;
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||
@@ -3341,13 +3355,13 @@ void GL_Framebuffer_Unbind(void)
|
||||
|
||||
void GL_Framebuffer_Enable(void)
|
||||
{
|
||||
if (!supportFBO || !UseScreenFBO())
|
||||
if (supportFBO == FBO_NONE || !UseScreenFBO())
|
||||
return;
|
||||
|
||||
GL_Framebuffer_Generate();
|
||||
|
||||
// failed
|
||||
if (!supportFBO || !framebufferobject.init)
|
||||
if (supportFBO == FBO_NONE || !framebufferobject.init)
|
||||
return;
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, framebufferobject.fboobj);
|
||||
@@ -3356,7 +3370,7 @@ void GL_Framebuffer_Enable(void)
|
||||
|
||||
void GL_Framebuffer_Disable(void)
|
||||
{
|
||||
if (!supportFBO || !framebufferobject.init)
|
||||
if (supportFBO == FBO_NONE || !framebufferobject.init)
|
||||
return;
|
||||
|
||||
pglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
[Project]
|
||||
FileName=r_opengl.dev
|
||||
Name=r_opengl
|
||||
Ver=1
|
||||
IsCpp=1
|
||||
Type=3
|
||||
Compiler=-D_M_IX86=500_@@_-Wall_@@_-D_WINDOWS_@@_-DUSE_WGL_SWAP_@@_-Os_@@_-fomit-frame-pointer_@@_
|
||||
CppCompiler=
|
||||
Includes=
|
||||
Linker=--def ../r_mingw.def_@@_-lgdi32_@@_
|
||||
Libs=
|
||||
UnitCount=3
|
||||
Folders=
|
||||
ObjFiles=
|
||||
PrivateResource=
|
||||
ResourceIncludes=
|
||||
MakeIncludes=
|
||||
Icon=
|
||||
ExeOutput=C:\srb2demo2
|
||||
ObjectOutput=..\..\..\objs\Mingw\r_opengl
|
||||
OverrideOutput=1
|
||||
OverrideOutputName=r_opengl.dll
|
||||
HostApplication=
|
||||
CommandLine=
|
||||
IncludeVersionInfo=0
|
||||
SupportXPThemes=0
|
||||
CompilerSet=0
|
||||
CompilerSettings=00000000000000000111d0
|
||||
UseCustomMakefile=0
|
||||
CustomMakefile=
|
||||
|
||||
[Unit1]
|
||||
FileName=ogl_win.c
|
||||
Folder=
|
||||
Compile=1
|
||||
CompileCpp=0
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit2]
|
||||
FileName=r_opengl.c
|
||||
Folder=
|
||||
Compile=1
|
||||
CompileCpp=0
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit3]
|
||||
FileName=r_opengl.h
|
||||
Folder=
|
||||
Compile=1
|
||||
CompileCpp=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[VersionInfo]
|
||||
Major=0
|
||||
Minor=1
|
||||
Release=1
|
||||
Build=1
|
||||
LanguageID=1033
|
||||
CharsetID=1252
|
||||
CompanyName=
|
||||
FileVersion=0.1
|
||||
FileDescription=Developed using the Dev-C++ IDE
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=r_opengl.exe
|
||||
ProductName=r_opengl
|
||||
ProductVersion=0.1
|
||||
AutoIncBuildNr=0
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="r_opengl" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=r_opengl - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "r_opengl.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "r_opengl.mak" CFG="r_opengl - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "r_opengl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "r_opengl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "r_opengl - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "r_opengl___Win32_Release"
|
||||
# PROP BASE Intermediate_Dir "r_opengl___Win32_Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\..\..\bin\VC\Release\r_opengl"
|
||||
# PROP Intermediate_Dir "..\..\..\objs\VC\Release\r_opengl"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "R_OPENGL_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /G5 /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "USE_WGL_SWAP" /FR /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x80c /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 user32.lib gdi32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Release\r_opengl.pdb" /machine:I386 /out:"C:\srb2demo2\r_opengl.dll"
|
||||
# SUBTRACT LINK32 /pdb:none /debug
|
||||
|
||||
!ELSEIF "$(CFG)" == "r_opengl - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "..\..\..\objs\Debug"
|
||||
# PROP BASE Intermediate_Dir "..\..\..\objs\Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\..\..\bin\VC\Debug\r_opengl"
|
||||
# PROP Intermediate_Dir "..\..\..\objs\VC\Debug\r_opengl"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "R_OPENGL_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /G6 /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__WIN32__" /D "__MSC__" /D "USE_WGL_SWAP" /FR /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x80c /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 user32.lib gdi32.lib /nologo /dll /pdb:"..\..\..\bin\VC\Debug\r_opengl.pdb" /debug /machine:I386 /out:"C:\srb2demo2\r_opengld.dll" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "r_opengl - Win32 Release"
|
||||
# Name "r_opengl - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ogl_win.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\r_opengl.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\r_opengl.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
+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);
|
||||
|
||||
|
||||
+122
-59
@@ -117,6 +117,11 @@ static void HU_DrawRankings(void);
|
||||
|
||||
consvar_t cv_showspecstuff = {"showspecstuff", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// stuff from SRB2-Banpyura thx alot! :3
|
||||
consvar_t cv_chat_xoffset = {"chat_xoffset", "0", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_chat_yoffset = {"chat_yoffset", "0", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_chat_showlimit = {"chat_showlimit", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static char cechotext[1024];
|
||||
static tic_t cechotimer = 0;
|
||||
static tic_t cechoduration = 5*TICRATE;
|
||||
@@ -149,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
|
||||
@@ -183,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
|
||||
@@ -194,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)
|
||||
@@ -207,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)
|
||||
@@ -219,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);
|
||||
}
|
||||
|
||||
@@ -235,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);
|
||||
}
|
||||
|
||||
@@ -467,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:
|
||||
@@ -523,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.
|
||||
@@ -774,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)
|
||||
@@ -826,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;
|
||||
@@ -966,7 +968,7 @@ void HU_Ticker(void)
|
||||
size_t i = 0;
|
||||
|
||||
// handle spam while we're at it:
|
||||
for(; (i < MAXPLAYERS); i++)
|
||||
for (; (i < MAXPLAYERS); i++)
|
||||
{
|
||||
if (stop_spamming[i] > 0)
|
||||
stop_spamming[i]--;
|
||||
@@ -1370,7 +1372,12 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
|
||||
// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense.
|
||||
|
||||
INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh
|
||||
// let's use this as our coordinates, shh
|
||||
// :chao: guess this just works lol
|
||||
#define chatx ((INT16)(13 + (cv_chat_xoffset.value)))
|
||||
#define chaty ((INT16)(169 + (cv_chat_yoffset.value)))
|
||||
|
||||
#define CHATSNAP (V_SNAPTOBOTTOM|V_SNAPTOLEFT)
|
||||
|
||||
// chat stuff by VincyTM LOL XD!
|
||||
|
||||
@@ -1397,7 +1404,7 @@ static void HU_drawMiniChat(void)
|
||||
|
||||
for (; i > 0; i--)
|
||||
{
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
size_t j = 0;
|
||||
INT32 linescount = 0;
|
||||
emote_t *emote = NULL;
|
||||
@@ -1457,6 +1464,7 @@ static void HU_drawMiniChat(void)
|
||||
if (splitscreen)
|
||||
{
|
||||
y -= BASEVIDHEIGHT/2;
|
||||
|
||||
if (splitscreen > 1)
|
||||
y += 16;
|
||||
}
|
||||
@@ -1474,7 +1482,7 @@ static void HU_drawMiniChat(void)
|
||||
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
|
||||
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
|
||||
size_t j = 0;
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
@@ -1507,9 +1515,9 @@ static void HU_drawMiniChat(void)
|
||||
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
|
||||
{
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, EMOTEWIDTH, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, EMOTEWIDTH, charheight, 239|CHATSNAP);
|
||||
|
||||
M_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag);
|
||||
M_DrawEmote(x+dx+2, y+dy, emote, CHATSNAP|transflag);
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
|
||||
j += emotelen;
|
||||
@@ -1517,9 +1525,9 @@ static void HU_drawMiniChat(void)
|
||||
else
|
||||
{
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|CHATSNAP);
|
||||
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |CHATSNAP|transflag, !cv_allcaps.value, colormap);
|
||||
}
|
||||
|
||||
dx += charwidth;
|
||||
@@ -1580,13 +1588,13 @@ static void HU_drawChatLog(INT32 offset)
|
||||
chat_topy = y + chat_scroll*charheight;
|
||||
chat_bottomy = chat_topy + boxh*charheight;
|
||||
|
||||
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
|
||||
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|CHATSNAP); // log box
|
||||
|
||||
for (i = 0; i < chat_nummsg_log; i++) // iterate through our chatlog
|
||||
{
|
||||
INT32 clrflag = 0;
|
||||
INT32 j = 0;
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), CHATSNAP|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
@@ -1616,7 +1624,7 @@ static void HU_drawChatLog(INT32 offset)
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
{
|
||||
M_DrawEmote(x+dx+2, y+dy+1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
M_DrawEmote(x+dx+2, y+dy+1, emote, CHATSNAP);
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
}
|
||||
j += emotelen;
|
||||
@@ -1624,7 +1632,7 @@ static void HU_drawChatLog(INT32 offset)
|
||||
else
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap);
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |CHATSNAP, !cv_allcaps.value, colormap);
|
||||
else
|
||||
j++; // don't forget to increment this or we'll get stuck in the limbo.
|
||||
}
|
||||
@@ -1661,9 +1669,9 @@ static void HU_drawChatLog(INT32 offset)
|
||||
|
||||
// draw arrows to indicate that we can (or not) scroll.
|
||||
if (chat_scroll > 0)
|
||||
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1A', false); // up arrow
|
||||
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), CHATSNAP | highlight | '\x1A', false); // up arrow
|
||||
if (chat_scroll < chat_maxscroll)
|
||||
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1B', false); // down arrow
|
||||
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), CHATSNAP | highlight | '\x1B', false); // down arrow
|
||||
|
||||
justscrolleddown = false;
|
||||
justscrolledup = false;
|
||||
@@ -1681,6 +1689,7 @@ static void HU_DrawChat(void)
|
||||
INT32 boxw = cv_chatwidth.value;
|
||||
INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
|
||||
UINT32 i = 0, saylen = strlen(w_chat_buf); // You learn new things everyday!
|
||||
UINT32 charcount = 0;
|
||||
INT32 cflag = 0;
|
||||
INT32 pm_offset = 0; // for cases when you type emote while also doing /pm
|
||||
size_t select_start = 0, select_end = 0;
|
||||
@@ -1712,7 +1721,7 @@ static void HU_DrawChat(void)
|
||||
cflag = V_GRAYMAP; // set text in gray if chat is muted.
|
||||
}
|
||||
|
||||
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | CHATSNAP);
|
||||
|
||||
while (talk[i])
|
||||
{
|
||||
@@ -1720,7 +1729,7 @@ static void HU_DrawChat(void)
|
||||
++i;
|
||||
else
|
||||
{
|
||||
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag));
|
||||
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |CHATSNAP|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag));
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -1738,7 +1747,7 @@ static void HU_DrawChat(void)
|
||||
typelines = 1;
|
||||
|
||||
if ((w_chat.cursor == 0 || w_chat.length == 0) && hu_tick < 4)
|
||||
V_DrawChatCharacter(chatx+2+c, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
V_DrawChatCharacter(chatx+2+c, y+1, '_'|CHATSNAP|t, !cv_allcaps.value, NULL);
|
||||
|
||||
if (w_chat.select != w_chat.cursor)
|
||||
{
|
||||
@@ -1755,17 +1764,23 @@ static void HU_DrawChat(void)
|
||||
|
||||
if ((emote = M_VerifyEmote(w_chat_buf+i, &emotelen)))
|
||||
{
|
||||
M_DrawEmote(chatx + c + 2, y-1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
M_DrawEmote(chatx + c + 2, y-1, emote, CHATSNAP|t);
|
||||
c += EMOTEWIDTH - charwidth;
|
||||
i += emotelen-1;
|
||||
drawwidth = EMOTEWIDTH;
|
||||
if (cv_chat_showlimit.value)
|
||||
charcount += emotelen;
|
||||
}
|
||||
else if (w_chat_buf[i] >= HU_FONTSTART) //Hurdler: isn't it better like that?
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
||||
{
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | CHATSNAP | t, !cv_allcaps.value, NULL);
|
||||
if (cv_chat_showlimit.value)
|
||||
charcount++;
|
||||
}
|
||||
|
||||
// Draw selection
|
||||
if (i >= select_start && i < select_end)
|
||||
V_DrawFill(chatx + c + 2 - (drawwidth-charwidth), y-1, drawwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
V_DrawFill(chatx + c + 2 - (drawwidth-charwidth), y-1, drawwidth, charheight, 103|V_TRANSLUCENT|CHATSNAP|t);
|
||||
|
||||
++i;
|
||||
|
||||
@@ -1774,7 +1789,7 @@ static void HU_DrawChat(void)
|
||||
INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
|
||||
INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
|
||||
if (hu_tick < 4)
|
||||
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
V_DrawChatCharacter(cursorx, cursory+1, '_' |CHATSNAP|t, !cv_allcaps.value, NULL);
|
||||
|
||||
if (cursorx == chatx+1 && saylen == i-1) // a weirdo hack
|
||||
{
|
||||
@@ -1792,6 +1807,13 @@ static void HU_DrawChat(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (cv_chat_showlimit.value)
|
||||
{
|
||||
// Limit
|
||||
const INT32 clr = ((HU_MAXMSGLEN - charcount) > 64 ? V_TRANSLUCENT : (charcount == HU_MAXMSGLEN ? V_REDMAP : V_YELLOWMAP));
|
||||
V_DrawSmallString(chatx, y+7, CHATSNAP|clr, va("%d/%d", charcount, HU_MAXMSGLEN));
|
||||
}
|
||||
|
||||
// handle /pm list. It's messy, horrible and I don't care.
|
||||
if (strnicmp(w_chat_buf, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
|
||||
{
|
||||
@@ -1827,6 +1849,7 @@ static void HU_DrawChat(void)
|
||||
{
|
||||
char nodenum[3];
|
||||
UINT32 n;
|
||||
|
||||
// right, that's half important: (w_chat_buf[4] may be a space since /pm0 msg is perfectly acceptable!)
|
||||
if (!isdigit(w_chat_buf[3]) || !(isdigit(w_chat_buf[4]) || (w_chat_buf[4] == ' ') || (w_chat_buf[4] == 0)))
|
||||
break;
|
||||
@@ -1864,17 +1887,17 @@ static void HU_DrawChat(void)
|
||||
}
|
||||
|
||||
// fill it like the chat so the text doesn't become hard to read because of the hud.
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), (longest_name_length+4)*4, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), (longest_name_length+4)*4, 6, 239 | CHATSNAP);
|
||||
|
||||
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, player_names[i]));
|
||||
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), CHATSNAP|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, player_names[i]));
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0) // no results.
|
||||
{
|
||||
pm_offset = 48 + 2;
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
|
||||
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, "NO RESULT.");
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, p_dispy - (6*count), 48, 6, 239 | CHATSNAP); // fill it like the chat so the text doesn't become hard to read because of the hud.
|
||||
V_DrawSmallString(chatx + boxw + 4, p_dispy - (6*count), CHATSNAP|V_ALLOWLOWERCASE, "NO RESULT.");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1926,15 +1949,15 @@ static void HU_DrawChat(void)
|
||||
|
||||
while ((suggest = M_FindEmote(complete, complete_len, skip)) != NULL)
|
||||
{
|
||||
V_DrawFillConsoleMap(chatx + boxw + pm_offset + 2, suggesty - (7*skip), emote_suggest_boxw, 6, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawFillConsoleMap(chatx + boxw + pm_offset + 2, suggesty - (7*skip), emote_suggest_boxw, 6, CHATSNAP);
|
||||
|
||||
// Highlight currently suggested emote
|
||||
int hlflag = 0;
|
||||
if (skip == emote_autocomplete.skip && emote_autocomplete.complete[0])
|
||||
hlflag = V_YELLOWMAP;
|
||||
|
||||
V_DrawSmallString(chatx + boxw + pm_offset + 4 + EMOTEWIDTH, suggesty - (7*skip), hlflag|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va(":%s:", suggest->name));
|
||||
M_DrawEmote(chatx + boxw + pm_offset + 2, suggesty - skip*7, suggest, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawSmallString(chatx + boxw + pm_offset + 4 + EMOTEWIDTH, suggesty - (7*skip), hlflag|CHATSNAP|V_ALLOWLOWERCASE, va(":%s:", suggest->name));
|
||||
M_DrawEmote(chatx + boxw + pm_offset + 2, suggesty - skip*7, suggest, CHATSNAP);
|
||||
|
||||
++skip;
|
||||
}
|
||||
@@ -1948,6 +1971,7 @@ static void HU_DrawChat(void)
|
||||
static void HU_DrawChat_Old(void)
|
||||
{
|
||||
INT32 t = 0, c = 0, y = HU_INPUTY;
|
||||
UINT32 charcount = 0;
|
||||
size_t i = 0;
|
||||
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
|
||||
const char *talk = ntalk;
|
||||
@@ -1993,11 +2017,17 @@ static void HU_DrawChat_Old(void)
|
||||
{
|
||||
M_DrawScaledEmote((HU_INPUTX + c)<<FRACBITS, (y+con_scalefactor*2)<<FRACBITS, charwidth*FRACUNIT/EMOTEWIDTH, emote, V_NOSCALESTART | V_NOSCALEPATCH | t);
|
||||
i += emotelen-1;
|
||||
|
||||
if (cv_chat_showlimit.value)
|
||||
charcount += emotelen;
|
||||
}
|
||||
else if (w_chat_buf[i] >= HU_FONTSTART) //Hurdler: isn't it better like that?
|
||||
{
|
||||
//charwidth = hu_font[w_chat[i]-HU_FONTSTART]->width * con_scalefactor;
|
||||
V_DrawCharacter(HU_INPUTX + c, y, w_chat_buf[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
|
||||
|
||||
if (cv_chat_showlimit.value)
|
||||
charcount++;
|
||||
}
|
||||
|
||||
// Draw selection
|
||||
@@ -2010,7 +2040,7 @@ static void HU_DrawChat_Old(void)
|
||||
{
|
||||
INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down.
|
||||
INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight);
|
||||
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value);
|
||||
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' | cv_constextsize.value | V_NOSCALESTART |t, !cv_allcaps.value);
|
||||
}
|
||||
|
||||
c += charwidth;
|
||||
@@ -2020,6 +2050,24 @@ static void HU_DrawChat_Old(void)
|
||||
y += charheight;
|
||||
}
|
||||
}
|
||||
|
||||
// console chat users are FINALLY being fed!
|
||||
if (cv_chat_showlimit.value)
|
||||
{
|
||||
const char *lim = va(" (%i/%i)", charcount, HU_MAXMSGLEN);
|
||||
for (i = 0; lim[i]; i++)
|
||||
{
|
||||
V_DrawCharacter(HU_INPUTX + c, y, lim[i] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
|
||||
|
||||
c += charwidth;
|
||||
if (c >= vid.width) // text wrapping
|
||||
{
|
||||
c = 0;
|
||||
y += charheight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void HU_DrawCEcho(void)
|
||||
@@ -2208,12 +2256,13 @@ static void HU_DrawSongCreditsBox(void)
|
||||
y = -BOXCREDITHEIGHT*dup + (FixedMul(BOXCREDITHEIGHT*FRACUNIT, FixedDiv(t*FRACUNIT, TICRATE*FRACUNIT/2))*dup - interpoffset)/FRACUNIT;
|
||||
}
|
||||
|
||||
bgt = (NUMTRANSMAPS/2) + (cursongcredit.trans/2);
|
||||
bgt = (NUMTRANSMAPS/2) + (cursongcredit.trans/2) - 2; // arbitrary value, looks a bit better
|
||||
|
||||
if (bgt < NUMTRANSMAPS)
|
||||
{
|
||||
V_DrawFill(x, y, strwidth*dup, BOXCREDITHEIGHT*dup, 28|flags|(bgt<<V_ALPHASHIFT));
|
||||
V_DrawFill(x+dup, y+dup, (strwidth-2)*dup, (BOXCREDITHEIGHT-2)*dup, 30|flags|(bgt<<V_ALPHASHIFT));
|
||||
const UINT8 accent = colortranslations[K_GetHudColor()][7];
|
||||
V_DrawFill(x, y, strwidth*dup, BOXCREDITHEIGHT*dup, accent|flags|(bgt<<V_ALPHASHIFT));
|
||||
V_DrawFill(x+dup, y+dup, (strwidth-2)*dup, (BOXCREDITHEIGHT-2)*dup, accent|flags|(bgt<<V_ALPHASHIFT));
|
||||
}
|
||||
|
||||
if (cursongcredit.trans < NUMTRANSMAPS)
|
||||
@@ -2240,7 +2289,22 @@ void HU_DrawSongCredits(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void HU_ForceShowChat(void)
|
||||
{
|
||||
// only matters for non console chat
|
||||
// see m_menu for how forceshowchat is set
|
||||
if (!chat_on && forceshowchat)
|
||||
{
|
||||
// only print this if theres nothing in chat already
|
||||
if (chat_nummsg_log == 0)
|
||||
{
|
||||
HU_AddChatText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", false);
|
||||
}
|
||||
|
||||
HU_DrawChat();
|
||||
}
|
||||
}
|
||||
|
||||
// Heads up displays drawer, call each frame
|
||||
//
|
||||
void HU_Drawer(void)
|
||||
@@ -2248,6 +2312,8 @@ void HU_Drawer(void)
|
||||
if (cv_vhseffect.value && ((paused && !camera[R_GetViewNumber()].freecam) || (demo.playback && cv_playbackspeed.value > 1)))
|
||||
V_DrawVhsEffect(demo.rewinding);
|
||||
|
||||
HU_ForceShowChat();
|
||||
|
||||
// draw chat string plus cursor
|
||||
if (chat_on)
|
||||
{
|
||||
@@ -2327,8 +2393,7 @@ void HU_Drawer(void)
|
||||
// IN-LEVEL MULTIPLAYER RANKINGS
|
||||
//======================================================================
|
||||
|
||||
static int
|
||||
Ping_gfx_num (int lag)
|
||||
static int Ping_gfx_num(int lag)
|
||||
{
|
||||
if (lag < 2)
|
||||
return 0;
|
||||
@@ -2342,8 +2407,7 @@ Ping_gfx_num (int lag)
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int
|
||||
Ping_gfx_color (UINT32 lag)
|
||||
static int Ping_gfx_color(UINT32 lag)
|
||||
{
|
||||
if (lag < 2)
|
||||
return SKINCOLOR_JAWZ;
|
||||
@@ -2366,8 +2430,7 @@ Ping_gfx_color (UINT32 lag)
|
||||
return SKINCOLOR_WHITE; // to make the flashing work
|
||||
}
|
||||
|
||||
static const UINT8 *
|
||||
Ping_gfx_colormap (UINT32 lag, boolean gentleman)
|
||||
static const UINT8 *Ping_gfx_colormap(UINT32 lag, boolean gentleman)
|
||||
{
|
||||
const UINT8 *colormap = NULL;
|
||||
|
||||
@@ -2387,8 +2450,7 @@ Ping_gfx_colormap (UINT32 lag, boolean gentleman)
|
||||
return colormap;
|
||||
}
|
||||
|
||||
static UINT32
|
||||
Ping_conversion (UINT32 lag)
|
||||
static UINT32 Ping_conversion(UINT32 lag)
|
||||
{
|
||||
if (cv_pingmeasurement.value)
|
||||
{
|
||||
@@ -2765,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
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,10 @@ extern patch_t *tallminus;
|
||||
// set true whenever the tab rankings are being shown for any reason
|
||||
extern boolean hu_showscores;
|
||||
|
||||
extern consvar_t cv_chat_xoffset;
|
||||
extern consvar_t cv_chat_yoffset;
|
||||
extern consvar_t cv_chat_showlimit;
|
||||
|
||||
// init heads up data at game startup.
|
||||
void HU_Init(void);
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#ifndef __I_SYSTEM__
|
||||
#define __I_SYSTEM__
|
||||
|
||||
// page for Saturn issue reports
|
||||
#define SATURNISSUEPAGE "https://github.com/Indev450/SRB2Kart-Saturn/issues"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -209,6 +212,10 @@ static inline void I_HandleInterrupt(void)
|
||||
I_Quit();
|
||||
}
|
||||
|
||||
/** \brief Open A URL
|
||||
*/
|
||||
int I_OpenURL(const char *url);
|
||||
|
||||
/** \brief The I_GetDiskFreeSpace function
|
||||
|
||||
\param freespace a INT64 pointer to hold the free space amount
|
||||
@@ -230,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
|
||||
*/
|
||||
|
||||
+5
-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
|
||||
|
||||
@@ -1694,6 +1693,7 @@ boolean I_InitTcpNetwork(void)
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
if (M_CheckProtoParam("ip"))
|
||||
{
|
||||
COM_ImmedExecute(va("exec \"%s"PATHSEP"kartexec.cfg\" -noerror\n", srb2home));
|
||||
|
||||
@@ -452,7 +452,11 @@ void A_SpawnFreshCopy(void *actor);
|
||||
extern boolean actionsoverridden[NUMACTIONS];
|
||||
|
||||
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
|
||||
#ifdef PHOBOS_BUILD
|
||||
#define NUMMOBJFREESLOTS 4096 // should be sufficient
|
||||
#else
|
||||
#define NUMMOBJFREESLOTS 1024
|
||||
#endif
|
||||
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
|
||||
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
|
||||
|
||||
|
||||
+74
-31
@@ -98,6 +98,8 @@ consvar_t cv_showminimapfinished = {"showminimapfinished", "On", CV_SAVE, CV_OnO
|
||||
CV_PossibleValue_t minimapdot_cons_t[NUMMINIMAPDOTSTUFF];
|
||||
consvar_t cv_showminimapangle = {"showminimapangle", "Off", CV_SAVE, minimapdot_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_spinoutroll = {"spinoutroll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t posanim_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}};
|
||||
consvar_t cv_posanim = {"postitionanimation", "On", CV_SAVE, posanim_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_smallposnum = {"smallpositionnumber", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -231,6 +233,7 @@ void K_RegisterKartHudStuff(void)
|
||||
CV_RegisterVar(&cv_showminimapnames);
|
||||
CV_RegisterVar(&cv_showminimapfinished);
|
||||
CV_RegisterVar(&cv_showminimapangle);
|
||||
CV_RegisterVar(&cv_spinoutroll);
|
||||
|
||||
CV_RegisterVar(&cv_showlapemblem);
|
||||
|
||||
@@ -385,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);
|
||||
@@ -504,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);
|
||||
@@ -674,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;
|
||||
@@ -685,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);
|
||||
@@ -700,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);
|
||||
@@ -769,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;
|
||||
@@ -791,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;
|
||||
@@ -799,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;
|
||||
@@ -812,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;
|
||||
@@ -820,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);
|
||||
@@ -829,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);
|
||||
@@ -844,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;
|
||||
@@ -855,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);
|
||||
@@ -1143,7 +1149,7 @@ enum
|
||||
SPEEDO_PMETERSMOL,
|
||||
};
|
||||
|
||||
static SINT8 K_GetSpeedometerStyle(void)
|
||||
static UINT8 K_GetSpeedometerStyle(void)
|
||||
{
|
||||
if (cv_newspeedometer.value == 2 && xtra_speedo)
|
||||
return SPEEDO_EXTRA;
|
||||
@@ -1971,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));
|
||||
@@ -2291,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]);
|
||||
}
|
||||
@@ -2382,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]);
|
||||
}
|
||||
@@ -3578,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)
|
||||
@@ -3781,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);
|
||||
|
||||
@@ -3805,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);
|
||||
}
|
||||
@@ -3938,10 +3960,23 @@ static void K_drawBattleFullscreen(void)
|
||||
|
||||
INT32 x = BASEVIDWIDTH/2;
|
||||
INT32 y = (-64*FRACUNIT) + cardanim; // card animation goes from 0 to 164, 164 is the middle of the screen
|
||||
INT32 splitflags = V_SNAPTOTOP; // I don't feel like properly supporting non-green resolutions, so you can have a misuse of SNAPTO instead
|
||||
INT32 splitflags = splitscreen ? V_SNAPTOTOP : 0; // I don't feel like properly supporting non-green resolutions, so you can have a misuse of SNAPTO instead
|
||||
fixed_t scale = FRACUNIT;
|
||||
boolean drawcomebacktimer = true; // lazy hack because it's cleaner in the long run.
|
||||
|
||||
// Small hack, if we're not in splitscreen we will not use V_SNAPTOTOP, instead we will just slightly offset
|
||||
// y position so "attack or protect" doesn't slightly show before popping in
|
||||
// We will also reduce this when is closer to finishing so when its at the bottom, the "hack offset" is 0
|
||||
if (!splitscreen)
|
||||
{
|
||||
fixed_t offset = ((vid.height - vid.dup*BASEVIDHEIGHT)/vid.dup) * FRACUNIT/2;
|
||||
|
||||
// cardanim goes from 0 to 164, so when it is 164 offset will be multiplied by (1 - 164/164) = 0 :3
|
||||
offset = FixedMul(offset, FRACUNIT - FixedDiv(cardanim, 164*FRACUNIT));
|
||||
|
||||
y -= offset;
|
||||
}
|
||||
|
||||
if (!LUA_HudEnabled(hud_battlecomebacktimer))
|
||||
drawcomebacktimer = false;
|
||||
|
||||
@@ -4029,12 +4064,12 @@ static void K_drawBattleFullscreen(void)
|
||||
if (K_UseColorHud()) // Colourized hud
|
||||
{
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
|
||||
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutstickerclr, colormap);
|
||||
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, splitflags, kp_timeoutstickerclr, colormap);
|
||||
}
|
||||
else
|
||||
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutsticker, NULL);
|
||||
V_DrawFixedPatch(x<<FRACBITS, ty<<FRACBITS, scale, splitflags, kp_timeoutsticker, NULL);
|
||||
|
||||
V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
|
||||
V_DrawKartString(x-txoff, ty, splitflags, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4394,6 +4429,9 @@ static void K_drawChallengerScreen(void)
|
||||
|
||||
static void K_drawLapStartAnim(void)
|
||||
{
|
||||
if (!cv_showlapemblem.value)
|
||||
return;
|
||||
|
||||
// This is an EVEN MORE insanely complicated animation.
|
||||
const UINT8 progress = 80-stplyr->kartstuff[k_lapanimation];
|
||||
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
|
||||
@@ -4437,9 +4475,10 @@ static void K_drawLapStartAnim(void)
|
||||
V_DrawFixedPatch(leftx, y, FRACUNIT, vflags, kp_lapanim_lap[min(progress/2, 6)], NULL);
|
||||
|
||||
char *lapnum = va("%02d", stplyr->laps + 1);
|
||||
const size_t laplength = strlen(lapnum);
|
||||
|
||||
for (size_t i = 0; i < laplength; i++)
|
||||
const int laplength = (int)strlen(lapnum);
|
||||
|
||||
for (int i = 0; i < laplength; i++)
|
||||
{
|
||||
int digit = lapnum[i] - '0';
|
||||
int frame = min(2, progress/2 - 8 - (i*2));
|
||||
@@ -4569,7 +4608,11 @@ static void K_drawCheckpointDebugger(void)
|
||||
else
|
||||
V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Skip: %d)", stplyr->starpostnum, numstarposts, ((numstarposts/2) + stplyr->starpostnum)));
|
||||
|
||||
V_DrawString(8, 192, 0, va("Waypoint dist: Prev %d, Next %d", stplyr->kartstuff[k_prevcheck], stplyr->kartstuff[k_nextcheck]));
|
||||
// really gnarly hack
|
||||
const INT32 prevcheck = (stprevnextchecks[0] != INT32_MAX) ? stprevnextchecks[0]: stplyr->kartstuff[k_prevcheck];
|
||||
const INT32 nextcheck = (stprevnextchecks[1] != INT32_MAX) ? stprevnextchecks[1]: stplyr->kartstuff[k_nextcheck];
|
||||
|
||||
V_DrawString(8, 192, 0, va("Waypoint dist: Prev %d, Next %d", prevcheck, nextcheck));
|
||||
}
|
||||
|
||||
// determines if gametype info (laps/bumpers) should be hidden
|
||||
@@ -4821,7 +4864,7 @@ void K_drawKartHUD(void)
|
||||
{
|
||||
if (stplyr->exiting)
|
||||
K_drawKartFinish();
|
||||
else if (stplyr->kartstuff[k_lapanimation] && !splitscreen && cv_showlapemblem.value)
|
||||
else if (stplyr->kartstuff[k_lapanimation] && !splitscreen)
|
||||
K_drawLapStartAnim();
|
||||
}
|
||||
|
||||
|
||||
+341
-189
@@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
// extra colourisation stuff
|
||||
static CV_PossibleValue_t colorspeedlines_cons_t[] = {{0, "Off"}, {1, "Normal"}, {2, "+Driftcharge"}, {3, "Drift only"}, {0, NULL}};
|
||||
static CV_PossibleValue_t colorspeedlines_cons_t[] = {{0, "Off"}, {1, "On"}, {0, NULL}};
|
||||
consvar_t cv_coloredspeedlines = {"colorizedspeedlines", "Off", CV_SAVE, colorspeedlines_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_coloredsneakertrail = {"sneakertrailcolor", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -67,15 +67,15 @@ static CV_PossibleValue_t sloperoll_cons_t[] = {{0, "Off"}, {1, "Players"}, {2,
|
||||
consvar_t cv_sloperoll = {"sloperoll", "Off", CV_SAVE|CV_CALL, sloperoll_cons_t, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_sparkroll = {"sparkroll", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_sliptideroll = {"sliptideroll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_spinoutroll = {"spinoutroll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_stairjank = {"stairjank", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistort_menu_Onchange, 0, NULL, NULL, 0, 0, NULL};
|
||||
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};
|
||||
@@ -83,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
|
||||
@@ -1032,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,
|
||||
@@ -1820,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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2187,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)
|
||||
@@ -3216,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);
|
||||
@@ -3231,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;
|
||||
@@ -3325,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)
|
||||
@@ -3336,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;
|
||||
@@ -3363,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;
|
||||
@@ -3380,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;
|
||||
@@ -3397,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);
|
||||
}
|
||||
@@ -3505,12 +3527,22 @@ 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);
|
||||
}
|
||||
|
||||
static INT32 K_AltFlip(INT32 n, tic_t tics)
|
||||
{
|
||||
return leveltime % (2 * tics) < tics ? n : -(n);
|
||||
}
|
||||
|
||||
static INT32 K_StairJankFlip(INT32 value)
|
||||
{
|
||||
return K_AltFlip(value, 2);
|
||||
}
|
||||
|
||||
#define SLOPEROLL_DIV 3
|
||||
void K_RollMobjBySlopes(mobj_t* mo, pslope_t *slope)
|
||||
{
|
||||
@@ -3707,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);
|
||||
@@ -3733,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;
|
||||
@@ -3749,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)
|
||||
@@ -3760,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)));
|
||||
@@ -3773,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;
|
||||
@@ -3788,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3945,11 +4025,9 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
||||
|
||||
if (cv_bananthrowroll.value && (mapthing == MT_BANANA))
|
||||
{
|
||||
//mo->angle = FixedAngle(M_RandomRange(-180, 180) << FRACBITS);
|
||||
if (cv_bananthrowroll.value == 1 && K_CheckSlopeRollDist(mo))
|
||||
mo->sloperoll = (angle_t)FixedAngle(M_RandomRange(-180, 180) << FRACBITS); // im lazy but this makes sure the banan goes back to upright when it lands lmao
|
||||
else if (cv_bananthrowroll.value == 2)
|
||||
mo->rollangle = (angle_t)FixedAngle(M_RandomRange(-180, 180) << FRACBITS);
|
||||
const angle_t speen = (angle_t)FixedAngle(M_RandomRange(-180, 180) << FRACBITS);
|
||||
//mo->angle = speen;
|
||||
mo->rollangle = speen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4322,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)
|
||||
@@ -4385,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;
|
||||
@@ -4425,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!
|
||||
@@ -4493,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;
|
||||
@@ -4561,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)))
|
||||
{
|
||||
@@ -4629,7 +4721,7 @@ void K_DropRocketSneaker(player_t *player)
|
||||
while ((shoe = shoe->hnext) && !P_MobjWasRemoved(shoe))
|
||||
{
|
||||
if (shoe->type != MT_ROCKETSNEAKER)
|
||||
return; //woah, not a rocketsneaker, bail! safeguard in case this gets used when you're holding non-rocketsneakers
|
||||
return; // woah, not a rocketsneaker, bail! safeguard in case this gets used when you're holding non-rocketsneakers
|
||||
|
||||
shoe->flags2 &= ~MF2_DONTDRAW;
|
||||
shoe->flags &= ~MF_NOGRAVITY;
|
||||
@@ -4693,7 +4785,7 @@ void K_RepairOrbitChain(mobj_t *orbit)
|
||||
}
|
||||
|
||||
// Then recount to make sure item amount is correct
|
||||
if (orbit->target && orbit->target->player) // !P_MobjWasRemoved(orbit->target)
|
||||
if (!P_MobjWasRemovedCompat(orbit->target) && orbit->target->player)
|
||||
{
|
||||
INT32 num = 0;
|
||||
|
||||
@@ -4710,7 +4802,7 @@ void K_RepairOrbitChain(mobj_t *orbit)
|
||||
prev->movedir = num;
|
||||
}
|
||||
|
||||
if (orbit->target) // !P_MobjWasRemoved(orbit->target)
|
||||
if (!P_MobjWasRemovedCompat(orbit->target))
|
||||
orbit->target->player->kartstuff[k_itemamount] = num;
|
||||
}
|
||||
}
|
||||
@@ -4857,7 +4949,7 @@ static void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z
|
||||
// Move the hnext chain!
|
||||
static void K_MoveHeldObjects(player_t *player)
|
||||
{
|
||||
if (!player->mo)
|
||||
if (P_MobjWasRemovedCompat(player->mo))
|
||||
return;
|
||||
|
||||
if (!player->mo->hnext)
|
||||
@@ -4865,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;
|
||||
@@ -4882,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;
|
||||
@@ -4898,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
|
||||
|
||||
@@ -4945,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)
|
||||
@@ -4980,9 +5086,7 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
mobj_t *cur = player->mo->hnext;
|
||||
mobj_t *targ = player->mo;
|
||||
|
||||
const boolean ponground = P_IsObjectOnGround(player->mo);
|
||||
|
||||
if (ponground && player->speed > 0)
|
||||
if (player->speed > 0 && P_IsObjectOnGround(player->mo))
|
||||
player->kartstuff[k_bananadrag]++;
|
||||
|
||||
while (!P_MobjWasRemoved(cur))
|
||||
@@ -5031,7 +5135,8 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
|
||||
cur->angle = R_PointToAngle2(cur->x, cur->y, targx, targy);
|
||||
|
||||
/*if (P_IsObjectOnGround(player->mo) && player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE
|
||||
/*if (player->speed > 0 && P_IsObjectOnGround(player->mo)
|
||||
&& player->kartstuff[k_bananadrag] > TICRATE
|
||||
&& P_RandomChance(min(FRACUNIT/2, FixedDiv(player->speed, K_GetKartSpeed(player, false))/2)))
|
||||
{
|
||||
if (leveltime & 1)
|
||||
@@ -5040,8 +5145,9 @@ static void K_MoveHeldObjects(player_t *player)
|
||||
targz -= 8*(2*FRACUNIT)/7;
|
||||
}*/
|
||||
|
||||
if (cv_bananajitter.value && ponground
|
||||
&& player->speed > 0 && player->kartstuff[k_bananadrag] > TICRATE)
|
||||
// "jitter" dragged bananas around
|
||||
if (cv_bananajitter.value &&
|
||||
player->speed > 0 && P_IsObjectOnGround(player->mo) && player->kartstuff[k_bananadrag] > TICRATE)
|
||||
{
|
||||
const fixed_t halfpspeed = FixedDiv(player->speed, K_GetKartSpeed(player, false))/2;
|
||||
|
||||
@@ -5453,59 +5559,15 @@ boolean K_PlayerEffectsShouldBlend(player_t *player)
|
||||
return false;
|
||||
}
|
||||
|
||||
static UINT8 K_GetSpeedLineColor(player_t *player, boolean colorSpeed)
|
||||
FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player)
|
||||
{
|
||||
UINT8 speedcolor = SKINCOLOR_NONE;
|
||||
const UINT8 playercolor = player->mo->color;
|
||||
|
||||
if (colorSpeed)
|
||||
{
|
||||
if (cv_coloredspeedlines.value != 3)
|
||||
speedcolor = playercolor;
|
||||
|
||||
if (cv_coloredspeedlines.value >= 2 && player->kartstuff[k_driftboost])
|
||||
{
|
||||
if (player->kartstuff[k_driftboost] <= 20)
|
||||
speedcolor = SKINCOLOR_SAPPHIRE;
|
||||
else if (player->kartstuff[k_driftboost] <= 50)
|
||||
speedcolor = SKINCOLOR_RASPBERRY;
|
||||
else if (player->kartstuff[k_driftboost] <= 125)
|
||||
speedcolor = K_RainbowColor();
|
||||
|
||||
if (cv_coloredspeedlines.value == 2)
|
||||
speedcolor = (leveltime & 1) ? playercolor : speedcolor;
|
||||
}
|
||||
}
|
||||
|
||||
if (cv_coloredspeedlines.value != 3)
|
||||
{
|
||||
if (player->kartstuff[k_eggmanexplode])
|
||||
{
|
||||
// Make it red when you have the eggman speed boost
|
||||
speedcolor = SKINCOLOR_RED;
|
||||
}
|
||||
else if (player->kartstuff[k_invincibilitytimer])
|
||||
{
|
||||
speedcolor = playercolor;
|
||||
}
|
||||
}
|
||||
|
||||
return speedcolor;
|
||||
}
|
||||
|
||||
typedef INT32 (*randomFunc)(INT32 min, INT32 max);
|
||||
|
||||
FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, boolean synched)
|
||||
{
|
||||
const randomFunc randomfunc = synched ? P_RandomRange : M_RandomRange;
|
||||
|
||||
fixed_t rand_x;
|
||||
fixed_t rand_y;
|
||||
fixed_t rand_z;
|
||||
|
||||
rand_z = player->mo->z + (player->mo->height/2) + (randomfunc(-20,20) * player->mo->scale);
|
||||
rand_y = player->mo->y + (randomfunc(-36,36) * player->mo->scale);
|
||||
rand_x = player->mo->x + (randomfunc(-36,36) * player->mo->scale);
|
||||
rand_z = player->mo->z + (player->mo->height/2) + (P_RandomRange(-20, 20) * player->mo->scale);
|
||||
rand_y = player->mo->y + (P_RandomRange(-36, 36) * player->mo->scale);
|
||||
rand_x = player->mo->x + (P_RandomRange(-36, 36) * player->mo->scale);
|
||||
|
||||
mobj_t *fast = P_SpawnMobj(rand_x, rand_y, rand_z, MT_FASTLINE);
|
||||
|
||||
@@ -5513,7 +5575,7 @@ FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, bool
|
||||
fast->momx = 3*player->mo->momx/4;
|
||||
fast->momy = 3*player->mo->momy/4;
|
||||
fast->momz = 3*player->mo->momz/4;
|
||||
fast->islocal = !synched;
|
||||
//fast->islocal = false;
|
||||
P_SetTarget(&fast->target, player->mo); // easier lua access
|
||||
|
||||
K_MatchGenericExtraFlags(fast, player->mo);
|
||||
@@ -5524,8 +5586,11 @@ FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, bool
|
||||
|
||||
if (cv_coloredspeedlines.value)
|
||||
{
|
||||
fast->color = K_GetSpeedLineColor(player, colorSpeed);
|
||||
fast->colorized = true;
|
||||
if (colorSpeed || player->kartstuff[k_invincibilitytimer]) // let invul color them even when players go rather slow
|
||||
{
|
||||
fast->color = player->mo->color;
|
||||
fast->colorized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (colorSpeed && K_PlayerEffectsShouldBlend(player))
|
||||
@@ -5542,8 +5607,6 @@ FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, bool
|
||||
*/
|
||||
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
const boolean onground = P_IsObjectOnGround(player->mo);
|
||||
|
||||
K_UpdateOffroad(player);
|
||||
K_UpdateEngineSounds(player, cmd); // Thanks, VAda!
|
||||
|
||||
@@ -5556,11 +5619,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
// Speed lines
|
||||
if ((player->kartstuff[k_sneakertimer] || player->kartstuff[k_driftboost] || player->kartstuff[k_startboost]) && player->speed > 0)
|
||||
{
|
||||
K_SpawnNormalSpeedLines(player, true);
|
||||
}
|
||||
else if ((cv_coloredspeedlines.value == 1 || cv_coloredspeedlines.value == 2) && player->kartstuff[k_eggmanexplode]) // gotta love the speedlines calling synched rng :chaosleep:
|
||||
{
|
||||
K_SpawnNormalSpeedLines(player, false);
|
||||
K_SpawnNormalSpeedLines(player);
|
||||
}
|
||||
|
||||
if (player->playerstate == PST_DEAD || player->kartstuff[k_respawn] > 1) // Ensure these are set correctly here
|
||||
@@ -5660,7 +5719,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
|
||||
if (player->kartstuff[k_spinouttimer])
|
||||
{
|
||||
if ((onground || ((player->kartstuff[k_spinouttype]+1)/2 == 1)) // spinouttype 1 and 2 - explosion and spb
|
||||
if ((P_IsObjectOnGround(player->mo) || ((player->kartstuff[k_spinouttype]+1)/2 == 1)) // spinouttype 1 and 2 - explosion and spb
|
||||
&& (player->kartstuff[k_sneakertimer] == 0))
|
||||
{
|
||||
player->kartstuff[k_spinouttimer]--;
|
||||
@@ -5759,7 +5818,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
if (G_BattleGametype() && player->kartstuff[k_bumper] > 0)
|
||||
player->kartstuff[k_wanted]++;
|
||||
|
||||
if (onground)
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
player->kartstuff[k_waterskip] = 0;
|
||||
|
||||
if (player->kartstuff[k_instashield])
|
||||
@@ -5803,7 +5862,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||
if (player->kartstuff[k_comebacktimer])
|
||||
player->kartstuff[k_comebackmode] = 0;
|
||||
|
||||
if (onground && player->kartstuff[k_pogospring])
|
||||
if (player->kartstuff[k_pogospring] && P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (P_MobjFlip(player->mo)*player->mo->momz <= 0)
|
||||
player->kartstuff[k_pogospring] = 0;
|
||||
@@ -6182,6 +6241,64 @@ static void K_KartDrift(player_t *player, boolean onground)
|
||||
player->kartstuff[k_brakedrift] = 0;
|
||||
}
|
||||
|
||||
INT32 stprevnextchecks[2] = {INT32_MAX, INT32_MAX}; // there wont be any map this big, wont there?.....
|
||||
|
||||
// K_KartUpdatePosition has a bug where whatever player comes last in the players array
|
||||
// gets its distance calculations applied twice
|
||||
// since we cannot fix this due to compat concerns (kartstuff is exposed after all)
|
||||
// we gotta do this shit hack to atleast fix the debugcheckpoint display
|
||||
static void K_KartUpdatePositionDebugHack(player_t *player, player_t *otherplayer)
|
||||
{
|
||||
mobj_t *mo;
|
||||
fixed_t pmo;
|
||||
fixed_t ppcd, pncd;
|
||||
|
||||
// dont need this crap
|
||||
if (!cv_kartdebugcheckpoint.value)
|
||||
return;
|
||||
|
||||
// not checking against ourselves
|
||||
if (player != otherplayer)
|
||||
return;
|
||||
|
||||
// dont care if its not first displayplayer
|
||||
// since this is only used for the debug display
|
||||
if (player != &players[displayplayers[0]])
|
||||
return;
|
||||
|
||||
ppcd = pncd = 0;
|
||||
stprevnextchecks[0] = stprevnextchecks[1] = 0;
|
||||
|
||||
// This checks every thing on the map, and looks for MT_BOSS3WAYPOINT (the thing we're using for checkpoint wp's, for now)
|
||||
for (mo = waypointcap; mo != NULL; mo = mo->tracer)
|
||||
{
|
||||
const boolean isprevcheckpointp = mo->health == player->starpostnum;
|
||||
const boolean isnextcheckpointp = mo->health == (player->starpostnum + 1);
|
||||
|
||||
if ((isprevcheckpointp || isnextcheckpointp) && (!mo->movecount || mo->movecount == player->laps+1))
|
||||
{
|
||||
pmo = P_AproxDistance(P_AproxDistance( mo->x - player->mo->x,
|
||||
mo->y - player->mo->y),
|
||||
mo->z - player->mo->z) / FRACUNIT;
|
||||
|
||||
if (isprevcheckpointp)
|
||||
{
|
||||
stprevnextchecks[0] += pmo;
|
||||
ppcd++;
|
||||
}
|
||||
|
||||
if (isnextcheckpointp)
|
||||
{
|
||||
stprevnextchecks[1] += pmo;
|
||||
pncd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ppcd > 1) stprevnextchecks[0] /= ppcd;
|
||||
if (pncd > 1) stprevnextchecks[1] /= pncd;
|
||||
}
|
||||
|
||||
//
|
||||
// K_KartUpdatePosition
|
||||
//
|
||||
@@ -6193,6 +6310,9 @@ void K_KartUpdatePosition(player_t *player)
|
||||
fixed_t pmo, imo;
|
||||
mobj_t *mo;
|
||||
|
||||
// always reset this
|
||||
stprevnextchecks[0] = stprevnextchecks[1] = INT32_MAX;
|
||||
|
||||
if (player->spectator || !player->mo)
|
||||
return;
|
||||
|
||||
@@ -6205,11 +6325,12 @@ void K_KartUpdatePosition(player_t *player)
|
||||
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
if ((((players[i].starpostnum) + (numstarposts + 1) * players[i].laps) >
|
||||
((player->starpostnum) + (numstarposts + 1) * player->laps)))
|
||||
const INT32 iplayerlaps = (players[i].starpostnum + (numstarposts + 1) * players[i].laps);
|
||||
const INT32 pplayerlaps = (player->starpostnum + (numstarposts + 1) * player->laps);
|
||||
|
||||
if (iplayerlaps > pplayerlaps)
|
||||
position++;
|
||||
else if (((players[i].starpostnum) + (numstarposts+1)*players[i].laps) ==
|
||||
((player->starpostnum) + (numstarposts+1)*player->laps))
|
||||
else if (iplayerlaps == pplayerlaps)
|
||||
{
|
||||
ppcd = pncd = ipcd = incd = 0;
|
||||
|
||||
@@ -6292,6 +6413,9 @@ void K_KartUpdatePosition(player_t *player)
|
||||
if (players[i].starposttime < player->starposttime)
|
||||
position++;
|
||||
}
|
||||
|
||||
// stupid hack
|
||||
K_KartUpdatePositionDebugHack(player, &players[i]);
|
||||
}
|
||||
}
|
||||
else if (G_BattleGametype())
|
||||
@@ -6561,7 +6685,7 @@ static void K_PlayerItemThink(player_t *player, boolean onground, boolean oldatt
|
||||
{
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BANANA_SHIELD);
|
||||
|
||||
if (!mo)
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
{
|
||||
player->kartstuff[k_itemamount] = moloop;
|
||||
break;
|
||||
@@ -6622,7 +6746,7 @@ static void K_PlayerItemThink(player_t *player, boolean onground, boolean oldatt
|
||||
newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->kartstuff[k_itemamount]) * moloop) << FRACBITS) + ANGLE_90;
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ORBINAUT_SHIELD);
|
||||
|
||||
if (!mo)
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
{
|
||||
player->kartstuff[k_itemamount] = moloop;
|
||||
break;
|
||||
@@ -6665,7 +6789,7 @@ static void K_PlayerItemThink(player_t *player, boolean onground, boolean oldatt
|
||||
newangle = (player->mo->angle + ANGLE_157h) + FixedAngle(((360 / player->kartstuff[k_itemamount]) * moloop) << FRACBITS) + ANGLE_90;
|
||||
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_JAWZ_SHIELD);
|
||||
|
||||
if (!mo)
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
{
|
||||
player->kartstuff[k_itemamount] = moloop;
|
||||
break;
|
||||
@@ -7025,6 +7149,34 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||
|
||||
K_RollMobjBySlopes(player->mo, player->mo->standingslope);
|
||||
|
||||
// "Stair jank" visuals akin to RR
|
||||
if (cv_stairjank.value && player->stairjank > 0)
|
||||
{
|
||||
// only spawn em once
|
||||
if (player->stairjank > 8)
|
||||
{
|
||||
// 90 degrees to direction you're facing
|
||||
fixed_t dirx = -FINESINE(player->mo->angle>>ANGLETOFINESHIFT);
|
||||
fixed_t diry = FINECOSINE(player->mo->angle>>ANGLETOFINESHIFT);
|
||||
fixed_t offset = player->mo->radius;
|
||||
|
||||
dirx = K_AltFlip(-dirx, 4);
|
||||
diry = K_AltFlip(-diry, 4);
|
||||
|
||||
mobj_t * spark = P_SpawnMobj(player->mo->x + FixedMul(dirx, offset), player->mo->y + FixedMul(diry, offset), player->mo->z, MT_DRIFTDUST);
|
||||
spark->momx = FixedMul(dirx, FRACUNIT) + (6 + ((int)leveltime % 5))*(player->mo->momx)/10;
|
||||
spark->momy = FixedMul(diry, FRACUNIT) + (6 + ((int)leveltime % 5))*(player->mo->momy)/10;
|
||||
spark->momz = 5*FRACUNIT;
|
||||
spark->scale = mapobjectscale/5;
|
||||
spark->destscale = mapobjectscale/2;
|
||||
spark->islocal = true;
|
||||
spark->color = SKINCOLOR_WHITE;
|
||||
P_SetTarget(&spark->target, player->mo);
|
||||
}
|
||||
|
||||
player->mo->temprollangle += K_StairJankFlip(ANGLE_11hh / 2 / (17 / player->stairjank)); // TODO: make strength adjustable?
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
// Quick Turning
|
||||
|
||||
@@ -32,6 +32,8 @@ extern consvar_t cv_bananajitter;
|
||||
extern consvar_t cv_bananthrowroll;
|
||||
extern consvar_t cv_airsparks;
|
||||
|
||||
extern INT32 stprevnextchecks[2];
|
||||
|
||||
boolean K_IsPlayerLosing(player_t *player);
|
||||
boolean K_IsPlayerWanted(player_t *player);
|
||||
INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush);
|
||||
|
||||
+14
-26
@@ -3055,58 +3055,46 @@ static int lib_kSetHyuCountdown(lua_State *L)
|
||||
|
||||
static int lib_gSetPlayerGamepadIndicatorColor(lua_State *L)
|
||||
{
|
||||
INT32 player = -1;
|
||||
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||
INT32 pnum = -1;
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||
UINT8 color = (UINT8)luaL_checkinteger(L, 2); // skincolor
|
||||
|
||||
if (!plr)
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
if (color >= MAXTRANSLATIONS)
|
||||
return luaL_error(L, "color %d out of range (0 - %d).", color, MAXTRANSLATIONS-1);
|
||||
|
||||
for (int i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
|
||||
{
|
||||
if (plr - players == displayplayers[i])
|
||||
{
|
||||
player = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pnum = P_GetLocalPlayerNumForPlayer(player);
|
||||
|
||||
// Not a local player
|
||||
if (player == -1) return 0;
|
||||
if (pnum == -1) return 0;
|
||||
|
||||
// pls update with color 0 when youre done with changing led stuff so it can get player color again
|
||||
G_SetPlayerGamepadIndicatorColor(player, color);
|
||||
G_SetPlayerGamepadIndicatorColor(pnum, color);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_gPlayerDeviceRumble(lua_State *L)
|
||||
{
|
||||
INT32 player = -1;
|
||||
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||
INT32 pnum = -1;
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); // retrieve player
|
||||
UINT16 low_strength = (UINT16)luaL_checkinteger(L, 2); // low frequency rumble motor strenght
|
||||
UINT16 high_strength = (UINT16)luaL_checkinteger(L, 3); // high frequency rumble motor strenght
|
||||
UINT32 duration = (UINT32)luaL_optinteger(L, 4, 84); // duration of rumble in ms
|
||||
|
||||
if (!plr)
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
for (int i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
|
||||
{
|
||||
if (plr - players == displayplayers[i])
|
||||
{
|
||||
player = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (demo.playback) return 0;
|
||||
|
||||
pnum = P_GetLocalPlayerNumForPlayer(player);
|
||||
|
||||
// Not a local player
|
||||
if (player == -1) return 0;
|
||||
if (pnum == -1) return 0;
|
||||
|
||||
G_PlayerDeviceRumble(player, low_strength, high_strength, duration);
|
||||
G_PlayerDeviceRumble(pnum, low_strength, high_strength, duration);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+98
-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
|
||||
@@ -65,6 +66,8 @@ static stringhook_t stringHooks[STRING_HOOK(MAX)];
|
||||
|
||||
bool hook_important = true;
|
||||
|
||||
#define NONMOHOOK ((mobjtype_t)-1)
|
||||
|
||||
// This will be indexed by hook id, the value of which fetches the registry.
|
||||
static int * hookRefs;
|
||||
static int nextid;
|
||||
@@ -296,7 +299,7 @@ struct Hook_State {
|
||||
INT32 status; /* return status to calling function */
|
||||
void * userdata;
|
||||
int hook_type;
|
||||
mobjtype_t mobj_type; /* < NUMMOBJTYPES if mobj hook */
|
||||
mobjtype_t mobj_type; /* != NONMOHOOK if mobj hook */
|
||||
const char * string; /* used to fetch table, ran first if set */
|
||||
int top; /* index of last argument passed to hook */
|
||||
int id; /* id to fetch ref */
|
||||
@@ -364,7 +367,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_hook
|
||||
int hook_type
|
||||
){
|
||||
return init_hook_type(hook, default_status,
|
||||
hook_type, NUMMOBJTYPES, NULL,
|
||||
hook_type, NONMOHOOK, NULL,
|
||||
hookIds[hook_type].numHooks);
|
||||
}
|
||||
|
||||
@@ -391,7 +394,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_string_hook
|
||||
const char * string
|
||||
){
|
||||
if (init_hook_type(hook, default_status,
|
||||
hook_type, NUMMOBJTYPES, string,
|
||||
hook_type, NONMOHOOK, string,
|
||||
stringHooks[hook_type].ref))
|
||||
{
|
||||
lua_pushstring(gL, string);
|
||||
@@ -407,7 +410,7 @@ FUNCINLINE static ATTRINLINE boolean prepare_hud_hook
|
||||
int hook_type
|
||||
){
|
||||
return init_hook_type(hook, 0,
|
||||
hook_type, NUMMOBJTYPES, NULL,
|
||||
hook_type, NONMOHOOK, NULL,
|
||||
hudHookIds[hook_type].numHooks);
|
||||
}
|
||||
|
||||
@@ -443,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)
|
||||
{
|
||||
@@ -530,9 +576,45 @@ static int call_string_hooks(Hook_State *hook)
|
||||
|
||||
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 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 )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjCollide )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjMoveCollide)
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjFuse )
|
||||
|| 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!",
|
||||
mobjHookNames[hook->hook_type])
|
||||
);
|
||||
|
||||
// print which script triggered it, ty indev <3
|
||||
for (int k = 0; k < mobjHookIds[mobj_type][hook->hook_type].numHooks; ++k)
|
||||
{
|
||||
lua_getref(gL, hookRefs[mobjHookIds[mobj_type][hook->hook_type].ids[k].id]);
|
||||
|
||||
lua_Debug ar;
|
||||
lua_getinfo(gL, ">S", &ar);
|
||||
|
||||
CONS_Printf("%s:%d\n", ar.short_src, ar.linedefined);
|
||||
}
|
||||
}
|
||||
|
||||
return numCalls;
|
||||
}
|
||||
|
||||
/*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
|
||||
(
|
||||
Hook_State * hook,
|
||||
@@ -547,11 +629,13 @@ static int call_hooks
|
||||
{
|
||||
calls += call_string_hooks(hook);
|
||||
}
|
||||
else if (hook->mobj_type < NUMMOBJTYPES)
|
||||
//else if (hook->mobj_type > 0)
|
||||
else if (hook->mobj_type != NONMOHOOK)
|
||||
{
|
||||
/* call generic mobj hooks first */
|
||||
calls += call_mobj_type_hooks(hook, MT_NULL);
|
||||
calls += call_mobj_type_hooks(hook, hook->mobj_type);
|
||||
if (hook->mobj_type < NUMMOBJTYPES)
|
||||
calls += call_mobj_type_hooks(hook, hook->mobj_type);
|
||||
ps_lua_mobjhooks.value.i += calls;
|
||||
}
|
||||
else
|
||||
@@ -718,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))
|
||||
{
|
||||
@@ -814,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)
|
||||
@@ -903,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);
|
||||
@@ -976,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);
|
||||
|
||||
|
||||
+13
-8
@@ -644,20 +644,22 @@ static int libd_drawScaled(lua_State *L)
|
||||
// KART: draw patch on minimap from x, y coordinates on the map
|
||||
static int libd_drawOnMinimap(lua_State *L)
|
||||
{
|
||||
fixed_t x, y, scale; // coordinates of the object
|
||||
patch_t *patch; // patch we want to draw
|
||||
UINT8 *colormap = NULL; // do we want to colormap this patch?
|
||||
boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
|
||||
fixed_t x, y, scale; // coordinates of the object
|
||||
patch_t *patch; // patch we want to draw
|
||||
UINT8 *colormap = NULL; // do we want to colormap this patch?
|
||||
boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
|
||||
huddrawlist_h list;
|
||||
patch_t *AutomapPic = NULL;
|
||||
drawinfo_t info;
|
||||
|
||||
// variables used to replicate k_kart's mmap drawer:
|
||||
patch_t *AutomapPic;
|
||||
|
||||
// variables used for actually drawing the icon:
|
||||
INT32 splitflags, minimaptrans;
|
||||
fixed_t amnumxpos, amnumypos;
|
||||
fixed_t amxpos, amypos;
|
||||
INT32 mm_x, mm_y;
|
||||
fixed_t patchw = 0, patchh = 0;
|
||||
fixed_t patchw, patchh;
|
||||
|
||||
HUDONLY // only run this function in hud hooks
|
||||
|
||||
@@ -722,8 +724,11 @@ static int libd_drawOnMinimap(lua_State *L)
|
||||
|
||||
mm_y -= AutomapPic->topoffset;
|
||||
|
||||
// patch is supposedly already centered, don't butt in.
|
||||
if (!centered)
|
||||
if (centered)
|
||||
{
|
||||
patchw = patchh = 0; // patch is supposedly already centered, don't butt in.
|
||||
}
|
||||
else
|
||||
{
|
||||
// scale patch coords
|
||||
patchw = (patch->width * scale / 2);
|
||||
|
||||
+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*/
|
||||
+33
-16
@@ -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)
|
||||
@@ -713,9 +710,12 @@ static UINT8 GetUserdataArchType(int index)
|
||||
|
||||
static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
|
||||
{
|
||||
int type = lua_type(gL, myindex);
|
||||
|
||||
if (myindex < 0)
|
||||
myindex = lua_gettop(gL)+1+myindex;
|
||||
switch (lua_type(gL, myindex))
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LUA_TNONE:
|
||||
case LUA_TNIL:
|
||||
@@ -725,8 +725,12 @@ static UINT8 ArchiveValue(UINT8 **p, int TABLESINDEX, int myindex)
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
case LUA_TTHREAD:
|
||||
case LUA_TFUNCTION:
|
||||
{
|
||||
const char *typestr = (type == LUA_TLIGHTUSERDATA ? "light userdata" : (type == LUA_TTHREAD ? "thread" : (type == LUA_TFUNCTION ? "function" : "??")));
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Archived an invalid value! (%s)\n"), typestr);
|
||||
WRITEUINT8(*p, ARCH_NULL);
|
||||
return 2;
|
||||
}
|
||||
case LUA_TBOOLEAN:
|
||||
WRITEUINT8(*p, ARCH_BOOLEAN);
|
||||
WRITEUINT8(*p, lua_toboolean(gL, myindex));
|
||||
@@ -1453,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++)
|
||||
{
|
||||
|
||||
+3
-3
@@ -766,7 +766,7 @@ boolean OP_FreezeObjectplace(void)
|
||||
if (!objectplacing)
|
||||
return false;
|
||||
|
||||
if ((maptol & TOL_NIGHTS) && (players[consoleplayer].pflags & PF_NIGHTSMODE))
|
||||
if (nightsmode && nightsplayer(&players[consoleplayer]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -1049,7 +1049,7 @@ void Command_ObjectPlace_f(void)
|
||||
{
|
||||
objectplacing = true;
|
||||
|
||||
if ((players[0].pflags & PF_NIGHTSMODE))
|
||||
if (nightsplayer(&players[0]))
|
||||
return;
|
||||
|
||||
if (!COM_CheckParm("-silent"))
|
||||
@@ -1120,7 +1120,7 @@ void Command_ObjectPlace_f(void)
|
||||
|
||||
// Don't touch the NiGHTS Objectplace stuff.
|
||||
// ... or if the mo mysteriously vanished.
|
||||
if (!players[0].mo || (players[0].pflags & PF_NIGHTSMODE))
|
||||
if (!players[0].mo || nightsplayer(&players[0]))
|
||||
return;
|
||||
|
||||
// If still in dummy state, get out of it.
|
||||
|
||||
+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;
|
||||
|
||||
+306
-190
File diff suppressed because it is too large.
Load diff
+3
-3
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#include "mserv.h"
|
||||
#include "r_things.h" // for SKINNAMESIZE
|
||||
|
||||
extern boolean forceshowhud;
|
||||
extern boolean forceshowhud, forceshowchat;
|
||||
|
||||
//
|
||||
// MENUS
|
||||
@@ -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;
|
||||
|
||||
+187
-92
@@ -36,6 +36,7 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef;
|
||||
menu_t OP_ControlsDef, OP_AllControlsDef;
|
||||
menu_t OP_MouseOptionsDef;
|
||||
menu_t OP_Joystick1Def, OP_Joystick2Def, OP_Joystick3Def, OP_Joystick4Def;
|
||||
menu_t OP_Joystick1RumbleDef, OP_Joystick2RumbleDef, OP_Joystick3RumbleDef, OP_Joystick4RumbleDef;
|
||||
|
||||
// Custom cvar menu
|
||||
menu_t OP_CustomCvarMenuDef;
|
||||
@@ -208,7 +209,7 @@ typedef enum
|
||||
static menuitem_t MPauseMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CALL, NULL, "Addons...", M_Addons, 8},
|
||||
{IT_STRING | IT_CALL, NULL, "Add local skins...", M_LocalSkins, 16},
|
||||
{IT_STRING | IT_CALL, NULL, "Local Add-ons...", M_LocalAddons, 8},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 24},
|
||||
{IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 32},
|
||||
|
||||
@@ -238,7 +239,7 @@ static menuitem_t MPauseMenu[] =
|
||||
typedef enum
|
||||
{
|
||||
mpause_addons = 0,
|
||||
mpause_addlocalskins,
|
||||
mpause_localaddons,
|
||||
mpause_scramble,
|
||||
mpause_switchmap,
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
@@ -446,25 +447,25 @@ enum
|
||||
|
||||
static menuitem_t SP_ReplayMenu[] =
|
||||
{
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack, 90},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", M_ReplayTimeAttack, 98},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Time", M_ReplayTimeAttack, 90},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Best Lap", M_ReplayTimeAttack, 98},
|
||||
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack, 106},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack, 114},
|
||||
{IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay,122},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Last", M_ReplayTimeAttack, 106},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Replay Guest", M_ReplayTimeAttack, 114},
|
||||
{IT_WHITESTRING|IT_KEYHANDLER, NULL, "Replay Staff",M_HandleStaffReplay, 122},
|
||||
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
|
||||
};
|
||||
|
||||
static menuitem_t SP_GuestReplayMenu[] =
|
||||
{
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay, 94},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", M_SetGuestReplay,102},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay,110},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Time as Guest", M_SetGuestReplay, 94},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Best Lap as Guest", M_SetGuestReplay, 102},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Save Last as Guest", M_SetGuestReplay, 110},
|
||||
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay,120},
|
||||
{IT_WHITESTRING|IT_CALL, NULL, "Delete Guest Replay", M_SetGuestReplay, 120},
|
||||
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SP_TimeAttackDef, 130}
|
||||
};
|
||||
|
||||
static menuitem_t SP_GhostMenu[] =
|
||||
@@ -555,10 +556,10 @@ static menuitem_t MP_PlayerSetupMenu[] =
|
||||
|
||||
static menuitem_t MP_ConnectMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CVAR, NULL, "Sort By", &cv_serversort, 0},
|
||||
{IT_STRING | IT_KEYHANDLER, NULL, "Page", M_HandleServerPage, 8},
|
||||
{IT_STRING | IT_CALL, NULL, "Refresh", M_Refresh, 16},
|
||||
{IT_STRING | IT_KEYHANDLER, NULL, "", M_HandleServerSearch,25},
|
||||
{IT_STRING | IT_CVAR, NULL, "Sort By", &cv_serversort, 0},
|
||||
{IT_STRING | IT_KEYHANDLER, NULL, "Page", M_HandleServerPage, 8},
|
||||
{IT_STRING | IT_CALL, NULL, "Refresh", M_Refresh, 16},
|
||||
{IT_STRING | IT_KEYHANDLER, NULL, "", M_HandleServerSearch, 25},
|
||||
|
||||
{IT_STRING | IT_SPACE, NULL, "", M_Connect, 48},
|
||||
{IT_STRING | IT_SPACE, NULL, "", M_Connect, 60},
|
||||
@@ -725,29 +726,36 @@ static const char* OP_AllControlsTooltips[sizeof(OP_AllControlsMenu)/sizeof(OP_A
|
||||
// The rest is null, for now
|
||||
};
|
||||
|
||||
#define OP_JOYMENU(pnum) \
|
||||
{IT_HEADER, NULL, "Gameplay Controls", NULL, 7}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis[pnum] , 15}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis[pnum] , 20}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis[pnum] , 25}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis[pnum] , 30}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis[pnum] , 35}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis[pnum] , 40}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis[pnum] , 45}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 1" , &cv_custom1axis[pnum] , 50}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 2" , &cv_custom2axis[pnum] , 55}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 3" , &cv_custom3axis[pnum] , 60}, \
|
||||
{IT_HEADER, NULL, "Camera Controls", NULL, 67}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis[pnum] , 75}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_camturnaxis[pnum] , 80}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Strafe Left/Right" , &cv_camstrafeaxis[pnum] , 85}, \
|
||||
{IT_HEADER, NULL, "Deadzones", NULL, 92}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone[pnum] , 100}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone[pnum] , 105}, \
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 112}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Controller Rumble" , &cv_rumble[pnum] , 120}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Controller Rumble Strength" , &cv_rumblestrength[pnum] , 125}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Set LED to Player color" , &cv_gamepadled[pnum] , 130},
|
||||
// i really do not feel like messing with setup routines
|
||||
// and macro preprocessor cannot eval maths for string shit like this :chaosleep:
|
||||
#define RUMBDEF_0 OP_Joystick1RumbleDef
|
||||
#define RUMBDEF_1 OP_Joystick2RumbleDef
|
||||
#define RUMBDEF_2 OP_Joystick3RumbleDef
|
||||
#define RUMBDEF_3 OP_Joystick4RumbleDef
|
||||
#define RUMBDEF(x) RUMBDEF_##x
|
||||
|
||||
#define OP_JOYMENU(pnum) \
|
||||
{IT_HEADER, NULL, "Gameplay Controls", NULL, 7}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Aim Forward/Back" , &cv_aimaxis[pnum] , 15}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_turnaxis[pnum] , 20}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Accelerate" , &cv_moveaxis[pnum] , 25}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Brake" , &cv_brakeaxis[pnum] , 30}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Drift" , &cv_driftaxis[pnum] , 35}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Use Item" , &cv_fireaxis[pnum] , 40}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Look Backward" , &cv_lookbackaxis[pnum] , 45}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 1" , &cv_custom1axis[pnum] , 50}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 2" , &cv_custom2axis[pnum] , 55}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Custom Button 3" , &cv_custom3axis[pnum] , 60}, \
|
||||
{IT_HEADER, NULL, "Camera Controls", NULL, 67}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Look Up/Down" , &cv_lookaxis[pnum] , 75}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Turn Left/Right" , &cv_camturnaxis[pnum] , 80}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Strafe Left/Right" , &cv_camstrafeaxis[pnum] , 85}, \
|
||||
{IT_HEADER, NULL, "Deadzones", NULL, 92}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "X deadzone" , &cv_xdeadzone[pnum] , 100}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Y deadzone" , &cv_ydeadzone[pnum] , 105}, \
|
||||
{IT_HEADER, NULL, "Miscellaneous", NULL, 112}, \
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Rumble Options..." , &RUMBDEF(pnum) , 120}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Set LED to Player color" , &cv_gamepadled[pnum] , 125},
|
||||
|
||||
static menuitem_t OP_Joystick1Menu[] =
|
||||
{
|
||||
@@ -773,6 +781,46 @@ static menuitem_t OP_Joystick4Menu[] =
|
||||
OP_JOYMENU(3)
|
||||
};
|
||||
|
||||
#undef RUMBDEF
|
||||
#undef RUMBDEF_0
|
||||
#undef RUMBDEF_1
|
||||
#undef RUMBDEF_2
|
||||
#undef RUMBDEF_3
|
||||
|
||||
// FIXME: stair jank rumble should be greyed out if its disabled, but menus suck butt!
|
||||
#define OP_JOYRUMBLEMENU(pnum) \
|
||||
{IT_HEADER, NULL, "Global", NULL, 7}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Controller Rumble" , &cv_rumble[pnum] , 15}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Controller Rumble Strength" , &cv_rumble_strength[pnum] , 20}, \
|
||||
{IT_HEADER, NULL, "Rumble Types", NULL, 27}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Spinout" , &cv_rumble_spinout[pnum] , 35}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Sneaker Boost" , &cv_rumble_sneakerboost[pnum] , 40}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Offroad" , &cv_rumble_offroad[pnum] , 45}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Banana Dragging" , &cv_rumble_bananadrag[pnum] , 50}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Stair Jank" , &cv_rumble_stairjank[pnum] , 55}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Brake Drift" , &cv_rumble_brakedrift[pnum] , 60}, \
|
||||
{IT_STRING | IT_CVAR, NULL, "Drift Charge" , &cv_rumble_driftcharge[pnum] , 65}, \
|
||||
|
||||
static menuitem_t OP_Joystick1RumbleMenu[] =
|
||||
{
|
||||
OP_JOYRUMBLEMENU(0)
|
||||
};
|
||||
|
||||
static menuitem_t OP_Joystick2RumbleMenu[] =
|
||||
{
|
||||
OP_JOYRUMBLEMENU(1)
|
||||
};
|
||||
|
||||
static menuitem_t OP_Joystick3RumbleMenu[] =
|
||||
{
|
||||
OP_JOYRUMBLEMENU(2)
|
||||
};
|
||||
|
||||
static menuitem_t OP_Joystick4RumbleMenu[] =
|
||||
{
|
||||
OP_JOYRUMBLEMENU(3)
|
||||
};
|
||||
|
||||
static menuitem_t OP_JoystickSetMenu[] =
|
||||
{
|
||||
{IT_CALL | IT_NOTHING, "None", NULL, M_AssignJoystick, LINEHEIGHT+5},
|
||||
@@ -789,10 +837,9 @@ static menuitem_t OP_JoystickSetMenu[] =
|
||||
static menuitem_t OP_MouseOptionsMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CVAR, NULL, "Use Mouse", &cv_usemouse, 10},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Mouse Turning", &cv_mouseturn, 20},
|
||||
{IT_STRING | IT_CVAR, NULL, "Invert Mouse", &cv_invertmouse, 30},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse X Speed", &cv_mousexsens, 40},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse X Speed", &cv_mousexsens, 40},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Mouse Y Speed", &cv_mouseysens, 50},
|
||||
};
|
||||
|
||||
@@ -861,7 +908,6 @@ static const char* OP_VideoTooltips[] =
|
||||
"Advanced graphical options.",
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
op_video_res = 0,
|
||||
@@ -945,24 +991,25 @@ static menuitem_t OP_ExpOptionsMenu[] =
|
||||
//{IT_STRING | IT_CVAR, NULL, "Randomized Directional Light", &cv_randomdirlight, 45}, // should this ever come back
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Skydome", &cv_skydome, 45},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Precache Level Textures", &cv_precachetextures, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Precache Level Textures", &cv_precachetextures, 55},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 60},
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 65},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Frameskip", &cv_frameskip, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Frameskip", &cv_frameskip, 75},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Votescreen Scaling", &cv_votebgscaling, 80},
|
||||
{IT_STRING | IT_CVAR, NULL, "Votescreen Scaling", &cv_votebgscaling, 85},
|
||||
|
||||
#ifdef HWRENDER
|
||||
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 90},
|
||||
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 95},
|
||||
#ifdef USE_FBO_OGL
|
||||
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 95},
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 105},
|
||||
{IT_DISABLED, NULL, "", NULL, 115}, // dummy text
|
||||
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 110},
|
||||
{IT_DISABLED, NULL, "", NULL, 120}, // dummy text
|
||||
#else
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 100},
|
||||
{IT_DISABLED, NULL, "", NULL, 110}, // dummy text
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 110},
|
||||
{IT_DISABLED, NULL, "", NULL, 120}, // dummy text
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
@@ -975,12 +1022,13 @@ static const char* OP_ExpTooltips[] =
|
||||
"Sets minimum sector brightness, useful for dark areas.",
|
||||
//"Should the directional lightning be randomized each map?\nTakes effect on next map load.",
|
||||
"Toggle being able to see the sky.",
|
||||
"Toggle skydome.", // idk man someone give a better description of this
|
||||
"Preload all level textures on level load.\nMassively reduces texture related stuttering during gameplay\nat the cost of longer level loading times.\nDisable this if you experience timeouts during level switches.",
|
||||
"Change the FPS counter sampling method\nInaccurate updates slower\nand might miss sudden framerate changes and drops,\nproviding a more averaged result.\nAccurate updates faster, but might be less readable.", // how to ingles??
|
||||
"Skips rendering frames if game logic takes too long\npreventing gameplay issues during performance drops.", // idk im shit as describing things
|
||||
"Different methods of scaling the votescreen backgrounds.",
|
||||
#ifdef HWRENDER
|
||||
"Disabling Screen Textures may result in a performance boost\nbut will break certain effects.\nScreen textures are required at resolutions lower than your desktop resolution!"
|
||||
"Disabling Screen Textures may result in a performance boost\nbut will break certain effects.\nScreen textures are required at resolutions lower than your desktop resolution!",
|
||||
#ifdef USE_FBO_OGL
|
||||
"Allows the game to downsample from a higher resolution\nthan your display in OpenGL renderer mode.\nRequires a GPU with atleast OpenGL 2.1 support.",
|
||||
#endif
|
||||
@@ -996,6 +1044,7 @@ enum
|
||||
op_exp_secbright,
|
||||
//op_exp_dirlight,
|
||||
op_exp_skybox,
|
||||
op_exp_skydome,
|
||||
op_exp_texcache,
|
||||
op_exp_accuratefps,
|
||||
op_exp_frameskip,
|
||||
@@ -1009,7 +1058,6 @@ enum
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef HWRENDER
|
||||
static menuitem_t OP_OpenGLOptionsMenu[] =
|
||||
{
|
||||
@@ -1066,7 +1114,6 @@ enum
|
||||
op_gl_shearing,
|
||||
op_gl_renderdist,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static menuitem_t OP_SoundOptionsMenu[] =
|
||||
@@ -1077,8 +1124,7 @@ static menuitem_t OP_SoundOptionsMenu[] =
|
||||
{IT_STRING|IT_CVAR|IT_CV_NOPRINT, NULL, "Music", &cv_gamedigimusic, 30},
|
||||
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Music Volume", &cv_digmusicvolume, 38},
|
||||
|
||||
//#ifndef NO_MIDI
|
||||
#if 0
|
||||
#if 0 //#ifndef NO_MIDI
|
||||
{IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "MIDI Volume", &cv_midimusicvolume, 46},
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 60},
|
||||
@@ -1113,8 +1159,7 @@ static const char* OP_SoundTooltips[] =
|
||||
"Volume of Sound effects.",
|
||||
"Turn Music on or off.",
|
||||
"Volume of Music.",
|
||||
//#ifndef NO_MIDI
|
||||
#if 0
|
||||
#if 0 //#ifndef NO_MIDI
|
||||
"Volume of Midi Music.",
|
||||
#endif
|
||||
"Reverse left and right channels of audio.",
|
||||
@@ -1174,7 +1219,7 @@ static const char* OP_SoundAdvancedTooltips[] =
|
||||
"Should the Grow music be on or off?",
|
||||
"Should the Invulnerability music be on or off?",
|
||||
"Should music be kept when restarting the map?",
|
||||
"Should the Intro fanfare be skipped\nand map music be played on map start?",
|
||||
"Should the Intro fanfare be skipped\nand map music be played on map start?\nNote that this WILL skip sounds played by the map before round start as well!",
|
||||
"Controls Sound effects caching.\nKeep will retain previously played sound effects in cache." // man idk how to describe this in a non awful way lmao
|
||||
"\nOn will preload all sound effects.\nEliminates sound-related lag and stutters but increases memory usage.",
|
||||
"Size of the Audio Buffer\nreducing it will result in less sound latency\nbut may cause issues such as crackling or distorted Sound.",
|
||||
@@ -1408,44 +1453,70 @@ static const char* OP_PlayerCamOptionsTooltips[] =
|
||||
static menuitem_t OP_ChatOptionsMenu[] =
|
||||
{
|
||||
// will ANYONE who doesn't know how to use the console want to touch this one?
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 5}, // nonetheless...
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 5}, // nonetheless...
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Chat Box Width", &cv_chatwidth, 20},
|
||||
NULL, "Chat Box Width", &cv_chatwidth, 10},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Chat Box Height", &cv_chatheight, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Center Text in Chat", &cv_chatcentertext, 40},
|
||||
NULL, "Chat Box Height", &cv_chatheight, 15},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Horizontal Offset", &cv_chat_xoffset, 20},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Vertical Offset", &cv_chat_yoffset, 25},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 55},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 65},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 85},
|
||||
{IT_STRING | IT_CVAR, NULL, "Center Text in Chat", &cv_chatcentertext, 35},
|
||||
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 45},
|
||||
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 55},
|
||||
{IT_STRING | IT_CVAR, NULL, "Display Character Limit", &cv_chat_showlimit, 60},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 105}, // shows ping above the framerate if we want to.
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 115},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 125},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 135},
|
||||
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 70}, // shows ping above the framerate if we want to.
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 80},
|
||||
{IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 85},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 145},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 90},
|
||||
};
|
||||
|
||||
static const char* OP_ChatOptionsTooltips[] =
|
||||
{
|
||||
"Chat mode used for in-game chat.",
|
||||
"Width of chat box.",
|
||||
"Height of chat box.",
|
||||
"Width of the chat box.",
|
||||
"Height of the chat box.",
|
||||
"Horizontal Offset of the chat box.",
|
||||
"Vertical Offset of the chat box.",
|
||||
"Center text in the chat message pop ups.",
|
||||
"Chatbox background.",
|
||||
"Background for the chat message pop ups.",
|
||||
"Fadeout time for new chat message.",
|
||||
"Spam protection for in-game chat.",
|
||||
"Maxiumum amount of chat messages to look back at.",
|
||||
"Show how many characters you have left to type in the chat.",
|
||||
"Show player ping.",
|
||||
"Choose the looks of the ping display.", // this is ass idk english lmao
|
||||
"Choose the style of the ping display.",
|
||||
"Measurement used for ping.",
|
||||
"Visibility of ping icon.",
|
||||
"Should Player IP addresses be printed when using\nthe nodes or listplayers command?",
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
op_chat_mode,
|
||||
op_chat_boxwidth,
|
||||
op_chat_boxheight,
|
||||
op_chat_yoffs,
|
||||
op_chat_xoffs,
|
||||
op_chat_centertxt,
|
||||
op_chat_bgtint,
|
||||
op_chat_fadetime,
|
||||
op_chat_spamprotect,
|
||||
op_chat_maxmsg,
|
||||
op_chat_charlmt,
|
||||
op_chat_showping,
|
||||
op_chat_pingstyle,
|
||||
op_chat_pingmeasr,
|
||||
op_chat_pingico,
|
||||
op_chat_nodeip,
|
||||
};
|
||||
|
||||
static menuitem_t OP_GameOptionsMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Random Item Toggles...", &OP_MonitorToggleDef, 10},
|
||||
@@ -1631,7 +1702,7 @@ static menuitem_t OP_AccessibilityMenu[] =
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Video Color Settings...", &OP_ColorOptionsDef, 30},
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Reduce Effects", &cv_reducevfx, 35},
|
||||
{IT_STRING|IT_CVAR, NULL, "Midnight Channel Flicker", &cv_lessflicker, 40}, // obsolete now? or still better be a seperate toggle?
|
||||
{IT_STRING|IT_CVAR, NULL, "Less Midnight Channel Flicker", &cv_lessflicker, 40}, // obsolete now? or still better be a seperate toggle?
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Minimum Sector Brightness", &cv_secbright, 45},
|
||||
|
||||
@@ -1713,6 +1784,7 @@ static menuitem_t OP_SaturnMenu[] =
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Saturn Hud...", &OP_SaturnHudDef, 140},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Sprite Distortion...", &OP_PlayerDistortDef, 145},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Saturn Credits", &OP_SaturnCreditsDef, 150}, // uwu
|
||||
{IT_STRING|IT_CALL, NULL, "Report an Issue", M_SaturnReportIssue, 155}
|
||||
};
|
||||
|
||||
static const char* OP_SaturnTooltips[] =
|
||||
@@ -1736,6 +1808,7 @@ static const char* OP_SaturnTooltips[] =
|
||||
"Options for Saturn specific HUD things.",
|
||||
"Options for sprite distortion effects.",
|
||||
"See the people who helped make this project possible!",
|
||||
"Noticed a bug, have a Suggestion or other Feedback?\nFeel free to tell us!",
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -1757,6 +1830,7 @@ enum
|
||||
sm_hud,
|
||||
sm_distortionmenu,
|
||||
sm_credits,
|
||||
sm_issue,
|
||||
};
|
||||
|
||||
static menuitem_t OP_PlayerDistortMenu[] =
|
||||
@@ -1767,20 +1841,23 @@ static menuitem_t OP_PlayerDistortMenu[] =
|
||||
{IT_STRING | IT_CVAR, NULL, "Slope Rotation Distance", &cv_sloperolldist, 15},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Players when Sliptiding", &cv_sliptideroll, 25},
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Sparks and Boost Trails", &cv_sparkroll, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Bananas on Throw", &cv_bananthrowroll, 35},
|
||||
{IT_STRING | IT_CVAR, NULL, "Stair Janking Effect", &cv_stairjank, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Stair Janking Sound Effect", &cv_stairjanksfx, 35}, // idk if that should be here but i dont care atm
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Player Stretch Factor", &cv_gravstretch, 45},
|
||||
{IT_STRING | IT_CVAR, NULL, "Squish Sound Effect", &cv_slamsound, 50},
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Sparks and Boost Trails", &cv_sparkroll, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Rotate Bananas on Throw", &cv_bananthrowroll, 45},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop", &cv_saltyhop, 60},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saltyhop Height", &cv_saltyheight, 65},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Sound Effect", &cv_saltyhopsfx, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Squish", &cv_saltysquish, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Roll", &cv_saltyroll, 80},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Player Stretch Factor", &cv_gravstretch, 55},
|
||||
{IT_STRING | IT_CVAR, NULL, "Squish Sound Effect", &cv_slamsound, 60},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Squishdance", &cv_squishdance, 90},
|
||||
{IT_STRING | IT_CVAR, NULL, "Squishdance Speed", &cv_squishdancespeed, 96},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop", &cv_saltyhop, 70},
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saltyhop Height", &cv_saltyheight, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Sound Effect", &cv_saltyhopsfx, 80},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Squish", &cv_saltysquish, 85},
|
||||
{IT_STRING | IT_CVAR, NULL, "Saltyhop Roll", &cv_saltyroll, 90},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Squishdance", &cv_squishdance, 100},
|
||||
{IT_STRING | IT_CVAR, NULL, "Squishdance Speed", &cv_squishdancespeed, 106}, // why is this offset by 6? idk cant remember lulul
|
||||
};
|
||||
|
||||
static const char* OP_PlayerDistortTooltips[] =
|
||||
@@ -1789,6 +1866,8 @@ static const char* OP_PlayerDistortTooltips[] =
|
||||
"Sprite rotation on slopes. Can either be just players or all objects.",
|
||||
"Distance object rotation should be visable.",
|
||||
"Player rotation when sliptiding.",
|
||||
"Slightly tilt the player when driving over stairs or small bumps.",
|
||||
"Sound effect when driving over stairs or small bumps.",
|
||||
"Rotation of a player's boost trails and drift sparks.",
|
||||
"Should banans rotate when thrown?\nAnd should they stay rotated when on the ground?",
|
||||
"Player squash and stretch.",
|
||||
@@ -1799,7 +1878,7 @@ static const char* OP_PlayerDistortTooltips[] =
|
||||
"Player hop squash and stretch.",
|
||||
"Should the player rotation be kept during player hop.",
|
||||
"Do a funny squishy dance when holding CUSTOM 3.",
|
||||
"Speed of the Squishy dance in BPM.",
|
||||
"Speed of the Squishy dance in SPM (Squishes Per Minute).",
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -1808,6 +1887,8 @@ enum
|
||||
sloperotate,
|
||||
slrotatedist,
|
||||
sliptide,
|
||||
stairjank,
|
||||
stairjanksfx,
|
||||
sparkrotate,
|
||||
bananrotat,
|
||||
stretchyplayer,
|
||||
@@ -2500,6 +2581,11 @@ menu_t OP_Joystick2Def = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick2Menu, &OP
|
||||
menu_t OP_Joystick3Def = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick3Menu, &OP_AllControlsDef, 30, 36, NULL);
|
||||
menu_t OP_Joystick4Def = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick4Menu, &OP_AllControlsDef, 30, 36, NULL);
|
||||
|
||||
menu_t OP_Joystick1RumbleDef = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick1RumbleMenu, &OP_Joystick1Def, 30, 36, NULL);
|
||||
menu_t OP_Joystick2RumbleDef = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick2RumbleMenu, &OP_Joystick2Def, 30, 36, NULL);
|
||||
menu_t OP_Joystick3RumbleDef = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick3RumbleMenu, &OP_Joystick3Def, 30, 36, NULL);
|
||||
menu_t OP_Joystick4RumbleDef = DEFAULTSCROLLSTYLE("M_CONTRO", OP_Joystick4RumbleMenu, &OP_Joystick4Def, 30, 36, NULL);
|
||||
|
||||
menu_t OP_JoystickSetDef =
|
||||
{
|
||||
"M_CONTRO",
|
||||
@@ -2591,7 +2677,7 @@ menu_t OP_Player2CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player2CamOptionsMenu
|
||||
menu_t OP_Player3CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player3CamOptionsMenu, &OP_CamOptionsDef, 30, 30, OP_PlayerCamOptionsTooltips);
|
||||
menu_t OP_Player4CamOptionsDef = DEFAULTMENUSTYLE(NULL, OP_Player4CamOptionsMenu, &OP_CamOptionsDef, 30, 30, OP_PlayerCamOptionsTooltips);
|
||||
|
||||
menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE("M_HUD", OP_ChatOptionsMenu, &OP_HUDOptionsDef, 30, 30, OP_ChatOptionsTooltips);
|
||||
menu_t OP_ChatOptionsDef = DEFAULTSCROLLSTYLE("M_HUD", OP_ChatOptionsMenu, &OP_HUDOptionsDef, 30, 25, OP_ChatOptionsTooltips);
|
||||
|
||||
menu_t OP_SoundAdvancedDef = DEFAULTSCROLLSTYLE("M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30, OP_SoundAdvancedTooltips);
|
||||
|
||||
@@ -2716,6 +2802,15 @@ void PDistort_menu_Onchange(void)
|
||||
OP_PlayerDistortMenu[slrotatedist].status = IT_GRAYEDOUT;
|
||||
OP_PlayerDistortMenu[saltroll].status = IT_GRAYEDOUT;
|
||||
}
|
||||
|
||||
if (cv_stairjank.value)
|
||||
{
|
||||
OP_PlayerDistortMenu[stairjanksfx].status = IT_STRING | IT_CVAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
OP_PlayerDistortMenu[stairjanksfx].status = IT_GRAYEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
void Bird_menu_Onchange(void)
|
||||
|
||||
+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);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key);
|
||||
// If currently typing something that looks like an existing emote, return suggestions for it
|
||||
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_autocomplete_t *autocomplete);
|
||||
|
||||
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-1)*8)
|
||||
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-2)*8)
|
||||
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH);
|
||||
|
||||
#endif
|
||||
+718
-346
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -2338,7 +2338,7 @@ void T_RaiseSector(levelspecthink_t *raise)
|
||||
fixed_t origspeed = raise->vars[3];
|
||||
|
||||
// Slow down as you get closer to the bottom
|
||||
raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->sector->ceilingheight - raise->vars[7], (raise->vars[5] - raise->vars[7])>>5));
|
||||
raise->vars[3] = FixedMul(raise->vars[3], FixedDiv(raise->sector->ceilingheight - raise->vars[7], (raise->vars[5] - raise->vars[7])>>5));
|
||||
|
||||
if (raise->vars[3] <= origspeed/16)
|
||||
raise->vars[3] = origspeed/16;
|
||||
@@ -2349,7 +2349,7 @@ void T_RaiseSector(levelspecthink_t *raise)
|
||||
{
|
||||
fixed_t origspeed = raise->vars[3];
|
||||
// Slow down as you get closer to the top
|
||||
raise->vars[3] = FixedMul(raise->vars[3],FixedDiv(raise->vars[5] - raise->sector->ceilingheight, (raise->vars[5] - raise->vars[7])>>5));
|
||||
raise->vars[3] = FixedMul(raise->vars[3], FixedDiv(raise->vars[5] - raise->sector->ceilingheight, (raise->vars[5] - raise->vars[7])>>5));
|
||||
|
||||
if (raise->vars[3] <= origspeed/16)
|
||||
raise->vars[3] = origspeed/16;
|
||||
|
||||
+44
-32
@@ -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];
|
||||
|
||||
@@ -589,7 +592,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
special->momx = special->momy = special->momz = 0;
|
||||
P_GivePlayerRings(player, 1);
|
||||
|
||||
if (UNLIKELY((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING))
|
||||
if (nightsmode && special->type != MT_FLINGRING)
|
||||
P_DoNightsScore(player);
|
||||
break;
|
||||
|
||||
@@ -601,7 +604,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
special->momx = special->momy = 0;
|
||||
P_GivePlayerRings(player, 1);
|
||||
|
||||
if (UNLIKELY((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN))
|
||||
if (nightsmode && special->type != MT_FLINGCOIN)
|
||||
P_DoNightsScore(player);
|
||||
break;
|
||||
case MT_BLUEBALL:
|
||||
@@ -617,7 +620,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
else
|
||||
special->scalespeed = 4*FRACUNIT/5;
|
||||
|
||||
if (UNLIKELY(maptol & TOL_NIGHTS))
|
||||
if (nightsmode)
|
||||
P_DoNightsScore(player);
|
||||
break;
|
||||
case MT_AUTOPICKUP:
|
||||
@@ -831,7 +834,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
{
|
||||
S_StartSound(toucher, special->info->seesound);
|
||||
|
||||
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
|
||||
if (nightsplayer(player))
|
||||
{
|
||||
player->bumpertime = TICRATE/2;
|
||||
if (special->threshold > 0)
|
||||
@@ -883,18 +886,20 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
break;
|
||||
case MT_HOOPCOLLIDE:
|
||||
// This produces a kind of 'domino effect' with the hoop's pieces.
|
||||
for (; special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
|
||||
|
||||
for (; special != NULL && special->hprev != NULL; special = special->hprev); // Move to the first sprite in the hoop
|
||||
i = 0;
|
||||
for (; special->hnext != NULL && special->type == MT_HOOP; special = special->hnext)
|
||||
for (; special != NULL && special->type == MT_HOOP; special = special->hnext)
|
||||
{
|
||||
if (!P_MobjWasRemoved(special->target))
|
||||
if (!P_MobjWasRemoved(special))
|
||||
{
|
||||
special->fuse = 11;
|
||||
special->movedir = i;
|
||||
special->extravalue1 = special->target->extravalue1;
|
||||
special->extravalue2 = special->target->extravalue2;
|
||||
special->target->threshold = 4242;
|
||||
if (!P_MobjWasRemoved(special->target))
|
||||
{
|
||||
special->extravalue1 = special->target->extravalue1;
|
||||
special->extravalue2 = special->target->extravalue2;
|
||||
special->target->threshold = 4242;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -1131,7 +1136,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
S_StartSound(toucher, special->info->painsound);
|
||||
return;
|
||||
}
|
||||
else if (UNLIKELY((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
|
||||
else if ((nightsplayer(player) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
|
||||
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
|
||||
{
|
||||
// Shatter the shield!
|
||||
@@ -1466,8 +1471,7 @@ static void P_UpdateRemovedOrbital(mobj_t *target, mobj_t *inflictor, mobj_t *so
|
||||
{
|
||||
// SRB2kart
|
||||
// I wish I knew a better way to do this
|
||||
//if (!P_MobjWasRemoved(target->target) && target->target->player && !P_MobjWasRemoved(target->target->player->mo))
|
||||
if (target->target && target->target->player && target->target->player->mo)
|
||||
if (!P_MobjWasRemovedCompat(target->target) && target->target->player && !P_MobjWasRemovedCompat(target->target->player->mo))
|
||||
{
|
||||
if (target->target->player->kartstuff[k_eggmanheld] && target->type == MT_EGGMANITEM_SHIELD)
|
||||
target->target->player->kartstuff[k_eggmanheld] = 0;
|
||||
@@ -1480,7 +1484,7 @@ static void P_UpdateRemovedOrbital(mobj_t *target, mobj_t *inflictor, mobj_t *so
|
||||
{
|
||||
if (target->movedir != 0 && target->movedir < (UINT16)target->target->player->kartstuff[k_itemamount])
|
||||
{
|
||||
if (target->target->hnext) // !P_MobjWasRemoved(target->target->hnext))
|
||||
if (!P_MobjWasRemovedCompat(target->target->hnext))
|
||||
K_KillBananaChain(target->target->hnext, inflictor, source);
|
||||
|
||||
target->target->player->kartstuff[k_itemamount] = 0;
|
||||
@@ -1694,7 +1698,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
|
||||
else
|
||||
prandom = P_RandomKey(5); // No placable object, just use a random number.
|
||||
|
||||
switch(prandom)
|
||||
switch (prandom)
|
||||
{
|
||||
default: item = MT_BUNNY; break;
|
||||
case 1: item = MT_BIRD; break;
|
||||
@@ -2012,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
|
||||
@@ -2238,18 +2242,24 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
return false;
|
||||
|
||||
// well no clue but this may happen ig
|
||||
if (!target || (target->health <= 0))
|
||||
if (P_MobjWasRemovedCompat(target))
|
||||
return false;
|
||||
|
||||
if (target->health <= 0)
|
||||
return false;
|
||||
|
||||
// Spectator handling
|
||||
if (netgame)
|
||||
{
|
||||
if (damage == DMG_SPECTATOR && target->player && target->player->spectator)
|
||||
damage = DMG_INSTAKILL;
|
||||
else if (target->player && target->player->spectator)
|
||||
return false;
|
||||
if (target->player && target->player->spectator)
|
||||
{
|
||||
if (damage == DMG_SPECTATOR)
|
||||
damage = DMG_INSTAKILL;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source && source->player && source->player->spectator)
|
||||
if (!P_MobjWasRemovedCompat(source) && source->player && source->player->spectator)
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2343,16 +2353,17 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
if (player->exiting)
|
||||
return false;
|
||||
|
||||
if (UNLIKELY(!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS)))
|
||||
if (UNLIKELY(!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && nightsmode))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UNLIKELY(player->pflags & PF_NIGHTSMODE)) // NiGHTS damage handling
|
||||
if (nightsplayer(player)) // NiGHTS damage handling
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
if (source == target)
|
||||
return false; // Don't hit yourself with your own paraloop, baka
|
||||
|
||||
if (source && source->player && !cv_friendlyfire.value
|
||||
&& (gametype == GT_COOP
|
||||
|| (G_GametypeHasTeams() && target->player->ctfteam == source->player->ctfteam)))
|
||||
@@ -2402,7 +2413,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
|
||||
else if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing])
|
||||
{
|
||||
if (!force) // shoulddamage bypasses all of that.
|
||||
if (!force) // shoulddamage bypasses all of that.
|
||||
{
|
||||
K_DoInstashield(player);
|
||||
return false;
|
||||
@@ -2591,7 +2602,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
||||
ns = FixedMul(((i*FRACUNIT)/16)+2*FRACUNIT, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
if (!twodmo(player->mo))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 8*FRACUNIT, false);
|
||||
@@ -2615,7 +2626,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
||||
ns = FixedMul(momxy, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
if (!twodmo(player->mo))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
ns = momz;
|
||||
@@ -2624,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;
|
||||
}
|
||||
@@ -2722,7 +2734,7 @@ void P_PlayerWeaponPanelBurst(player_t *player)
|
||||
ns = FixedMul(3*FRACUNIT, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
if (!twodmo(player->mo))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, false);
|
||||
@@ -2806,7 +2818,7 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
|
||||
ns = FixedMul(2*FRACUNIT, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa), ns);
|
||||
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
if (!twodmo(player->mo))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
|
||||
@@ -2922,7 +2934,7 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss)
|
||||
|
||||
momx = FixedMul(FINECOSINE(fa), ns);
|
||||
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
if (!twodmo(player->mo))
|
||||
momy = FixedMul(FINESINE(fa),ns);
|
||||
else
|
||||
momy = 0;
|
||||
@@ -2979,7 +2991,7 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
|
||||
{
|
||||
angle_t fa = P_RandomByte()*FINEANGLES/256;
|
||||
flag->momx = FixedMul(FINECOSINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
if (!twodmo(player->mo))
|
||||
flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
|
||||
}
|
||||
|
||||
|
||||
+18
-2
@@ -59,8 +59,12 @@ extern "C" {
|
||||
|
||||
#define AIMINGTOSLOPE(aiming) FINESINE((aiming>>ANGLETOFINESHIFT) & FINEMASK)
|
||||
|
||||
#define mariomode (maptol & TOL_MARIO)
|
||||
#define twodlevel (maptol & TOL_2D)
|
||||
// unused modes, kept for compat
|
||||
#define nightsmode (UNLIKELY(maptol & TOL_NIGHTS))
|
||||
#define nightsplayer(player) (UNLIKELY((player)->pflags & PF_NIGHTSMODE))
|
||||
#define mariomode (UNLIKELY(maptol & TOL_MARIO))
|
||||
#define twodlevel (UNLIKELY(maptol & TOL_2D))
|
||||
#define twodmo(mobj) (UNLIKELY(twodlevel || ((mobj)->flags2 & MF2_TWOD)))
|
||||
|
||||
//
|
||||
// P_TICK
|
||||
@@ -287,6 +291,17 @@ FUNCINLINE static ATTRINLINE boolean P_MobjWasRemoved(const mobj_t *mobj)
|
||||
return (!mobj || mobj->thinker.function != (actionf_p1)P_MobjThinker);
|
||||
}
|
||||
|
||||
// stupid, but kart allows mobjs that are marked to be removed to be accessed and modified in many cases
|
||||
// so can only check if its not NULL in vanilla compat mode
|
||||
FUNCINLINE static ATTRINLINE boolean P_MobjWasRemovedCompat(const mobj_t *mobj)
|
||||
{
|
||||
#ifdef PHOBOS_BUILD
|
||||
return P_MobjWasRemoved(mobj);
|
||||
#else
|
||||
return !mobj;
|
||||
#endif
|
||||
}
|
||||
|
||||
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
|
||||
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
|
||||
#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false)
|
||||
@@ -403,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);
|
||||
|
||||
|
||||
+172
-41
@@ -136,14 +136,17 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
|
||||
return false;
|
||||
|
||||
// Spectators don't trigger springs.
|
||||
if (object->player && object->player->spectator)
|
||||
return false;
|
||||
|
||||
if (UNLIKELY(object->player && (object->player->pflags & PF_NIGHTSMODE)))
|
||||
if (object->player)
|
||||
{
|
||||
/*Someone want to make these work like bumpers?*/
|
||||
return false;
|
||||
// Spectators don't trigger springs.
|
||||
if (object->player->spectator)
|
||||
return false;
|
||||
|
||||
if (nightsplayer(object->player))
|
||||
{
|
||||
/*Someone want to make these work like bumpers?*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you.
|
||||
@@ -160,10 +163,15 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||
if (spring->eflags & MFE_VERTICALFLIP)
|
||||
vertispeed *= -1;
|
||||
|
||||
// Vertical springs teleport you on TOP of them.
|
||||
if (vertispeed > 0)
|
||||
{
|
||||
object->z = spring->z + spring->height + 1;
|
||||
}
|
||||
else if (vertispeed < 0)
|
||||
{
|
||||
object->z = spring->z - object->height - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Horizontal springs teleport you in FRONT of them.
|
||||
@@ -215,7 +223,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||
if (object->player)
|
||||
{
|
||||
if (spring->flags & MF_ENEMY) // Spring shells
|
||||
{
|
||||
P_SetTarget(&spring->target, object);
|
||||
}
|
||||
|
||||
if (horizspeed && object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0)
|
||||
{
|
||||
@@ -235,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
|
||||
@@ -266,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);
|
||||
@@ -312,13 +322,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
if (thing == tmthing)
|
||||
return true;
|
||||
|
||||
// Ignore... things.
|
||||
if (!tmthing || P_MobjWasRemoved(thing))
|
||||
return true;
|
||||
|
||||
I_Assert(!P_MobjWasRemoved(tmthing));
|
||||
I_Assert(!P_MobjWasRemoved(thing));
|
||||
|
||||
// Ignore... things.
|
||||
if (P_MobjWasRemovedCompat(tmthing) || P_MobjWasRemoved(thing))
|
||||
return true;
|
||||
|
||||
// Ignore spectators
|
||||
if ((tmthing->player && tmthing->player->spectator)
|
||||
|| (thing->player && thing->player->spectator))
|
||||
@@ -350,12 +360,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)) || (thing->flags & MF_NOCLIPTHING))
|
||||
if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)))
|
||||
return true;
|
||||
|
||||
// Don't collide with your buddies while NiGHTS-flying.
|
||||
if (UNLIKELY(tmthing->player && thing->player && (maptol & TOL_NIGHTS)
|
||||
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))))
|
||||
if (nightsmode &&
|
||||
tmthing->player && thing->player &&
|
||||
(nightsplayer(tmthing->player) || nightsplayer(thing->player)))
|
||||
return true;
|
||||
|
||||
blockdist = thing->radius + tmthing->radius;
|
||||
@@ -719,11 +730,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
if (thing->type != MT_PLAYER)
|
||||
return true;
|
||||
|
||||
if (thing->player && thing->player->powers[pw_flashing])
|
||||
return true;
|
||||
|
||||
if (thing->type == MT_PLAYER && thing->player)
|
||||
if (thing->player)
|
||||
{
|
||||
if (thing->player->powers[pw_flashing])
|
||||
return true;
|
||||
|
||||
if (tmthing->state == &states[S_MINEEXPLOSION1])
|
||||
K_ExplodePlayer(thing->player, tmthing->target, tmthing);
|
||||
else
|
||||
@@ -1077,6 +1088,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
thing->momy -= FixedMul(PUSHACCEL, thing->scale);
|
||||
tmthing->momy += FixedMul(PUSHACCEL, thing->scale);
|
||||
}
|
||||
|
||||
if (tmthing->momx > 0 && tmthing->momx > FixedMul(4*FRACUNIT, thing->scale)
|
||||
&& tmthing->momx > thing->momx)
|
||||
{
|
||||
@@ -1094,6 +1106,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
thing->momx = FixedMul(thing->info->speed, thing->scale);
|
||||
else if (thing->momx < -FixedMul(thing->info->speed, thing->scale))
|
||||
thing->momx = -FixedMul(thing->info->speed, thing->scale);
|
||||
|
||||
if (thing->momy > FixedMul(thing->info->speed, thing->scale))
|
||||
thing->momy = FixedMul(thing->info->speed, thing->scale);
|
||||
else if (thing->momy < -FixedMul(thing->info->speed, thing->scale))
|
||||
@@ -1105,6 +1118,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
tmthing->momx = FixedMul(4*FRACUNIT, thing->scale);
|
||||
else if (tmthing->momx < FixedMul(-4*FRACUNIT, thing->scale))
|
||||
tmthing->momx = FixedMul(-4*FRACUNIT, thing->scale);
|
||||
|
||||
if (tmthing->momy > FixedMul(4*FRACUNIT, thing->scale))
|
||||
tmthing->momy = FixedMul(4*FRACUNIT, thing->scale);
|
||||
else if (tmthing->momy < FixedMul(-4*FRACUNIT, thing->scale))
|
||||
@@ -1126,6 +1140,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
P_TouchSpecialThing(thing, tmthing, true); // can remove thing
|
||||
return true;
|
||||
}
|
||||
|
||||
// check again for special pickup
|
||||
if (tmthing->flags & MF_SPECIAL && thing->player)
|
||||
{
|
||||
@@ -1813,14 +1828,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||
delta1 = abs(thing->z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (topheight > tmfloorz && delta1 < delta2
|
||||
if ((topheight > tmfloorz) && (delta1 < delta2)
|
||||
&& !(rover->flags & FF_REVERSEPLATFORM))
|
||||
{
|
||||
tmfloorz = tmdropoffz = topheight;
|
||||
tmfloorslope = *rover->t_slope;
|
||||
}
|
||||
|
||||
if (bottomheight < tmceilingz && delta1 >= delta2
|
||||
if ((bottomheight < tmceilingz) && (delta1 >= delta2)
|
||||
&& !(rover->flags & FF_PLATFORM)
|
||||
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
|
||||
{
|
||||
@@ -1875,8 +1890,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||
|
||||
po->validcount = validcount;
|
||||
|
||||
if (!P_BBoxInsidePolyobj(po, tmbbox)
|
||||
|| !(po->flags & POF_SOLID))
|
||||
if (!(po->flags & POF_SOLID) || !P_BBoxInsidePolyobj(po, tmbbox))
|
||||
{
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
continue;
|
||||
@@ -2012,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;
|
||||
@@ -2054,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);
|
||||
@@ -2121,7 +2135,7 @@ static boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
|
||||
po->validcount = validcount;
|
||||
|
||||
if (!P_PointInsidePolyobj(po, x, y) || !(po->flags & POF_SOLID))
|
||||
if (!(po->flags & POF_SOLID) || !P_PointInsidePolyobj(po, x, y))
|
||||
{
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
continue;
|
||||
@@ -2130,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;
|
||||
@@ -2371,8 +2385,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
fixed_t tryx = thing->x;
|
||||
fixed_t tryy = thing->y;
|
||||
fixed_t radius = thing->radius;
|
||||
fixed_t thingtop ;//= thing->z + thing->height;
|
||||
fixed_t thingtop;//= thing->z + thing->height;
|
||||
fixed_t startingonground = P_IsObjectOnGround(thing);
|
||||
fixed_t stairjank = 0;
|
||||
pslope_t *oldslope = thing->standingslope;
|
||||
INT32 special = -1;
|
||||
floatok = false;
|
||||
|
||||
@@ -2422,7 +2438,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
|
||||
if (thing->player)
|
||||
{
|
||||
if (special == -1)
|
||||
if (special == -1) // this should use the target coords not the ones were started with, but cant fix that for compat reasons!
|
||||
special = GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1);
|
||||
|
||||
// If using type Section1:13, double the maxstep.
|
||||
@@ -2446,11 +2462,19 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
|
||||
thingtop = thing->z + thing->height;
|
||||
|
||||
const boolean flipped =
|
||||
(thing->eflags & MFE_VERTICALFLIP) != 0;
|
||||
|
||||
// Step up
|
||||
if (thing->z < tmfloorz)
|
||||
{
|
||||
if (tmfloorz - thing->z <= maxstep)
|
||||
{
|
||||
if (maxstep > 0 && !flipped)
|
||||
{
|
||||
stairjank = (tmfloorz - thing->z);
|
||||
}
|
||||
|
||||
thing->z = thing->floorz = tmfloorz;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
@@ -2463,6 +2487,11 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
{
|
||||
if (thingtop - tmceilingz <= maxstep)
|
||||
{
|
||||
if (maxstep > 0 && flipped)
|
||||
{
|
||||
stairjank = (thingtop - tmceilingz);
|
||||
}
|
||||
|
||||
thing->z = ( thing->ceilingz = tmceilingz ) - thing->height;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
@@ -2479,11 +2508,21 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
|
||||
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
|
||||
{
|
||||
if (flipped)
|
||||
{
|
||||
stairjank = (tmceilingz - thingtop);
|
||||
}
|
||||
|
||||
thing->z = (thing->ceilingz = tmceilingz) - thing->height;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
|
||||
{
|
||||
if (!flipped)
|
||||
{
|
||||
stairjank = (thing->z - tmfloorz);
|
||||
}
|
||||
|
||||
thing->z = thing->floorz = tmfloorz;
|
||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||
}
|
||||
@@ -2559,6 +2598,26 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||
else // don't set standingslope if you're not going to clip against it
|
||||
thing->standingslope = NULL;
|
||||
|
||||
/* FIXME: slope step down (even up) has some false
|
||||
positives, so just ignore them entirely. */
|
||||
if (stairjank && !oldslope && !thing->standingslope && thing->player && !thing->player->spectator)
|
||||
{
|
||||
/* use a shorter sound if not two tics have passed
|
||||
* since the last step */
|
||||
//S_ReducedVFXSound(thing, (thing->player->stairjank >= 16 ? sfx_s23b : sfx_s268), NULL);
|
||||
//S_StartSound(thing, (thing->player->stairjank >= 16 ? sfx_s23b : sfx_s268));
|
||||
// sound does not work out all that well for kart maps
|
||||
|
||||
// best i can do...
|
||||
if (cv_stairjank.value && cv_stairjanksfx.value)
|
||||
S_StartSoundAtVolume(thing, (thing->player->stairjank >= 8 ? sfx_s23b : sfx_s268), 192); // dont blast this at full volume lul
|
||||
|
||||
// Can't spawn things during P_TryMove, because global variables :)
|
||||
|
||||
thing->player->stairjank = 9;
|
||||
//thing->player->stairjank = 17;
|
||||
}
|
||||
|
||||
thing->x = x;
|
||||
thing->y = y;
|
||||
|
||||
@@ -2609,7 +2668,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
|
||||
if (tmfloorz - thing->z > maxstep)
|
||||
return false; // too big a step up
|
||||
}
|
||||
} while(tryx != x || tryy != y);
|
||||
} while (tryx != x || tryy != y);
|
||||
|
||||
// the move is ok,
|
||||
// so link the thing into its new position
|
||||
@@ -3104,6 +3163,9 @@ void P_SlideMove(mobj_t *mo, boolean forceslide)
|
||||
INT16 hitcount = 0;
|
||||
boolean success = false;
|
||||
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height)
|
||||
{
|
||||
// Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already.
|
||||
@@ -3140,6 +3202,9 @@ void P_SlideMove(mobj_t *mo, boolean forceslide)
|
||||
bestslideline = NULL;
|
||||
|
||||
retry:
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
if (++hitcount == 3)
|
||||
goto stairstep; // don't loop forever
|
||||
|
||||
@@ -3188,7 +3253,13 @@ retry:
|
||||
// the move must have hit the middle, so stairstep
|
||||
stairstep:
|
||||
if (!P_TryMove(mo, mo->x, mo->y + mo->momy, true)) //Allow things to drop off.
|
||||
{
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
P_TryMove(mo, mo->x + mo->momx, mo->y, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3200,7 +3271,12 @@ stairstep:
|
||||
newy = FixedMul(mo->momy, bestslidefrac);
|
||||
|
||||
if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
|
||||
{
|
||||
goto stairstep;
|
||||
}
|
||||
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
}
|
||||
|
||||
// Now continue along the wall.
|
||||
@@ -3219,7 +3295,7 @@ stairstep:
|
||||
if (bestslideline != NULL)
|
||||
P_HitSlideLine(bestslideline); // clip the moves
|
||||
|
||||
if (UNLIKELY((twodlevel || (mo->flags2 & MF2_TWOD)) && mo->player))
|
||||
if (twodmo(mo) && mo->player)
|
||||
{
|
||||
mo->momx = tmxmove;
|
||||
tmymove = 0;
|
||||
@@ -3271,8 +3347,11 @@ stairstep:
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
success = true;
|
||||
} while(tmxmove || tmymove);
|
||||
} while (tmxmove || tmymove);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -3285,12 +3364,18 @@ void P_BouncePlayerMove(mobj_t *mo)
|
||||
{
|
||||
fixed_t leadx, leady;
|
||||
fixed_t trailx, traily;
|
||||
fixed_t mmomx = 0, mmomy = 0;
|
||||
fixed_t oldmomx = mo->momx, oldmomy = mo->momy;
|
||||
fixed_t mmomx, mmomy;
|
||||
fixed_t oldmomx, oldmomy;
|
||||
|
||||
if (!mo->player)
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
if (mo->player == NULL)
|
||||
return;
|
||||
|
||||
oldmomx = mo->momx;
|
||||
oldmomy = mo->momy;
|
||||
|
||||
if (mo->player->spectator)
|
||||
{
|
||||
P_SlideMove(mo, true);
|
||||
@@ -3379,6 +3464,9 @@ void P_BouncePlayerMove(mobj_t *mo)
|
||||
|
||||
if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true))
|
||||
{
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
|
||||
}
|
||||
}
|
||||
@@ -3396,6 +3484,9 @@ void P_BounceMove(mobj_t *mo)
|
||||
INT32 hitcount;
|
||||
fixed_t mmomx = 0, mmomy = 0;
|
||||
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
if (mo->player)
|
||||
{
|
||||
P_BouncePlayerMove(mo);
|
||||
@@ -3412,6 +3503,9 @@ void P_BounceMove(mobj_t *mo)
|
||||
hitcount = 0;
|
||||
|
||||
retry:
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
if (++hitcount == 3)
|
||||
goto bounceback; // don't loop forever
|
||||
|
||||
@@ -3470,7 +3564,12 @@ bounceback:
|
||||
newy = FixedMul(mmomy, bestslidefrac);
|
||||
|
||||
if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
|
||||
{
|
||||
if (P_MobjWasRemovedCompat(mo))
|
||||
return;
|
||||
|
||||
goto bounceback;
|
||||
}
|
||||
}
|
||||
|
||||
// Now continue along the wall.
|
||||
@@ -3667,7 +3766,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|
||||
delta1 = abs(thing->z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (bottomheight <= thing->ceilingz && delta1 >= delta2)
|
||||
if ((bottomheight <= thing->ceilingz) && (delta1 >= delta2))
|
||||
{
|
||||
if (thing->flags & MF_PUSHABLE)
|
||||
{
|
||||
@@ -3884,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
|
||||
@@ -4125,7 +4256,7 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
|
||||
* Must clear tmthing at tic end, as it might contain a pointer to a removed thinker, or the level might have ended/been ended and we clear the objects it was pointing too. Hopefully we don't need to carry this between tics for sync. */
|
||||
void P_MapStart(void)
|
||||
{
|
||||
if (UNLIKELY(tmthing))
|
||||
if (tmthing)
|
||||
I_Error("P_MapStart: tmthing set!");
|
||||
}
|
||||
|
||||
@@ -4177,7 +4308,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
|
||||
delta1 = abs(z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (topheight > floorz && delta1 < delta2)
|
||||
if ((topheight > floorz) && (delta1 < delta2))
|
||||
floorz = topheight;
|
||||
}
|
||||
}
|
||||
|
||||
+32
-18
@@ -326,16 +326,18 @@ void P_CameraLineOpening(line_t *linedef)
|
||||
{
|
||||
for (rover = front->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
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);
|
||||
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
|
||||
|
||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
midheight = (bottomheight + ((topheight - bottomheight) / 2));
|
||||
|
||||
delta1 = abs(mapcampointer->z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (bottomheight < lowestceiling && delta1 >= delta2)
|
||||
lowestceiling = bottomheight;
|
||||
@@ -354,16 +356,18 @@ void P_CameraLineOpening(line_t *linedef)
|
||||
{
|
||||
for (rover = back->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
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);
|
||||
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
|
||||
|
||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
midheight = (bottomheight + ((topheight - bottomheight) / 2));
|
||||
|
||||
delta1 = abs(mapcampointer->z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (bottomheight < lowestceiling && delta1 >= delta2)
|
||||
lowestceiling = bottomheight;
|
||||
@@ -462,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;
|
||||
@@ -524,7 +528,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
// Check for frontsector's fake floors
|
||||
for (rover = front->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
fixed_t topheight, bottomheight, midheight;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
@@ -538,8 +542,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
|
||||
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
|
||||
|
||||
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
midheight = (bottomheight + ((topheight - bottomheight) / 2));
|
||||
|
||||
delta1 = abs(mobj->z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
|
||||
{
|
||||
@@ -567,7 +573,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
// Check for backsectors fake floors
|
||||
for (rover = back->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
fixed_t topheight, bottomheight, midheight;
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
@@ -580,8 +586,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
|
||||
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
|
||||
|
||||
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
midheight = (bottomheight + ((topheight - bottomheight) / 2));
|
||||
|
||||
delta1 = abs(mobj->z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
|
||||
{
|
||||
@@ -611,8 +619,10 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
{
|
||||
const sector_t *polysec = linedef->backsector;
|
||||
|
||||
delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
|
||||
delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
|
||||
const fixed_t polymid = (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight) / 2));
|
||||
|
||||
delta1 = abs(mobj->z - polymid);
|
||||
delta2 = abs(thingtop - polymid);
|
||||
|
||||
if (polysec->floorheight < lowestceiling && delta1 >= delta2)
|
||||
{
|
||||
@@ -620,7 +630,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
ceilingslope = NULL;
|
||||
}
|
||||
else if (polysec->floorheight < highestceiling && delta1 >= delta2)
|
||||
{
|
||||
highestceiling = polysec->floorheight;
|
||||
}
|
||||
|
||||
if (polysec->ceilingheight > highestfloor && delta1 < delta2)
|
||||
{
|
||||
@@ -628,7 +640,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
floorslope = NULL;
|
||||
}
|
||||
else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
|
||||
{
|
||||
lowestfloor = polysec->ceilingheight;
|
||||
}
|
||||
}
|
||||
|
||||
if (highestceiling < highceiling)
|
||||
@@ -842,7 +856,7 @@ void P_SetThingPosition(mobj_t *thing)
|
||||
// at sector_t->touching_thinglist) are broken. When a node is
|
||||
// added, new sector links are created.
|
||||
|
||||
P_CreateSecNodeList(thing,thing->x,thing->y);
|
||||
P_CreateSecNodeList(thing, thing->x, thing->y);
|
||||
thing->touching_sectorlist = sector_list; // Attach to Thing's mobj_t
|
||||
sector_list = NULL; // clear for next time
|
||||
}
|
||||
|
||||
+1771
-1426
File diff suppressed because it is too large.
Load diff
+5
-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
|
||||
@@ -298,6 +287,7 @@ typedef struct mobj_s
|
||||
angle_t angle, pitch, roll; // orientation
|
||||
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
|
||||
angle_t rollangle;
|
||||
angle_t temprollangle; // same as rollangle but resets each tic, idk either man. // cba exposing this to lua either
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
@@ -411,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;
|
||||
|
||||
+74
-8
@@ -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)
|
||||
@@ -3059,7 +3125,7 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save)
|
||||
break;
|
||||
|
||||
default:
|
||||
I_Error("P_UnarchiveSpecials: Unknown tclass %d in savegame", tclass);
|
||||
I_Error("P_NetUnArchiveThinkers: Unknown tclass %d in savegame", tclass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3170,7 +3236,7 @@ FUNCINLINE static ATTRINLINE void P_UnArchivePolyObjects(savebuffer_t *save)
|
||||
numSavedPolys = READINT32(save->p);
|
||||
|
||||
if (numSavedPolys != numPolyObjects)
|
||||
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency\n");
|
||||
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency (expected %d, got %d)\n", numPolyObjects, numSavedPolys);
|
||||
|
||||
for (i = 0; i < numSavedPolys; ++i)
|
||||
P_UnArchivePolyObj(save, &PolyObjects[i]);
|
||||
|
||||
+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;
|
||||
|
||||
+366
-255
File diff suppressed because it is too large.
Load diff
@@ -35,6 +35,7 @@ extern mapthing_t *deathmatchstarts[MAX_DM_STARTS];
|
||||
extern INT32 numdmstarts, numcoopstarts, numredctfstarts, numbluectfstarts;
|
||||
|
||||
extern boolean levelloading;
|
||||
extern UINT8 levelfadecol;
|
||||
|
||||
extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame
|
||||
extern virtres_t *curmapvirt;
|
||||
|
||||
@@ -901,6 +901,11 @@ void P_SlopeLaunch(mobj_t *mo)
|
||||
|
||||
//CONS_Printf("Launched off of slope.\n");
|
||||
mo->standingslope = NULL;
|
||||
|
||||
if (mo->player)
|
||||
{
|
||||
mo->player->stairjank = 0; // fuck you
|
||||
}
|
||||
}
|
||||
|
||||
// Function to help handle landing on slopes
|
||||
|
||||
+56
-26
@@ -538,6 +538,7 @@ static sector_t *getNextSector(line_t *line, sector_t *sec)
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return line->frontsector;
|
||||
}
|
||||
|
||||
@@ -568,6 +569,7 @@ fixed_t P_FindLowestFloorSurrounding(sector_t *sec)
|
||||
if (other->floorheight < floorh)
|
||||
floorh = other->floorheight;
|
||||
}
|
||||
|
||||
return floorh;
|
||||
}
|
||||
|
||||
@@ -1180,7 +1182,7 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max)
|
||||
for (i = 0; i < sector->linecount; i++)
|
||||
{
|
||||
line = sector->lines[i];
|
||||
check = getNextSector(line,sector);
|
||||
check = getNextSector(line, sector);
|
||||
|
||||
if (!check)
|
||||
continue;
|
||||
@@ -1960,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);
|
||||
}
|
||||
@@ -2098,7 +2106,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||
ffloor_t *rover;
|
||||
boolean foundit = false;
|
||||
|
||||
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag != line->tag)
|
||||
continue;
|
||||
@@ -2159,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;
|
||||
@@ -2167,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';
|
||||
|
||||
@@ -2182,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;
|
||||
@@ -2988,10 +2989,10 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
if (GETSECSPECIAL(rover->master->frontsector->special, section) != number)
|
||||
continue;
|
||||
|
||||
topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector);
|
||||
@@ -3399,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:
|
||||
@@ -3878,7 +3879,7 @@ DoneSection2:
|
||||
|
||||
player->kartstuff[k_lapanimation] = 80;
|
||||
|
||||
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
|
||||
if (nightsplayer(player))
|
||||
player->drillmeter += 48*20;
|
||||
|
||||
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
|
||||
@@ -4609,11 +4610,13 @@ void P_UpdateSpecials(void)
|
||||
// POINT LIMIT
|
||||
P_CheckPointLimit();
|
||||
|
||||
#ifndef PHOBOS_BUILD
|
||||
// Dynamic slopeness
|
||||
// we run this here only when not joined midrace
|
||||
// for vanilla compat reasons :chaosleep:
|
||||
if (!midgamejoin)
|
||||
P_RunDynamicSlopes();
|
||||
#endif
|
||||
|
||||
P_UpdateAnimFlats();
|
||||
}
|
||||
@@ -5298,6 +5301,18 @@ static void P_RunLevelLoadExecutors(void)
|
||||
}
|
||||
}
|
||||
|
||||
static fixed_t P_GetSectorGravityFactor(sector_t *sec)
|
||||
{
|
||||
return FixedDiv(*sec->gravity >> FRACBITS, 1000);
|
||||
}
|
||||
|
||||
fixed_t P_GetSectorGravity(sector_t *sec)
|
||||
{
|
||||
if (sec && sec->gravity)
|
||||
return FixedMul(gravity, P_GetSectorGravityFactor(sec));
|
||||
return gravity;
|
||||
}
|
||||
|
||||
/** After the map has loaded, scans for specials that spawn 3Dfloors and
|
||||
* thinkers.
|
||||
*
|
||||
@@ -5359,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
|
||||
@@ -5368,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5452,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;
|
||||
|
||||
@@ -5484,6 +5508,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
|
||||
if ((lines[i].flags & (ML_NOSONIC|ML_NOTAILS)) != (ML_NOSONIC|ML_NOTAILS)) // If you can do something...
|
||||
{
|
||||
angle_t flatangle = InvAngle(lines[i].angle);
|
||||
|
||||
fixed_t xoffs;
|
||||
fixed_t yoffs;
|
||||
|
||||
@@ -5548,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;
|
||||
@@ -7121,7 +7151,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
|
||||
return false;
|
||||
|
||||
// Allow this to affect pushable objects at some point?
|
||||
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || UNLIKELY(thing->player->pflags & PF_NIGHTSMODE)))
|
||||
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || nightsplayer(thing->player)))
|
||||
{
|
||||
INT32 dist;
|
||||
INT32 speed;
|
||||
@@ -7151,7 +7181,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
|
||||
// Written with bits and pieces of P_HomingAttack
|
||||
if ((speed > 0) && (P_CheckSight(thing, tmpusher->source)))
|
||||
{
|
||||
if (LIKELY(!(thing->player->pflags & PF_NIGHTSMODE)))
|
||||
if (!nightsplayer(thing->player))
|
||||
{
|
||||
// only push wrt Z if health & 1 (mapthing has ambush flag)
|
||||
if (tmpusher->source->health & 1)
|
||||
|
||||
Loaded 100 of 145 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user