Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44ecb677ad | ||
|
|
3e99f4d142 | ||
|
|
a9d0e2154b | ||
|
|
16a0953d1d | ||
|
|
737ae08355 | ||
|
|
6d83a7e187 | ||
|
|
56df9b6af3 | ||
|
|
7f2435d821 | ||
|
|
b180f29fd9 | ||
|
|
32c85f96a4 | ||
|
|
ec83c60320 | ||
|
|
fb4a912dba | ||
|
|
123b2aa60b | ||
|
|
bd82a8db29 | ||
|
|
6f71fc17c2 | ||
|
|
d8c3e9f41c | ||
|
|
e10345b4de | ||
|
|
2ab66b113c | ||
|
|
f64263cf6f | ||
|
|
55c72f32da | ||
|
|
53bc12baad | ||
|
|
b391e763bc | ||
|
|
2bae0bdb0f | ||
|
|
d42df54901 | ||
|
|
e6256d448f | ||
|
|
ad1a980eb1 | ||
|
|
1b50858fa6 | ||
|
|
3276bbb7b6 | ||
|
|
dc00fa3429 | ||
|
|
dc9276b73c | ||
|
|
271d70d6f3 | ||
|
|
e52a6c430b | ||
|
|
d77d25acf8 | ||
|
|
9898809f0a | ||
|
|
48768aa13c | ||
|
|
b1c01a763f | ||
|
|
d9bcd6007c | ||
|
|
d1b478b3b1 | ||
|
|
14b421f533 | ||
|
|
7310a8e4df | ||
|
|
c1c3a7dc78 | ||
|
|
ff10b77414 | ||
|
|
4667c332b4 | ||
|
|
4a9f6b6a22 | ||
|
|
f1d78243d0 | ||
|
|
6e41c8a2a0 | ||
|
|
9c5955feb0 | ||
|
|
0764b180f7 | ||
|
|
b883e4e4fe | ||
|
|
f78688b684 | ||
|
|
097cd5e2ca | ||
|
|
cd4836ae99 | ||
|
|
f0acf179c2 | ||
|
|
836ad12c40 | ||
|
|
a147fa3100 | ||
|
|
a68a05a838 | ||
|
|
95504547df | ||
|
|
ceb2a70664 | ||
|
|
8593a1975c | ||
|
|
48d9b2bc98 | ||
|
|
939bf588b3 | ||
|
|
a61b028e97 | ||
|
|
e29bdd09c5 | ||
|
|
74b082760d | ||
|
|
4460fa608b | ||
|
|
949192c570 | ||
|
|
4fa0ca2304 | ||
|
|
d9d2f043fa | ||
|
|
1ea51f29c5 | ||
|
|
b0653416f6 | ||
|
|
b4570cbdaa | ||
|
|
f2dc344bf8 | ||
|
|
c0654448f0 | ||
|
|
2bf3912633 | ||
|
|
4d71fb8409 | ||
|
|
8543a099f4 | ||
|
|
9c6ec02b18 | ||
|
|
bb9118ee32 | ||
|
|
1847aac223 | ||
|
|
14be968089 | ||
|
|
9f678263d0 | ||
|
|
cb0667921e | ||
|
|
52ab27a825 | ||
|
|
38b89093fa | ||
|
|
224ce007e1 | ||
|
|
2800685cfc | ||
|
|
0241d7fe00 | ||
|
|
5d8bb3223f | ||
|
|
5e1f943a38 | ||
|
|
fca7b4a837 | ||
|
|
02ce2ff5ec | ||
|
|
d2bab80b29 | ||
|
|
667a8bb166 | ||
|
|
76a18d001f | ||
|
|
78ab90c1a6 | ||
|
|
45b9aeb85a | ||
|
|
d580306b8a | ||
|
|
102e944fd5 | ||
|
|
3748896ebc | ||
|
|
79988dea3d | ||
|
|
4409a5848f | ||
|
|
07c13636fc | ||
|
|
51cc706b1e | ||
|
|
54bd31c80a | ||
|
|
61534d7356 | ||
|
|
9bd4a933cf | ||
|
|
e233635783 | ||
|
|
da24ba20c7 | ||
|
|
74bdabc636 | ||
|
|
4b129314d3 | ||
|
|
3a55972997 | ||
|
|
6e04e4171e | ||
|
|
cccfaaabfd | ||
|
|
eadbe9c2e5 | ||
|
|
9bbabcee06 | ||
|
|
7ca6fa6772 | ||
|
|
6317e9c510 | ||
|
|
0a80985771 | ||
|
|
548d52cc60 | ||
|
|
11c6c69a00 | ||
|
|
08025d2da3 | ||
|
|
4169e7bd71 | ||
|
|
bfb7a6b08d | ||
|
|
58abb0d4c3 | ||
|
|
9658279cb1 | ||
|
|
d1a6394e52 | ||
|
|
6f4e387061 | ||
|
|
33ef566fd2 | ||
|
|
eeecd954e2 | ||
|
|
ccb804a4ed | ||
|
|
a21029ee9e | ||
|
|
ccc90842a7 | ||
|
|
dc069d7bb5 | ||
|
|
f4a827dfc2 | ||
|
|
4f3232b6cc | ||
|
|
7393eb728c | ||
|
|
1e715f8cd7 | ||
|
|
7aadc77a69 | ||
|
|
27e1406e6d | ||
|
|
796204d376 | ||
|
|
acabd1a03e | ||
|
|
c08aae2622 | ||
|
|
3eba512ad4 | ||
|
|
c99115d552 | ||
|
|
bf6c682cc1 | ||
|
|
dc2f0b5707 | ||
|
|
9488d98cfd | ||
|
|
906b8165d3 | ||
|
|
74c8325987 | ||
|
|
e30efbfe6c | ||
|
|
5d4bb0f5ce | ||
|
|
e63777c7d6 | ||
|
|
a34ca05bff | ||
|
|
af9ffc1f6f | ||
|
|
18816453f4 | ||
|
|
1eb8a75058 | ||
|
|
5abf42fe75 | ||
|
|
1306a233b8 | ||
|
|
46f8c6b7a5 | ||
|
|
face5cf447 | ||
|
|
603267b753 | ||
|
|
7cf3113d67 | ||
|
|
397fa962b1 | ||
|
|
d2637ab71f | ||
|
|
a6e020adeb | ||
|
|
d50dcac0c0 | ||
|
|
dd6bc23a8e | ||
|
|
71575f5cf8 | ||
|
|
3685502edf | ||
|
|
9899747a7f | ||
|
|
d2a415380d | ||
|
|
dd7ffd7dfe | ||
|
|
770f9af5e1 | ||
|
|
c2ab5be8b8 | ||
|
|
b8ae656968 | ||
|
|
553b61e1f5 | ||
|
|
f87bcef079 | ||
|
|
c3458afe2b | ||
|
|
17bc8a4a36 | ||
|
|
b04f017ab6 | ||
|
|
083ddb6396 | ||
|
|
c3129742c3 | ||
|
|
877bd640f3 | ||
|
|
3233df9c6c | ||
|
|
9ad5f5189c | ||
|
|
c7718dea79 | ||
|
|
5a0fb59b26 | ||
|
|
07c52e6af5 | ||
|
|
405c566038 | ||
|
|
78780799ea | ||
|
|
82b9457aa7 | ||
|
|
4e6abb39dd |
No files matched your search
+21
-6
@@ -246,13 +246,25 @@ debug_opts=-DNDEBUG
|
||||
opts+=-O3
|
||||
ifdef USELTO
|
||||
# compile with LTO
|
||||
ifdef MINGW
|
||||
opts+=-flto=auto -g
|
||||
libs+=-flto=auto -g
|
||||
else
|
||||
opts+=-flto=auto
|
||||
libs+=-flto=auto
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USEASAN
|
||||
# compile with asan
|
||||
ifdef MINGW
|
||||
opts+=-fsanitize=address -g
|
||||
libs+=-fsanitize=address -g
|
||||
else
|
||||
opts+=-fsanitize=address
|
||||
libs+=-fsanitize=address
|
||||
endif
|
||||
opts+=-fsanitize=address
|
||||
libs+=-fsanitize=address
|
||||
endif
|
||||
@@ -262,8 +274,11 @@ opts+=$(debug_opts)
|
||||
|
||||
opts+=$(foreach v,$(passthru_opts),$(if $($(v)),-D$(v)))
|
||||
|
||||
opts+=$(WFLAGS) $(CPPFLAGS) $(CFLAGS)
|
||||
cxxopts:=$(opts) $(CXXFLAGS) -std=c++17
|
||||
CXXFLAGS+=-std=c++17 # force c17 for c++ since most vpss run older ubuntu versions with old compilers
|
||||
|
||||
opts+=$(WFLAGS) $(CFLAGS)
|
||||
cxxopts:=$(opts) $(CXXFLAGS)
|
||||
opts+=$(CWFLAGS) # warning flags that shouldnt be passed to c++ compiler
|
||||
|
||||
libs+=$(LDFLAGS) -lstdc++ -lpthread
|
||||
asflags:=$(ASFLAGS) -x assembler-with-cpp
|
||||
@@ -375,12 +390,12 @@ ifdef Echo_name
|
||||
@printf '%-20.20s\r' $$<
|
||||
endif
|
||||
endif
|
||||
$(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$<
|
||||
$(.)$(2) -MM -MF $$@ -MT $(objdir)/$$*.o $(3) $$<
|
||||
endef
|
||||
|
||||
$(eval $(call _recipe,c))
|
||||
$(eval $(call _recipe,cpp))
|
||||
$(eval $(call _recipe,s,$(asflags)))
|
||||
$(eval $(call _recipe,c,$(cc)))
|
||||
$(eval $(call _recipe,cpp,$(cxx)))
|
||||
$(eval $(call _recipe,s,$(cc),$(asflags)))
|
||||
|
||||
# compiling recipe template
|
||||
# 1: target file suffix
|
||||
|
||||
@@ -6,8 +6,7 @@ passthru_opts+=\
|
||||
NOHW NOMD5 NOPOSTPROCESSING\
|
||||
MOBJCONSISTANCY PACKETDROP ZDEBUG\
|
||||
HAVE_MINIUPNPC\
|
||||
HAVE_DISCORDRPC DEVELOP\
|
||||
NOBLUAJIT
|
||||
HAVE_DISCORDRPC DEVELOP
|
||||
|
||||
# build with debugging information
|
||||
ifdef DEBUGMODE
|
||||
@@ -98,7 +97,7 @@ opts+=-DHAVE_VALGRIND
|
||||
endif
|
||||
|
||||
default_packages:=\
|
||||
GME/libgme/LIBGME\
|
||||
LIBGME/libgme/LIBGME\
|
||||
OPENMPT/libopenmpt/LIBOPENMPT\
|
||||
ZLIB/zlib\
|
||||
|
||||
|
||||
@@ -20,10 +20,6 @@ $(foreach v,$(join $(wordlist 2,$(_n),- $(gcc_versions)),\
|
||||
CXXFLAGS+= -Wno-aggregate-return
|
||||
|
||||
# -W -Wno-unused
|
||||
|
||||
ifdef GCC150
|
||||
opts+=-std=gnu17
|
||||
endif
|
||||
WFLAGS:=-Wall -Wno-trigraphs
|
||||
ifndef GCC295
|
||||
#WFLAGS+=-Wno-packed
|
||||
@@ -45,7 +41,8 @@ ifdef GCC41
|
||||
WFLAGS+=-Wshadow
|
||||
endif
|
||||
#WFLAGS+=-Wlarger-than-%len%
|
||||
WFLAGS+=-Wpointer-arith -Wbad-function-cast
|
||||
WFLAGS+=-Wpointer-arith
|
||||
CWFLAGS+=-Wbad-function-cast
|
||||
ifdef GCC45
|
||||
#WFLAGS+=-Wc++-compat
|
||||
endif
|
||||
@@ -75,9 +72,10 @@ endif
|
||||
endif
|
||||
#WFLAGS+=-Wstrict-prototypes
|
||||
ifdef GCC40
|
||||
WFLAGS+=-Wold-style-definition
|
||||
CWFLAGS+=-Wold-style-definition
|
||||
endif
|
||||
WFLAGS+=-Wmissing-prototypes -Wmissing-declarations
|
||||
WFLAGS+=-Wmissing-declarations
|
||||
CWFLAGS+=-Wmissing-prototypes
|
||||
ifdef GCC40
|
||||
WFLAGS+=-Wmissing-field-initializers
|
||||
endif
|
||||
@@ -88,7 +86,7 @@ endif
|
||||
#WFLAGS+=-Wpacked
|
||||
#WFLAGS+=-Wpadded
|
||||
#WFLAGS+=-Wredundant-decls
|
||||
WFLAGS+=-Wnested-externs
|
||||
CWFLAGS+=-Wnested-externs
|
||||
#WFLAGS+=-Wunreachable-code
|
||||
WFLAGS+=-Winline
|
||||
ifdef DEBUGMODE
|
||||
|
||||
@@ -66,7 +66,7 @@ $(eval $(call _set,LIBGME))
|
||||
|
||||
lib:=../libs/libopenmpt
|
||||
LIBOPENMPT_opts:=-I$(lib)/inc
|
||||
LIBOPENMPT_libs:=-L$(lib)/lib/$(x86)/mingw -lopenmpt
|
||||
LIBOPENMPT_libs:=-L$(lib)/lib/$(x86) -lopenmpt
|
||||
$(eval $(call _set,LIBOPENMPT))
|
||||
|
||||
lib:=../libs/SDL2_mixer/$(mingw)
|
||||
|
||||
@@ -29,6 +29,7 @@ m_cond.c
|
||||
m_fixed.c
|
||||
m_menu.c
|
||||
m_textinput.c
|
||||
m_emotes.cpp
|
||||
m_misc.c
|
||||
m_perfstats.c
|
||||
m_queue.c
|
||||
|
||||
+21
-1
@@ -36,6 +36,26 @@ LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
|
||||
/* extra error code for `luaL_load' */
|
||||
#define LUA_ERRFILE (LUA_ERRERR+1)
|
||||
|
||||
/* Compiler-specific attributes and other macros */
|
||||
|
||||
#ifdef __GNUC__ // __attribute__ ((X))
|
||||
|
||||
#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__) // MinGW, >= GCC 4.1
|
||||
#if 0 //defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0
|
||||
#define FUNCREPORT __attribute__ ((format(gnu_printf, 2, 3)))
|
||||
#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4
|
||||
#define FUNCREPORT __attribute__ ((format(ms_printf, 2, 3)))
|
||||
#else
|
||||
#define FUNCREPORT __attribute__ ((format(printf, 2, 3)))
|
||||
#endif
|
||||
#else
|
||||
#define FUNCREPORT __attribute__ ((format(printf, 2, 3)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FUNCREPORT
|
||||
#define FUNCREPORT
|
||||
#endif
|
||||
|
||||
typedef struct luaL_Reg {
|
||||
const char *name;
|
||||
@@ -70,7 +90,7 @@ LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
|
||||
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
|
||||
|
||||
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
|
||||
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
||||
LUALIB_API FUNCREPORT int (luaL_error) (lua_State *L, const char *fmt, ...);
|
||||
|
||||
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
|
||||
const char *const lst[]);
|
||||
|
||||
+823
-728
File diff suppressed because it is too large.
Load diff
+2
-3
@@ -42,8 +42,8 @@ applications may follow different packet versions.
|
||||
#define VANILLA_GT_MATCH 3
|
||||
|
||||
// Networking and tick handling related.
|
||||
#define BACKUPTICS 32
|
||||
#define TICQUEUE 512 // more than enough for most timeouts....
|
||||
#define BACKUPTICS 512 // more than enough for most timeouts....
|
||||
#define CLIENTBACKUPTICS 32
|
||||
#define MAXTEXTCMD 256
|
||||
|
||||
// No. of tics your controls can be delayed by.
|
||||
@@ -533,7 +533,6 @@ extern UINT32 serverlistultimatecount;
|
||||
extern INT32 mapchangepending;
|
||||
|
||||
// Points inside doomcom
|
||||
extern doomdata_t *netbuffer;
|
||||
extern consvar_t cv_stunserver;
|
||||
extern consvar_t cv_httpsource;
|
||||
extern consvar_t cv_kicktime;
|
||||
|
||||
+4
-1
@@ -40,6 +40,7 @@
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "m_emotes.h"
|
||||
#include "i_sound.h"
|
||||
#include "i_system.h"
|
||||
#include "i_time.h"
|
||||
@@ -927,7 +928,7 @@ void D_SRB2Loop(void)
|
||||
// consoleplayer -> displayplayers (hear sounds from viewpoint)
|
||||
S_UpdateSounds(); // move positional sounds
|
||||
|
||||
LUA_Step();
|
||||
//LUA_Step();
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
if (!dedicated && renderisnewtic)
|
||||
@@ -2036,6 +2037,8 @@ void D_SRB2Main(void)
|
||||
|
||||
S_InitMusicDefs();
|
||||
|
||||
M_InitEmotes();
|
||||
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
||||
|
||||
+34
-29
@@ -48,12 +48,6 @@ tic_t connectiontimeout = (10*TICRATE);
|
||||
|
||||
/// \brief network packet
|
||||
doomcom_t *doomcom = NULL;
|
||||
/// \brief network packet data, points inside doomcom
|
||||
doomdata_t *netbuffer = NULL;
|
||||
/// \brief hole punching packet, also points inside doomcom
|
||||
#ifdef HOLEPUNCH
|
||||
holepunch_t *holepunchpacket = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
FILE *debugfile = NULL; // put some net info in a file during the game
|
||||
@@ -209,13 +203,9 @@ static node_t nodes[MAXNETNODES];
|
||||
// 0 if a = n (mod 256)
|
||||
// >0 if a > b (mod 256)
|
||||
// mnemonic: to use it compare to 0: cmpack(a,b)<0 is "a < b" ...
|
||||
FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b)
|
||||
FUNCMATH static inline INT32 cmpack(UINT8 a, UINT8 b)
|
||||
{
|
||||
register INT32 d = a - b;
|
||||
|
||||
if (d >= 127 || d < -128)
|
||||
return -d;
|
||||
return d;
|
||||
return (SINT8)(a - b);
|
||||
}
|
||||
|
||||
/** Sets freeack to a free acknum and copies the netbuffer in the ackpak table
|
||||
@@ -229,6 +219,8 @@ static boolean GetFreeAcknum(UINT8 *freeack)
|
||||
node_t *node = &nodes[doomcom->remotenode];
|
||||
INT32 i, numfreeslot = 0;
|
||||
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0)
|
||||
{
|
||||
DEBFILE(va("too fast %d %d\n",node->remotefirstack,node->nextacknum));
|
||||
@@ -298,6 +290,7 @@ static boolean Processackpak(void)
|
||||
INT32 i;
|
||||
boolean goodpacket = true;
|
||||
node_t *node = &nodes[doomcom->remotenode];
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
// Received an ack return, so remove the ack in the list
|
||||
if (netbuffer->ackreturn && cmpack(node->remotefirstack, netbuffer->ackreturn) < 0)
|
||||
@@ -307,7 +300,7 @@ static boolean Processackpak(void)
|
||||
// Search the ackbuffer and free it
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
{
|
||||
if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes
|
||||
if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode
|
||||
&& cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0)
|
||||
{
|
||||
RemoveAck(i);
|
||||
@@ -423,6 +416,7 @@ void Net_SendAcks(INT32 node)
|
||||
#ifdef NONET
|
||||
(void)node;
|
||||
#else
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
netbuffer->packettype = PT_NOTHING;
|
||||
M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND);
|
||||
HSendPacket(node, false, 0, MAXACKTOSEND);
|
||||
@@ -434,6 +428,8 @@ static void GotAcks(void)
|
||||
{
|
||||
INT32 i, j;
|
||||
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
for (j = 0; j < MAXACKTOSEND; j++)
|
||||
{
|
||||
if (netbuffer->u.textcmd[j])
|
||||
@@ -487,6 +483,8 @@ void Net_AckTicker(void)
|
||||
#ifndef NONET
|
||||
INT32 i;
|
||||
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
for (i = 0; i < MAXACKPACKETS; i++)
|
||||
{
|
||||
const INT32 nodei = ackpak[i].destinationnode;
|
||||
@@ -542,6 +540,7 @@ void Net_UnAcknowledgePacket(INT32 node)
|
||||
#ifdef NONET
|
||||
(void)node;
|
||||
#else
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND;
|
||||
DEBFILE(va("UnAcknowledge node %d\n", node));
|
||||
|
||||
@@ -736,6 +735,7 @@ void Net_CloseConnection(INT32 node)
|
||||
//
|
||||
static UINT32 NetbufferChecksum(void)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
UINT32 c = 0x1234567;
|
||||
const INT32 l = doomcom->datalength - 4;
|
||||
const UINT8 *buf = (UINT8 *)netbuffer + 4;
|
||||
@@ -852,6 +852,8 @@ const char *Net_GetPacketName(UINT8 packettype)
|
||||
|
||||
static void DebugPrintpacket(const char *header)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
fprintf(debugfile, "%-12s (node %d,ack %d,ackret %d,size %d) type(%d) : %s\n",
|
||||
header, doomcom->remotenode, netbuffer->ack, netbuffer->ackreturn, doomcom->datalength,
|
||||
netbuffer->packettype, Net_GetPacketName(netbuffer->packettype));
|
||||
@@ -1021,6 +1023,7 @@ void Command_Droprate(void)
|
||||
#ifndef NONET
|
||||
static boolean ShouldDropPacket(void)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
return (packetdropquantity[netbuffer->packettype])
|
||||
|| (packetdroprate != 0 && rand() < (((double)RAND_MAX) * (packetdroprate / 100.f))) || packetdroprate == 100;
|
||||
}
|
||||
@@ -1032,6 +1035,7 @@ static boolean ShouldDropPacket(void)
|
||||
//
|
||||
boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
doomcom->datalength = (INT16)(packetlength + BASEPACKETSIZE);
|
||||
|
||||
if (node == 0) // Packet is to go back to us
|
||||
@@ -1132,7 +1136,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
|
||||
//
|
||||
boolean HGetPacket(void)
|
||||
{
|
||||
//boolean nodejustjoined;
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
// Get a packet from self
|
||||
if (rebound_tail != rebound_head)
|
||||
@@ -1220,6 +1224,18 @@ static void Internal_FreeNodenum(INT32 nodenum)
|
||||
(void)nodenum;
|
||||
}
|
||||
|
||||
static char *I_NetSplitAddress(char *host, char **port)
|
||||
{
|
||||
boolean v4 = (host[0] != '[');
|
||||
|
||||
host = strtok(host, v4 ? ":" : "[]");
|
||||
|
||||
if (port)
|
||||
*port = strtok(NULL, ":");
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
SINT8 I_NetMakeNode(const char *hostname)
|
||||
{
|
||||
SINT8 newnode = -1;
|
||||
@@ -1227,20 +1243,14 @@ SINT8 I_NetMakeNode(const char *hostname)
|
||||
if (I_NetMakeNodewPort)
|
||||
{
|
||||
char *localhostname = strdup(hostname);
|
||||
char *t = localhostname;
|
||||
const char *port;
|
||||
char *port;
|
||||
if (!localhostname)
|
||||
return newnode;
|
||||
|
||||
// retrieve portnum from address!
|
||||
strtok(localhostname, ":");
|
||||
port = strtok(NULL, ":");
|
||||
hostname = I_NetSplitAddress(localhostname, &port);
|
||||
|
||||
// remove the port in the hostname as we've it already
|
||||
while ((*t != ':') && (*t != '\0'))
|
||||
t++;
|
||||
*t = '\0';
|
||||
|
||||
newnode = I_NetMakeNodewPort(localhostname, port);
|
||||
newnode = I_NetMakeNodewPort(hostname, port);
|
||||
free(localhostname);
|
||||
}
|
||||
return newnode;
|
||||
@@ -1332,11 +1342,6 @@ boolean D_CheckNetGame(void)
|
||||
if (doomcom->numnodes > MAXNETNODES)
|
||||
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
|
||||
|
||||
netbuffer = (doomdata_t *)(void *)&doomcom->data;
|
||||
#ifdef HOLEPUNCH
|
||||
holepunchpacket = (holepunch_t *)(void *)&doomcom->data;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (M_CheckParm("-debugfile"))
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "i_system.h"
|
||||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "m_emotes.h"
|
||||
#include "g_input.h"
|
||||
#include "m_menu.h"
|
||||
#include "r_local.h"
|
||||
@@ -912,6 +913,8 @@ void D_RegisterClientCommands(void)
|
||||
|
||||
CV_RegisterVar(&cv_keyboardlayout);
|
||||
|
||||
CV_RegisterVar(&cv_emotes);
|
||||
|
||||
// time attack ghost options are also saved to config
|
||||
CV_RegisterVar(&cv_ghost_besttime);
|
||||
CV_RegisterVar(&cv_ghost_bestlap);
|
||||
|
||||
@@ -142,6 +142,7 @@ UINT8 *PutFileNeeded(UINT16 firstfile)
|
||||
{
|
||||
size_t i;
|
||||
UINT8 count = 0;
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
UINT8 *p_start = netbuffer->packettype == PT_MOREFILESNEEDED ? netbuffer->u.filesneededcfg.files : netbuffer->u.serverinfo.fileneeded;
|
||||
UINT8 *p = p_start;
|
||||
char wadfilename[MAX_WADPATH] = "";
|
||||
@@ -323,6 +324,7 @@ boolean CL_SendRequestFile(void)
|
||||
#ifdef MORELEGACYDOWNLOADER
|
||||
boolean firstloop = true;
|
||||
#endif
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (M_CheckParm("-nodownload"))
|
||||
@@ -451,9 +453,11 @@ tryagain:
|
||||
// returns false if a requested file was not found or cannot be sent
|
||||
boolean Got_RequestFilePak(INT32 node)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
char wad[MAX_WADPATH+1];
|
||||
UINT8 *p = netbuffer->u.textcmd;
|
||||
UINT8 id;
|
||||
|
||||
while (p < netbuffer->u.textcmd + MAXTEXTCMD) // Don't allow hacked client to overflow
|
||||
{
|
||||
id = READUINT8(p);
|
||||
@@ -817,6 +821,7 @@ void SV_FileSendTicker(void)
|
||||
size_t size;
|
||||
filetx_t *f;
|
||||
INT32 packetsent, ram, i, j;
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
if (!filestosend) // No file to send
|
||||
return;
|
||||
@@ -945,6 +950,7 @@ void SV_FileSendTicker(void)
|
||||
|
||||
void Got_Filetxpak(void)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
INT32 filenum = netbuffer->u.filetxpak.fileid;
|
||||
fileneeded_t *file = &fileneeded[filenum];
|
||||
char *filename = file->filename;
|
||||
|
||||
@@ -1616,7 +1616,6 @@ actionpointer_t actionpointers[] =
|
||||
{A_BrakLobShot, "A_BRAKLOBSHOT"},
|
||||
{A_NapalmScatter, "A_NAPALMSCATTER"},
|
||||
{A_SpawnFreshCopy, "A_SPAWNFRESHCOPY"},
|
||||
//{A_InvincSparkleRotate, "A_INVINCSPARKLEROTATE"},
|
||||
|
||||
{NULL, "NONE"},
|
||||
|
||||
|
||||
@@ -70,7 +70,11 @@ extern "C" {
|
||||
#include <string.h>
|
||||
|
||||
#define _USE_MATH_DEFINES // fixes M_PI errors in r_plane.c for Visual Studio
|
||||
#ifdef __cplusplus
|
||||
#include <cmath>
|
||||
#else
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
+1
-1
@@ -575,7 +575,7 @@ extern consvar_t cv_downloading; // allow clients to downloading WADs.
|
||||
extern consvar_t cv_nettimeout; // SRB2Kart: Advanced server options menu
|
||||
extern consvar_t cv_jointimeout;
|
||||
extern consvar_t cv_maxping;
|
||||
extern ticcmd_t netcmds[TICQUEUE][MAXPLAYERS];
|
||||
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
|
||||
extern INT32 serverplayer;
|
||||
extern INT32 adminplayers[MAXPLAYERS];
|
||||
|
||||
|
||||
+11
-10
@@ -365,8 +365,8 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
char searchpath[1024];
|
||||
size_t *searchpathindex;
|
||||
|
||||
dirhandle = (DIR**) malloc(maxsearchdepth * sizeof (DIR*));
|
||||
searchpathindex = (size_t *) malloc(maxsearchdepth * sizeof (size_t));
|
||||
dirhandle = (DIR**) malloc(maxsearchdepth * sizeof(DIR*));
|
||||
searchpathindex = (size_t *) malloc(maxsearchdepth * sizeof(size_t));
|
||||
|
||||
strcpy(searchpath,startpath);
|
||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||
@@ -410,14 +410,14 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
}
|
||||
|
||||
// okay, now we actually want searchpath to incorporate d_name
|
||||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||
strcpy(&searchpath[searchpathindex[depthleft]], dent->d_name);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
if (dent->d_type == DT_UNKNOWN && lstat(searchpath,&fsstat) == 0)
|
||||
if (dent->d_type == DT_UNKNOWN && lstat(searchpath, &fsstat) == 0)
|
||||
{
|
||||
if (S_ISDIR(fsstat.st_mode))
|
||||
dent->d_type = DT_DIR;
|
||||
else if (S_ISLNK(fsstat.st_mode))
|
||||
else if (S_ISLNK(fsstat.st_mode))
|
||||
dent->d_type = DT_LNK;
|
||||
}
|
||||
|
||||
@@ -439,11 +439,12 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
{
|
||||
searchpathindex[--depthleft] = strlen(searchpath) + 1;
|
||||
dirhandle[depthleft] = opendir(searchpath);
|
||||
|
||||
if (!dirhandle[depthleft])
|
||||
{
|
||||
// can't open it... maybe no read-permissions
|
||||
// go back to previous dir
|
||||
depthleft++;
|
||||
// can't open it... maybe no read-permissions
|
||||
// go back to previous dir
|
||||
depthleft++;
|
||||
}
|
||||
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
@@ -455,9 +456,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
||||
{
|
||||
case FS_FOUND:
|
||||
if (completepath)
|
||||
strcpy(filename,searchpath);
|
||||
strcpy(filename, searchpath);
|
||||
else
|
||||
strcpy(filename,dent->d_name);
|
||||
strcpy(filename, dent->d_name);
|
||||
retval = FS_FOUND;
|
||||
found = 1;
|
||||
break;
|
||||
|
||||
+2
-2
@@ -1051,7 +1051,7 @@ void G_ConsGhostTic(INT32 playernum)
|
||||
mobj = NULL;
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
if (th->function != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
mobj = (mobj_t *)th;
|
||||
if (mobj->type == (mobjtype_t)type && mobj->x == x && mobj->y == y && mobj->z == z)
|
||||
@@ -3701,7 +3701,7 @@ void G_DoPlayMetal(void)
|
||||
// find metal sonic
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
if (th->function != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
|
||||
+1
-3939
File diff suppressed because it is too large.
Load diff
@@ -21,8 +21,6 @@ extern "C" {
|
||||
#include "hw_data.h"
|
||||
#include "hw_gl.h"
|
||||
|
||||
extern boolean currently_batching;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused
|
||||
|
||||
+208
-136
@@ -48,14 +48,20 @@ typedef struct
|
||||
// if no portals are found, the portal scanning phase can be skipped while rendering, saving a bit of time.
|
||||
boolean gl_maphasportals = false;
|
||||
|
||||
// Determine on mapload if current map has any Horizonlines present
|
||||
// so we can avoid rather hot checks in HWR_Subsector
|
||||
boolean gl_maphashorizonlines = false;
|
||||
|
||||
// ==========================================================================
|
||||
// FLOOR & CEILING CONVEX POLYS GENERATION
|
||||
// ==========================================================================
|
||||
|
||||
//debug counters
|
||||
#ifdef DEBUG_HWBSP
|
||||
static INT32 nobackpoly = 0;
|
||||
static INT32 skipcut = 0;
|
||||
static INT32 totalsubsecpolys = 0;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Polygon fast alloc / free
|
||||
@@ -96,8 +102,8 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
|
||||
double frac;
|
||||
double num;
|
||||
double den;
|
||||
double v1x,v1y,v1dx,v1dy;
|
||||
double v2x,v2y,v2dx,v2dy;
|
||||
double v1x, v1y, v1dx, v1dy;
|
||||
double v2x, v2y, v2dx, v2dy;
|
||||
|
||||
// a segment of a polygon
|
||||
v1x = v1->x;
|
||||
@@ -112,6 +118,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
|
||||
v2dy = bsp->dy;
|
||||
|
||||
den = v2dy*v1dx - v2dx*v1dy;
|
||||
|
||||
if (fabsf((float)den) < 1.0E-36f) // avoid checking exactly for 0.0
|
||||
return NULL; // parallel
|
||||
|
||||
@@ -119,6 +126,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
|
||||
// (do not accept hit with the extensions)
|
||||
num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
|
||||
frac = num / den;
|
||||
|
||||
if (frac < 0.0l || frac > 1.0l)
|
||||
return NULL;
|
||||
|
||||
@@ -128,7 +136,6 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
|
||||
frac = num / den;
|
||||
bspfrac = (float)frac;
|
||||
|
||||
|
||||
// find the interception point along the partition line
|
||||
pt.x = (float)(v2x + v2dx*frac);
|
||||
pt.y = (float)(v2y + v2dy*frac);
|
||||
@@ -136,37 +143,18 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
|
||||
return &pt;
|
||||
}
|
||||
|
||||
#define DIVLINE_VERTEX_DIFF 0.45f
|
||||
|
||||
// if two vertice coords have a x and/or y difference
|
||||
// of less or equal than 1 FRACUNIT, they are considered the same
|
||||
// point. Note: hardcoded value, 1.0f could be anything else.
|
||||
static boolean SameVertice (polyvertex_t *p1, polyvertex_t *p2)
|
||||
{
|
||||
#if 0
|
||||
float diff;
|
||||
diff = p2->x - p1->x;
|
||||
if (diff < -1.5f || diff > 1.5f)
|
||||
if (fabsf( p2->x - p1->x ) > DIVLINE_VERTEX_DIFF)
|
||||
return false;
|
||||
diff = p2->y - p1->y;
|
||||
if (diff < -1.5f || diff > 1.5f)
|
||||
if (fabsf( p2->y - p1->y ) > DIVLINE_VERTEX_DIFF)
|
||||
return false;
|
||||
#elif 0
|
||||
if (p1->x != p2->x)
|
||||
return false;
|
||||
if (p1->y != p2->y)
|
||||
return false;
|
||||
#elif 0
|
||||
if (fabsf( p2->x - p1->x ) > 1.0E-36f )
|
||||
return false;
|
||||
if (fabsf( p2->y - p1->y ) > 1.0E-36f )
|
||||
return false;
|
||||
#else
|
||||
#define DIVLINE_VERTEX_DIFF 0.45f
|
||||
static const float ep = DIVLINE_VERTEX_DIFF;
|
||||
if (fabsf( p2->x - p1->x ) > ep )
|
||||
return false;
|
||||
if (fabsf( p2->y - p1->y ) > ep )
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// p1 and p2 are considered the same vertex
|
||||
return true;
|
||||
}
|
||||
@@ -182,22 +170,23 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
|
||||
poly_t **frontpoly, //return one poly here
|
||||
poly_t **backpoly) //return the other here
|
||||
{
|
||||
INT32 i,j;
|
||||
INT32 i, j;
|
||||
polyvertex_t *pv;
|
||||
|
||||
INT32 ps = -1,pe = -1;
|
||||
INT32 nptfront,nptback;
|
||||
INT32 ps = -1, pe = -1;
|
||||
INT32 nptfront, nptback;
|
||||
polyvertex_t vs = {0,0,0};
|
||||
polyvertex_t ve = {0,0,0};
|
||||
polyvertex_t lastpv = {0,0,0};
|
||||
float fracs = 0.0f,frace = 0.0f; //used to tell which poly is on
|
||||
// the front side of the bsp partition line
|
||||
INT32 psonline = 0, peonline = 0;
|
||||
float fracs = 0.0f, frace = 0.0f; //used to tell which poly is on
|
||||
// the front side of the bsp partition line
|
||||
INT32 psonline = 0, peonline = 0;
|
||||
|
||||
for (i = 0; i < poly->numpts; i++)
|
||||
{
|
||||
j = i + 1;
|
||||
if (j == poly->numpts) j = 0;
|
||||
if (j == poly->numpts)
|
||||
j = 0;
|
||||
|
||||
// start & end points
|
||||
pv = fracdivline(bsp, &poly->pts[i], &poly->pts[j]);
|
||||
@@ -284,7 +273,7 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
|
||||
return;
|
||||
}
|
||||
|
||||
if (pe <= ps)
|
||||
if (UNLIKELY(pe <= ps))
|
||||
I_Error("SplitPoly: invalid splitting line (%d %d)", ps, pe);
|
||||
|
||||
// number of points on each side, _not_ counting those
|
||||
@@ -296,6 +285,7 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
|
||||
*backpoly = HWR_AllocPoly(2 + nptback);
|
||||
else
|
||||
*backpoly = NULL;
|
||||
|
||||
if (nptfront > 0)
|
||||
*frontpoly = HWR_AllocPoly(2 + nptfront);
|
||||
else
|
||||
@@ -308,10 +298,12 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
|
||||
*pv++ = vs;
|
||||
*pv++ = ve;
|
||||
i = pe;
|
||||
|
||||
do
|
||||
{
|
||||
if (++i == poly->numpts)
|
||||
i = 0;
|
||||
|
||||
*pv++ = poly->pts[i];
|
||||
} while (i != ps && --nptfront);
|
||||
}
|
||||
@@ -323,10 +315,12 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
|
||||
*pv++ = ve;
|
||||
*pv++ = vs;
|
||||
i = ps;
|
||||
|
||||
do
|
||||
{
|
||||
if (++i == poly->numpts)
|
||||
i = 0;
|
||||
|
||||
*pv++ = poly->pts[i];
|
||||
} while (i != pe && --nptback);
|
||||
}
|
||||
@@ -353,36 +347,48 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
|
||||
static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
|
||||
{
|
||||
INT32 i, j;
|
||||
|
||||
polyvertex_t *pv;
|
||||
|
||||
INT32 nump = 0, ps, pe;
|
||||
polyvertex_t vs = {0, 0, 0}, ve = {0, 0, 0},
|
||||
p1 = {0, 0, 0}, p2 = {0, 0, 0};
|
||||
p1 = {0, 0, 0}, p2 = {0, 0, 0};
|
||||
float fracs = 0.0f;
|
||||
|
||||
fdivline_t cutseg; // x, y, dx, dy as start of node_t struct
|
||||
|
||||
poly_t *temppoly;
|
||||
|
||||
// for each seg of the subsector
|
||||
for (; count--; lseg++)
|
||||
{
|
||||
//x,y,dx,dy (like a divline)
|
||||
// x, y, dx, dy (like a divline)
|
||||
const line_t *line = lseg->linedef;
|
||||
|
||||
// portal check
|
||||
if (!gl_maphasportals && line->special == PORTALSPECIAL && lseg->side == 0)
|
||||
if (UNLIKELY(!gl_maphasportals && line->special == PORTALSPECIAL && lseg->side == 0))
|
||||
{
|
||||
// Find the other side!
|
||||
INT32 line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, -1);
|
||||
|
||||
if (line == &lines[line2])
|
||||
line2 = P_FindSpecialLineFromTag(PORTALSPECIAL, line->tag, line2);
|
||||
|
||||
if (line2 >= 0) // found it!
|
||||
gl_maphasportals = 1;
|
||||
}
|
||||
|
||||
if (!gl_maphashorizonlines && line->special == HORIZONSPECIAL)
|
||||
gl_maphashorizonlines = true;
|
||||
|
||||
if (line->sidenum[1] != 0xffff)
|
||||
{
|
||||
if (sides[line->sidenum[0]].sector == sides[line->sidenum[1]].sector)
|
||||
{
|
||||
// Segs that are self-ref linedef do not cutout the subsector.
|
||||
#ifdef DEBUG_HWBSP
|
||||
CONS_Debug(DBG_RENDER, "CutOutSubsecPoly: self ref line %i\n", line - lines);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
p1.x = FIXED_TO_FLOAT(lseg->side ? line->v2->x : line->v1->x);
|
||||
p1.y = FIXED_TO_FLOAT(lseg->side ? line->v2->y : line->v1->y);
|
||||
p2.x = FIXED_TO_FLOAT(lseg->side ? line->v1->x : line->v2->x);
|
||||
@@ -396,6 +402,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
|
||||
// see if it cuts the convex poly
|
||||
ps = -1;
|
||||
pe = -1;
|
||||
|
||||
for (i = 0; i < poly->numpts; i++)
|
||||
{
|
||||
j = i + 1;
|
||||
@@ -438,6 +445,7 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
|
||||
ve = vs;
|
||||
vs = *pv;
|
||||
}
|
||||
|
||||
//found 2nd point
|
||||
break;
|
||||
}
|
||||
@@ -451,25 +459,32 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
|
||||
{
|
||||
// generate FRONT poly
|
||||
temppoly = HWR_AllocPoly(nump);
|
||||
|
||||
pv = temppoly->pts;
|
||||
*pv++ = vs;
|
||||
*pv++ = ve;
|
||||
|
||||
do
|
||||
{
|
||||
if (++ps == poly->numpts)
|
||||
ps = 0;
|
||||
*pv++ = poly->pts[ps];
|
||||
} while (ps != pe);
|
||||
|
||||
HWR_FreePoly(poly);
|
||||
poly = temppoly;
|
||||
}
|
||||
//hmmm... maybe we should NOT accept this, but this happens
|
||||
#ifdef DEBUG_HWBSP
|
||||
// hmmm... maybe we should NOT accept this, but this happens
|
||||
// only when the cut is not needed it seems (when the cut
|
||||
// line is aligned to one of the borders of the poly, and
|
||||
// only some times..)
|
||||
else
|
||||
{
|
||||
skipcut++;
|
||||
// I_Error("CutOutPoly: only one point for split line (%d %d) %d", ps, pe, debugpos);
|
||||
I_Error("CutOutPoly: only one point for split line (%d %d) %d", ps, pe, debugpos);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return poly;
|
||||
@@ -492,8 +507,10 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
|
||||
|
||||
if (poly)
|
||||
{
|
||||
poly = CutOutSubsecPoly (lseg,count,poly);
|
||||
poly = CutOutSubsecPoly(lseg,count,poly);
|
||||
#ifdef DEBUG_HWBSP
|
||||
totalsubsecpolys++;
|
||||
#endif
|
||||
//extra data for this subsector
|
||||
extrasubsectors[num].planepoly = poly;
|
||||
}
|
||||
@@ -503,8 +520,8 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
|
||||
// search for the segs source of this divline
|
||||
static inline void SearchDivline(node_t *bsp, fdivline_t *divline)
|
||||
{
|
||||
divline->x = FIXED_TO_FLOAT(bsp->x);
|
||||
divline->y = FIXED_TO_FLOAT(bsp->y);
|
||||
divline->x = FIXED_TO_FLOAT(bsp->x);
|
||||
divline->y = FIXED_TO_FLOAT(bsp->y);
|
||||
divline->dx = FIXED_TO_FLOAT(bsp->dx);
|
||||
divline->dy = FIXED_TO_FLOAT(bsp->dy);
|
||||
}
|
||||
@@ -562,10 +579,12 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
|
||||
if (poly && poly->numpts > 2)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "Adding a new subsector\n");
|
||||
if (addsubsector == numsubsectors + NEWSUBSECTORS)
|
||||
|
||||
if (UNLIKELY(addsubsector == numsubsectors + NEWSUBSECTORS))
|
||||
I_Error("WalkBSPNode: not enough addsubsectors\n");
|
||||
else if (addsubsector > 0x7fff)
|
||||
else if (UNLIKELY(addsubsector > 0x7fff))
|
||||
I_Error("WalkBSPNode: addsubsector > 0x7fff\n");
|
||||
|
||||
*leafnode = (UINT16)((UINT16)addsubsector | NF_SUBSECTOR);
|
||||
extrasubsectors[addsubsector].planepoly = poly;
|
||||
addsubsector++;
|
||||
@@ -587,6 +606,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
M_ClearBox(bbox);
|
||||
poly = extrasubsectors[bspnum & ~NF_SUBSECTOR].planepoly;
|
||||
|
||||
@@ -601,12 +621,14 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
|
||||
SplitPoly(&fdivline, poly, &frontpoly, &backpoly);
|
||||
poly = NULL;
|
||||
|
||||
#ifdef DEBUG_HWBSP
|
||||
//debug
|
||||
if (!backpoly)
|
||||
nobackpoly++;
|
||||
#endif
|
||||
|
||||
// Recursively divide front space.
|
||||
if (frontpoly)
|
||||
if (LIKELY(frontpoly))
|
||||
{
|
||||
WalkBSPNode(bsp->children[0], frontpoly, &bsp->children[0],bsp->bbox[0]);
|
||||
|
||||
@@ -641,53 +663,79 @@ void HWR_FreeExtraSubsectors(void)
|
||||
#define MAXDIST 1.5f
|
||||
// BP: can't move vertex: DON'T change polygon geometry! (convex)
|
||||
//#define MOVEVERTEX
|
||||
static boolean PointInSeg(polyvertex_t *a,polyvertex_t *v1,polyvertex_t *v2)
|
||||
|
||||
// Is vertex va within the seg v1, v2
|
||||
static boolean PointInSeg(polyvertex_t *va,polyvertex_t *v1,polyvertex_t *v2)
|
||||
{
|
||||
register float ax,ay,bx,by,cx,cy,d,norm;
|
||||
register polyvertex_t *p;
|
||||
register float ax, ay, bx, by, cx, cy, d, norm;
|
||||
|
||||
// check bbox of the seg first
|
||||
if (v1->x > v2->x)
|
||||
// check bbox of the seg first (without altering v1, v2)
|
||||
if (v2->x > v1->x)
|
||||
{
|
||||
p = v1;
|
||||
v1 = v2;
|
||||
v2 = p;
|
||||
// check if x within seg box v1..v2
|
||||
if ((va->x + MAXDIST) < v1->x) return false;
|
||||
if ((va->x - MAXDIST) > v2->x) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if x within seg box v2..v1
|
||||
if ((va->x + MAXDIST) < v2->x) return false;
|
||||
if ((va->x - MAXDIST) > v1->x) return false;
|
||||
}
|
||||
|
||||
if (a->x < v1->x-MAXDIST || a->x > v2->x+MAXDIST)
|
||||
return false;
|
||||
|
||||
if (v1->y > v2->y)
|
||||
if (v2->y > v1->y)
|
||||
{
|
||||
p = v1;
|
||||
v1 = v2;
|
||||
v2 = p;
|
||||
// check if x within seg box v1..v2
|
||||
if ((va->y + MAXDIST) < v1->y) return false;
|
||||
if ((va->y - MAXDIST) > v2->y) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if x within seg box v2..v1
|
||||
if ((va->y + MAXDIST) < v2->y) return false;
|
||||
if ((va->y - MAXDIST) > v1->y) return false;
|
||||
}
|
||||
if (a->y < v1->y-MAXDIST || a->y > v2->y+MAXDIST)
|
||||
return false;
|
||||
|
||||
// v1 = origine
|
||||
ax= v2->x-v1->x;
|
||||
ay= v2->y-v1->y;
|
||||
norm = hypotf(ax, ay);
|
||||
// v1 = origin
|
||||
ax = v2->x-v1->x;
|
||||
ay = v2->y-v1->y;
|
||||
norm = hypotf(ax, ay); // length of seg
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
if (norm != 0) // yes, this can be exactly 0
|
||||
#pragma GCC diagnostic pop
|
||||
{
|
||||
ax /= norm;
|
||||
ay /= norm;
|
||||
ay /= norm; // unit vector along seg, v1->v2
|
||||
}
|
||||
bx = a->x-v1->x;
|
||||
by = a->y-v1->y;
|
||||
//d = a.b
|
||||
d =ax*bx+ay*by;
|
||||
|
||||
bx = va->x - v1->x;
|
||||
by = va->y - v1->y; // vector v1->va
|
||||
|
||||
// d = (a DOT b), (product of lengths * cosine( angle ))
|
||||
d = ax*bx+ay*by;
|
||||
|
||||
// bound of the seg
|
||||
if (d < 0 || d > norm)
|
||||
{
|
||||
// Also excludes some va within MAXDIST of v1 or v2
|
||||
return false;
|
||||
//c = d.1a-b
|
||||
}
|
||||
|
||||
// Cross product.
|
||||
if (((by * ax) - (bx * ay)) <= 0)
|
||||
{
|
||||
// The vertex is to the rightside of the seg, so adding
|
||||
// it to the polygon would worsen the crack.
|
||||
return false;
|
||||
}
|
||||
|
||||
// measure the error in vector bx,by as difference squared sum
|
||||
//c= (d * unit_vector_seg) - b
|
||||
cx = ax*d-bx;
|
||||
cy = ay*d-by;
|
||||
|
||||
#ifdef MOVEVERTEX
|
||||
if (cx*cx+cy*cy <= MAXDIST*MAXDIST)
|
||||
{
|
||||
@@ -708,7 +756,7 @@ static INT32 numsplitpoly;
|
||||
static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
|
||||
{
|
||||
poly_t *q;
|
||||
INT32 j,k;
|
||||
INT32 j,k;
|
||||
|
||||
if (bspnum & NF_SUBSECTOR)
|
||||
{
|
||||
@@ -716,47 +764,55 @@ static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
|
||||
{
|
||||
bspnum &= ~NF_SUBSECTOR;
|
||||
q = extrasubsectors[bspnum].planepoly;
|
||||
|
||||
if (poly == q || !q)
|
||||
return;
|
||||
for (j = 0; j < q->numpts; j++)
|
||||
|
||||
const INT32 numpts = q->numpts;
|
||||
|
||||
for (j = 0; j < numpts; j++)
|
||||
{
|
||||
k = j+1;
|
||||
if (k == q->numpts) k = 0;
|
||||
if (k == numpts)
|
||||
k = 0;
|
||||
|
||||
if (!SameVertice(p, &q->pts[j])
|
||||
&& !SameVertice(p, &q->pts[k])
|
||||
&& PointInSeg(p, &q->pts[j],
|
||||
&q->pts[k]))
|
||||
&& PointInSeg(p, &q->pts[j], &q->pts[k]))
|
||||
{
|
||||
poly_t *newpoly = HWR_AllocPoly(q->numpts+1);
|
||||
poly_t *newpoly = HWR_AllocPoly(numpts+1);
|
||||
INT32 n;
|
||||
|
||||
for (n = 0; n <= j; n++)
|
||||
newpoly->pts[n] = q->pts[n];
|
||||
|
||||
newpoly->pts[k] = *p;
|
||||
|
||||
for (n = k+1; n < newpoly->numpts; n++)
|
||||
newpoly->pts[n] = q->pts[n-1];
|
||||
|
||||
numsplitpoly++;
|
||||
extrasubsectors[bspnum].planepoly =
|
||||
newpoly;
|
||||
extrasubsectors[bspnum].planepoly = newpoly;
|
||||
HWR_FreePoly(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXBOTTOM])-MAXDIST <= p->y) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXTOP ])+MAXDIST >= p->y) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXLEFT ])-MAXDIST <= p->x) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXRIGHT ])+MAXDIST >= p->x))
|
||||
SearchSegInBSP(nodes[bspnum].children[0],p,poly);
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXTOP ])+MAXDIST >= p->y) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXLEFT ])-MAXDIST <= p->x) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[0][BOXRIGHT ])+MAXDIST >= p->x))
|
||||
SearchSegInBSP(nodes[bspnum].children[0], p, poly);
|
||||
|
||||
if ((FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXBOTTOM])-MAXDIST <= p->y) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXTOP ])+MAXDIST >= p->y) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXLEFT ])-MAXDIST <= p->x) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXRIGHT ])+MAXDIST >= p->x))
|
||||
SearchSegInBSP(nodes[bspnum].children[1],p,poly);
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXTOP ])+MAXDIST >= p->y) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXLEFT ])-MAXDIST <= p->x) &&
|
||||
(FIXED_TO_FLOAT(nodes[bspnum].bbox[1][BOXRIGHT ])+MAXDIST >= p->x))
|
||||
SearchSegInBSP(nodes[bspnum].children[1], p, poly);
|
||||
}
|
||||
|
||||
// search for T-intersection problem
|
||||
@@ -780,13 +836,18 @@ static INT32 SolveTProblem(void)
|
||||
for (l = 0; l < addsubsector; l++)
|
||||
{
|
||||
p = extrasubsectors[l].planepoly;
|
||||
|
||||
if (!p)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < p->numpts; i++)
|
||||
SearchSegInBSP((INT32)numnodes-1, &p->pts[i], p);
|
||||
}
|
||||
//CONS_Debug(DBG_RENDER, "numsplitpoly %d\n", numsplitpoly);
|
||||
|
||||
#ifdef DEBUG_HWBSP
|
||||
CONS_Debug(DBG_RENDER, "numsplitpoly %d\n", numsplitpoly);
|
||||
#endif
|
||||
|
||||
return numsplitpoly;
|
||||
}
|
||||
|
||||
@@ -826,29 +887,31 @@ static void AdjustSegs(void)
|
||||
if (lseg->polyseg)
|
||||
continue;
|
||||
|
||||
if (p) {
|
||||
for (j = 0; j < p->numpts; j++)
|
||||
for (j = 0; j < p->numpts; j++)
|
||||
{
|
||||
distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x);
|
||||
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y);
|
||||
distv1 = distv1*distv1+tmp*tmp;
|
||||
|
||||
if (distv1 <= nearv1)
|
||||
{
|
||||
distv1 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v1->x);
|
||||
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v1->y);
|
||||
distv1 = distv1*distv1+tmp*tmp;
|
||||
if (distv1 <= nearv1)
|
||||
{
|
||||
v1found = j;
|
||||
nearv1 = distv1;
|
||||
}
|
||||
// the same with v2
|
||||
distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x);
|
||||
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y);
|
||||
distv2 = distv2*distv2+tmp*tmp;
|
||||
if (distv2 <= nearv2)
|
||||
{
|
||||
v2found = j;
|
||||
nearv2 = distv2;
|
||||
}
|
||||
v1found = j;
|
||||
nearv1 = distv1;
|
||||
}
|
||||
|
||||
// the same with v2
|
||||
distv2 = p->pts[j].x - FIXED_TO_FLOAT(lseg->v2->x);
|
||||
tmp = p->pts[j].y - FIXED_TO_FLOAT(lseg->v2->y);
|
||||
distv2 = distv2*distv2+tmp*tmp;
|
||||
|
||||
if (distv2 <= nearv2)
|
||||
{
|
||||
v2found = j;
|
||||
nearv2 = distv2;
|
||||
}
|
||||
}
|
||||
if (p && nearv1 <= NEARDIST*NEARDIST)
|
||||
|
||||
if (nearv1 <= NEARDIST*NEARDIST)
|
||||
// share vertice with segs
|
||||
lseg->pv1 = &(p->pts[v1found]);
|
||||
else
|
||||
@@ -863,7 +926,8 @@ static void AdjustSegs(void)
|
||||
pv->y = FIXED_TO_FLOAT(lseg->v1->y);
|
||||
lseg->pv1 = pv;
|
||||
}
|
||||
if (p && nearv2 <= NEARDIST*NEARDIST)
|
||||
|
||||
if (nearv2 <= NEARDIST*NEARDIST)
|
||||
lseg->pv2 = &(p->pts[v2found]);
|
||||
else
|
||||
{
|
||||
@@ -876,11 +940,15 @@ static void AdjustSegs(void)
|
||||
// recompute length
|
||||
{
|
||||
float x,y;
|
||||
x = ((polyvertex_t *)lseg->pv2)->x - ((polyvertex_t *)lseg->pv1)->x
|
||||
+ FIXED_TO_FLOAT(FRACUNIT/2);
|
||||
y = ((polyvertex_t *)lseg->pv2)->y - ((polyvertex_t *)lseg->pv1)->y
|
||||
+ FIXED_TO_FLOAT(FRACUNIT/2);
|
||||
lseg->flength = (float)hypot(x, y);
|
||||
|
||||
const polyvertex_t *pv1 = (polyvertex_t *)lseg->pv1;
|
||||
const polyvertex_t *pv2 = (polyvertex_t *)lseg->pv2;
|
||||
|
||||
x = pv2->x - pv1->x + 0.5f;
|
||||
y = pv2->y - pv1->y + 0.5f;
|
||||
|
||||
lseg->flength = hypotf(x, y);
|
||||
|
||||
// BP: debug see this kind of segs
|
||||
//if (nearv2 > NEARDIST*NEARDIST || nearv1 > NEARDIST*NEARDIST)
|
||||
// lseg->length = 1;
|
||||
@@ -906,29 +974,29 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
#endif
|
||||
|
||||
// reset the portal flag
|
||||
gl_maphasportals = 0;
|
||||
// reset the portal and horizonline flag
|
||||
gl_maphasportals = gl_maphashorizonlines = 0;
|
||||
|
||||
// find min/max boundaries of map
|
||||
//CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n");
|
||||
#ifdef DEBUG_HWBSP
|
||||
CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n");
|
||||
#endif
|
||||
M_ClearBox(rootbbox);
|
||||
for (i = 0;i < numvertexes; i++)
|
||||
M_AddToBox(rootbbox, vertexes[i].x, vertexes[i].y);
|
||||
|
||||
//CONS_Debug(DBG_RENDER, "Generating subsector polygons... %d subsectors\n", numsubsectors);
|
||||
#ifdef DEBUG_HWBSP
|
||||
CONS_Debug(DBG_RENDER, "Generating subsector polygons... %d subsectors\n", numsubsectors);
|
||||
#endif
|
||||
|
||||
HWR_FreeExtraSubsectors();
|
||||
|
||||
// allocate extra data for each subsector present in map
|
||||
totsubsectors = numsubsectors + NEWSUBSECTORS;
|
||||
extrasubsectors = calloc(totsubsectors, sizeof (*extrasubsectors));
|
||||
if (extrasubsectors == NULL)
|
||||
if (UNLIKELY(extrasubsectors == NULL))
|
||||
I_Error("couldn't malloc extrasubsectors totsubsectors %s\n", sizeu1(totsubsectors));
|
||||
|
||||
// allocate table for back to front drawing of subsectors
|
||||
/*gl_drawsubsectors = (INT16 *)malloc(sizeof (*gl_drawsubsectors) * totsubsectors);
|
||||
if (!gl_drawsubsectors)
|
||||
I_Error("couldn't malloc gl_drawsubsectors\n");*/
|
||||
|
||||
// number of the first new subsector that might be added
|
||||
addsubsector = numsubsectors;
|
||||
|
||||
@@ -952,17 +1020,21 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
|
||||
WalkBSPNode(bspnum, rootp, NULL,rootbbox);
|
||||
|
||||
i = SolveTProblem();
|
||||
//CONS_Debug(DBG_RENDER, "%d point divides a polygon line\n",i);
|
||||
#ifdef DEBUG_HWBSP
|
||||
CONS_Debug(DBG_RENDER, "%d point divides a polygon line\n",i);
|
||||
#endif
|
||||
AdjustSegs();
|
||||
|
||||
#ifdef DEBUG_HWBSP
|
||||
//debug debug..
|
||||
//if (nobackpoly)
|
||||
// CONS_Debug(DBG_RENDER, "no back polygon %u times\n",nobackpoly);
|
||||
if (nobackpoly)
|
||||
CONS_Debug(DBG_RENDER, "no back polygon %u times\n",nobackpoly);
|
||||
//"(should happen only with the deep water trick)"
|
||||
//if (skipcut)
|
||||
// CONS_Debug(DBG_RENDER, "%u cuts were skipped because of only one point\n",skipcut);
|
||||
if (skipcut)
|
||||
CONS_Debug(DBG_RENDER, "%u cuts were skipped because of only one point\n",skipcut);
|
||||
|
||||
//CONS_Debug(DBG_RENDER, "done: %u total subsector convex polygons\n", totalsubsecpolys);
|
||||
CONS_Debug(DBG_RENDER, "done: %u total subsector convex polygons\n", totalsubsecpolys);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif //HWRENDER
|
||||
@@ -38,12 +38,6 @@ INT32 textureformat = GL_TEXFMT_P_8; // use chromakey for hole
|
||||
|
||||
RGBA_t mapPalette[256] = {0}; // the palette for the currently loaded level or menu etc.
|
||||
|
||||
// Returns a pointer to the palette which should be used for caching textures.
|
||||
RGBA_t *HWR_GetTexturePalette(void)
|
||||
{
|
||||
return HWR_ShouldUsePaletteRendering() ? mapPalette : pLocalPalette;
|
||||
}
|
||||
|
||||
static INT32 format2bpp(GLTextureFormat_t format)
|
||||
{
|
||||
switch (format)
|
||||
|
||||
+18
-6
@@ -610,7 +610,7 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
|
||||
}
|
||||
else // Do TRANSMAP** fade.
|
||||
{
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
const RGBA_t *palette = HWR_GetTexturePalette();
|
||||
Surf.PolyColor.rgba = palette[color&0xFF].rgba;
|
||||
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
@@ -794,7 +794,7 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
|
||||
{
|
||||
F2DCoord v1, v2;
|
||||
RGBA_t color_rgba;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
const RGBA_t *palette = HWR_GetTexturePalette();
|
||||
|
||||
color_rgba = palette[color&0xFF];
|
||||
|
||||
@@ -815,7 +815,7 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
float fx, fy, fw, fh, fwait = 0;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
RGBA_t *palette;
|
||||
|
||||
if (wh < 0)
|
||||
return; // consistency w/ software
|
||||
@@ -860,11 +860,13 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
|
||||
|
||||
if (fx >= vid.width || fy >= vid.height)
|
||||
return;
|
||||
|
||||
if (fx < 0)
|
||||
{
|
||||
fw += fx;
|
||||
fx = 0;
|
||||
}
|
||||
|
||||
if (fy < 0)
|
||||
{
|
||||
fh += fy;
|
||||
@@ -873,11 +875,13 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
|
||||
|
||||
if (fw <= 0 || fh <= 0)
|
||||
return;
|
||||
|
||||
if (fx + fw > vid.width)
|
||||
{
|
||||
fwait = fw - (fvw- fx);
|
||||
fw = fvw - fx;
|
||||
}
|
||||
|
||||
if (fy + fh > vid.height)
|
||||
fh = fvh - fy;
|
||||
|
||||
@@ -899,6 +903,8 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
|
||||
v[0].t = v[1].t = 0.0f;
|
||||
v[2].t = v[3].t = 1.0f;
|
||||
|
||||
palette = HWR_GetTexturePalette();
|
||||
|
||||
Surf.PolyColor = palette[color&0xFF];
|
||||
|
||||
GL_DrawPolygon(&Surf, v, 4,
|
||||
@@ -913,7 +919,6 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
float fx, fy, fw, fh;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
|
||||
if (w < 0 || h < 0)
|
||||
return; // consistency w/ software
|
||||
@@ -937,6 +942,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
|
||||
|
||||
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
|
||||
{
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
RGBA_t rgbaColour = palette[color&0xFF];
|
||||
FRGBAFloat clearColour;
|
||||
clearColour.red = (float)rgbaColour.s.red / 255;
|
||||
@@ -967,6 +973,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
|
||||
else if (!(options & V_SNAPTOTOP))
|
||||
fy += (fvh - (FLOATBASEVIDHEIGHT * dupy)) / 2;
|
||||
}
|
||||
|
||||
if (options & V_SPLITSCREEN)
|
||||
fy += (FLOATBASEVIDHEIGHT * dupy)/2;
|
||||
if (options & V_HORZSCREEN)
|
||||
@@ -976,11 +983,13 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
|
||||
|
||||
if (fx >= vid.width || fy >= vid.height)
|
||||
return;
|
||||
|
||||
if (fx < 0)
|
||||
{
|
||||
fw += fx;
|
||||
fx = 0;
|
||||
}
|
||||
|
||||
if (fy < 0)
|
||||
{
|
||||
fh += fy;
|
||||
@@ -989,8 +998,10 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
|
||||
|
||||
if (fw <= 0 || fh <= 0)
|
||||
return;
|
||||
|
||||
if (fx + fw > vid.width)
|
||||
fw = fvw - fx;
|
||||
|
||||
if (fy + fh > vid.height)
|
||||
fh = fvh - fy;
|
||||
|
||||
@@ -1026,12 +1037,13 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
float fx, fy, fw, fh;
|
||||
UINT8 alphalevel = ((color & V_ALPHAMASK) >> V_ALPHASHIFT);
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
|
||||
if (w < 0 || h < 0)
|
||||
return; // consistency w/ software
|
||||
|
||||
const UINT8 alphalevel = ((color & V_ALPHAMASK) >> V_ALPHASHIFT);
|
||||
const RGBA_t *palette = HWR_GetTexturePalette();
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
|
||||
@@ -60,6 +60,9 @@ void HWR_FreeExtraSubsectors(void);
|
||||
// --------
|
||||
// hw_cache.c
|
||||
// --------
|
||||
|
||||
extern RGBA_t mapPalette[256];
|
||||
|
||||
void HWR_InitMapTextures(void);
|
||||
void HWR_LoadMapTextures(size_t pnumtextures);
|
||||
void HWR_FreeMapTextures(void);
|
||||
@@ -85,7 +88,6 @@ void HWR_ClearAllTextures(void);
|
||||
void HWR_FreeColormapCache(void);
|
||||
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
|
||||
|
||||
RGBA_t *HWR_GetTexturePalette(void);
|
||||
void HWR_SetPalette(RGBA_t *palette);
|
||||
void HWR_SetMapPalette(void);
|
||||
UINT32 HWR_CreateLightTable(UINT8 *lighttable);
|
||||
|
||||
+60
-77
@@ -14,8 +14,6 @@
|
||||
#ifdef HWRENDER
|
||||
|
||||
#include <algorithm>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
|
||||
#include "../doomstat.h"
|
||||
#include "../doomdef.h"
|
||||
@@ -99,8 +97,6 @@ line_t *gl_linedef;
|
||||
sector_t *gl_frontsector;
|
||||
sector_t *gl_backsector;
|
||||
|
||||
static boolean gl_maphashorizonlines = false;
|
||||
|
||||
// values for the far clipping plane
|
||||
static constexpr float clipping_distances[] = {1024.0f, 2048.0f, 4096.0f, 6144.0f, 8192.0f, 12288.0f, 16384.0f};
|
||||
// values for bsp culling
|
||||
@@ -132,7 +128,17 @@ static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, b
|
||||
static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
|
||||
static void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
|
||||
|
||||
static void HWR_AddSprites(sector_t *sec);
|
||||
namespace
|
||||
{
|
||||
enum class AddSpritesType
|
||||
{
|
||||
kNoLimitDist,
|
||||
kLimitDist,
|
||||
};
|
||||
|
||||
template<AddSpritesType> static void HWR_AddSprites(sector_t *);
|
||||
}
|
||||
|
||||
static void HWR_ProjectSprite(mobj_t *thing);
|
||||
static void HWR_AddPrecipitationSprites(void);
|
||||
static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
|
||||
@@ -174,7 +180,6 @@ static void CV_glpalettedepth_OnChange(void);
|
||||
static CV_PossibleValue_t glscreentextures_cons_t[] = {{0, "Off"}, {1, "Wipes Only"}, {2, "All"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glfakecontrast_cons_t[] = {{0, "Off"}, {1, "Standard"}, {2, "Smooth"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glshaders_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Ignore custom shaders"}, {0, NULL}};
|
||||
static CV_PossibleValue_t secbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
|
||||
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
|
||||
@@ -219,7 +224,6 @@ consvar_t cv_glslopecontrast = {"gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NU
|
||||
consvar_t cv_glshaders = {"gr_shaders", "On", CV_CALL|CV_SAVE, glshaders_cons_t, CV_glshaders_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_gllightdither = {"gr_lightdithering", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_gllightdithering_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glsecbright = {"secbright", "0", CV_SAVE, secbright_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_glfiltermode = {"gr_filtermode", "Nearest", CV_CALL|CV_SAVE, glfiltermode_cons_t, CV_filtermode_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glanisotropicmode = {"gr_anisotropicmode", "1", CV_CALL|CV_SAVE, glanisotropicmode_cons_t, CV_anisotropic_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -409,6 +413,9 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
||||
tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : GL_DEFAULTMIX;
|
||||
fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG;
|
||||
|
||||
// Clamp the light level, since it can sometimes go out of the 0-255 range from animations
|
||||
light_level = CLAMP(SOFTLIGHT(light_level), cv_secbright.value, 255);
|
||||
|
||||
// Crappy backup coloring if you can't do shaders
|
||||
if (!HWR_UseShader())
|
||||
{
|
||||
@@ -446,9 +453,6 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
||||
poly_color.s.blue = (UINT8)blue;
|
||||
}
|
||||
|
||||
// Clamp the light level, since it can sometimes go out of the 0-255 range from animations
|
||||
light_level = CLAMP(SOFTLIGHT(light_level), cv_glsecbright.value, 255);
|
||||
|
||||
// in palette rendering mode, this is not needed since it properly takes the changes to the palette itself
|
||||
if (!HWR_ShouldUsePaletteRendering())
|
||||
{
|
||||
@@ -704,7 +708,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
||||
for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++,v3d++,pv++)
|
||||
SETUP3DVERT(v3d, pv->x, pv->y);
|
||||
|
||||
lightlevel = HWR_CalcSlopeLight(lightlevel, slope, gl_frontsector, (FOFsector != NULL));
|
||||
if (slope)
|
||||
lightlevel = HWR_CalcSlopeLight(lightlevel, slope, gl_frontsector, (FOFsector != NULL));
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap, P_SectorUsesDirectionalLighting(gl_frontsector));
|
||||
|
||||
@@ -3026,7 +3031,7 @@ static void HWR_Subsector(size_t num)
|
||||
// rendering heights for bottom and top planes
|
||||
// yes there were functions for this stuff, no idea why it wasnt used but bleh
|
||||
bottomCullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy);
|
||||
topCullHeight = P_GetFFloorTopZAt(rover, viewx, viewy);
|
||||
topCullHeight = P_GetFFloorTopZAt(rover, viewx, viewy);
|
||||
|
||||
if (gl_frontsector->cullheight)
|
||||
{
|
||||
@@ -3166,7 +3171,10 @@ doaddline:
|
||||
{
|
||||
// draw sprites first, coz they are clipped to the solidsegs of
|
||||
// subsectors more 'in front'
|
||||
HWR_AddSprites(gl_frontsector);
|
||||
if (cv_drawdist.value || current_bsp_culling_distance)
|
||||
HWR_AddSprites<AddSpritesType::kLimitDist>(gl_frontsector);
|
||||
else
|
||||
HWR_AddSprites<AddSpritesType::kNoLimitDist>(gl_frontsector);
|
||||
|
||||
//Hurdler: at this point validcount must be the same, but is not because
|
||||
// gl_frontsector doesn't point anymore to sub->sector due to
|
||||
@@ -3522,7 +3530,7 @@ static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch, GLPatch_t
|
||||
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
|
||||
static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip, const boolean papersprite)
|
||||
{
|
||||
if (!cv_glspritebillboarding.value || !spr || !spr->mobj || !wallVerts || papersprite)
|
||||
if (!cv_glspritebillboarding.value || papersprite)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -3762,7 +3770,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
continue;
|
||||
|
||||
if (!lightset)
|
||||
lightlevel = static_cast<INT32>(CLAMP(*list[i-1].lightlevel, 0, 255));
|
||||
lightlevel = static_cast<INT32>(*list[i-1].lightlevel);
|
||||
|
||||
colormap = list[i-1].extra_colormap;
|
||||
break;
|
||||
@@ -3781,7 +3789,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
{
|
||||
if (!lightset)
|
||||
{
|
||||
lightlevel = static_cast<INT32>(CLAMP(*list[i].lightlevel, 0, 255));
|
||||
lightlevel = static_cast<INT32>(*list[i].lightlevel);
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
|
||||
}
|
||||
|
||||
@@ -3988,7 +3996,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||
|
||||
if (!lightset)
|
||||
{
|
||||
lightlevel = static_cast<INT32>(CLAMP(sector->lightlevel, 0, 255));
|
||||
lightlevel = static_cast<INT32>(sector->lightlevel);
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
|
||||
}
|
||||
|
||||
@@ -4089,7 +4097,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
|
||||
// colormap test
|
||||
sector_t *sector = sprmo->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
INT32 lightlevel = 255;
|
||||
extracolormap_t *colormap = sector->extra_colormap;
|
||||
|
||||
if (sector->numlights)
|
||||
@@ -4099,7 +4107,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
light = R_GetPlaneLight(sector, sprmo->z + sprmo->height, false); // Always use the light at the top instead of whatever I was doing before
|
||||
|
||||
if (!(sprmo->frame & FF_FULLBRIGHT))
|
||||
lightlevel = static_cast<UINT8>(CLAMP(*sector->lightlist[light].lightlevel, 0, 255));
|
||||
lightlevel = static_cast<INT32>(*sector->lightlist[light].lightlevel);
|
||||
|
||||
if (sector->lightlist[light].extra_colormap)
|
||||
colormap = sector->lightlist[light].extra_colormap;
|
||||
@@ -4107,7 +4115,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
else
|
||||
{
|
||||
if (!(sprmo->frame & FF_FULLBRIGHT))
|
||||
lightlevel = static_cast<UINT8>(CLAMP(sector->lightlevel, 0, 255));
|
||||
lightlevel = static_cast<INT32>(sector->lightlevel);
|
||||
|
||||
if (sector->extra_colormap)
|
||||
colormap = sector->extra_colormap;
|
||||
@@ -4528,6 +4536,10 @@ static void HWR_DrawSprites(void)
|
||||
// HWR_AddSprites
|
||||
// During BSP traversal, this adds sprites by sector.
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
template <AddSpritesType Type>
|
||||
static void HWR_AddSprites(sector_t *sec)
|
||||
{
|
||||
mobj_t *thing;
|
||||
@@ -4543,22 +4555,29 @@ static void HWR_AddSprites(sector_t *sec)
|
||||
// Well, now it will be done.
|
||||
sec->validcount = validcount;
|
||||
|
||||
limit_dist = cv_drawdist.value;
|
||||
|
||||
if (current_bsp_culling_distance)
|
||||
if constexpr (Type == AddSpritesType::kLimitDist)
|
||||
{
|
||||
// Use the smaller setting
|
||||
if (limit_dist)
|
||||
limit_dist = std::min(current_bsp_culling_distance/mapobjectscale, limit_dist);
|
||||
else
|
||||
limit_dist = current_bsp_culling_distance/mapobjectscale;
|
||||
limit_dist = cv_drawdist.value;
|
||||
|
||||
if (current_bsp_culling_distance)
|
||||
{
|
||||
// Use the smaller setting
|
||||
if (limit_dist)
|
||||
limit_dist = std::min(current_bsp_culling_distance/mapobjectscale, limit_dist);
|
||||
else
|
||||
limit_dist = current_bsp_culling_distance/mapobjectscale;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle all things in sector.
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
if (!R_ThingWithinDist(thing, limit_dist))
|
||||
continue;
|
||||
// reduce branching in this rather tight loop
|
||||
if constexpr (Type == AddSpritesType::kLimitDist)
|
||||
{
|
||||
if (!R_ThingWithinDist(thing, limit_dist))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!R_ThingVisible(thing))
|
||||
continue;
|
||||
@@ -4566,6 +4585,7 @@ static void HWR_AddSprites(sector_t *sec)
|
||||
HWR_ProjectSprite(thing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// HWR_AddPrecipitationSprites
|
||||
@@ -4949,24 +4969,24 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
vis->mobj = thing;
|
||||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||
if (UNLIKELY((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1))) // Bosses "flash"
|
||||
{
|
||||
if (vis->mobj->type == MT_CYBRAKDEMON)
|
||||
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_ALLWHITE, SKINCOLOR_NONE, GTC_CACHE));
|
||||
vis->colormap = R_GetTranslationColormap(TC_ALLWHITE, SKINCOLOR_NONE, GTC_CACHE);
|
||||
else if (vis->mobj->type == MT_METALSONIC_BATTLE)
|
||||
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_METALSONIC, SKINCOLOR_NONE, GTC_CACHE));
|
||||
vis->colormap = R_GetTranslationColormap(TC_METALSONIC, SKINCOLOR_NONE, GTC_CACHE);
|
||||
else
|
||||
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_BOSS, SKINCOLOR_NONE, GTC_CACHE));
|
||||
vis->colormap = R_GetTranslationColormap(TC_BOSS, SKINCOLOR_NONE, GTC_CACHE);
|
||||
}
|
||||
else if (thing->color)
|
||||
{
|
||||
// New colormap stuff for skins Tails 06-07-2002
|
||||
if (thing->colorized)
|
||||
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolors_t>(thing->color), GTC_CACHE));
|
||||
vis->colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolors_t>(thing->color), GTC_CACHE);
|
||||
else if (thing->skin && thing->sprite == SPR_PLAY) // This thing is a player!
|
||||
vis->colormap = static_cast<UINT8*>(R_GetLocalTranslationColormap(static_cast<skin_t*>(thing->skin), static_cast<skin_t*>(thing->localskin), static_cast<skincolors_t>(thing->color), GTC_CACHE, thing->skinlocal));
|
||||
vis->colormap = R_GetLocalTranslationColormap(static_cast<skin_t*>(thing->skin), static_cast<skin_t*>(thing->localskin), static_cast<skincolors_t>(thing->color), GTC_CACHE, thing->skinlocal);
|
||||
else
|
||||
vis->colormap = static_cast<UINT8*>(R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolors_t>(thing->color), GTC_CACHE));
|
||||
vis->colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolors_t>(thing->color), GTC_CACHE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5725,42 +5745,7 @@ void HWR_RenderPlayerView(void)
|
||||
HWR_RenderFrame(player, false);
|
||||
}
|
||||
|
||||
// Determine on mapload if current map has any Horizonlines present
|
||||
// so we can avoid rather hot checks in HWR_Subsector
|
||||
static void HWR_CheckForHorizonLines(void)
|
||||
{
|
||||
size_t i;
|
||||
INT32 h;
|
||||
|
||||
gl_maphashorizonlines = false;
|
||||
|
||||
if (!cv_glhorizonlines.value)
|
||||
return;
|
||||
|
||||
for (i = 0; i < numsubsectors; i++)
|
||||
{
|
||||
subsector_t *subsec = &subsectors[i];
|
||||
|
||||
// sector checked already?
|
||||
if (subsec->validcount == validcount)
|
||||
continue;
|
||||
|
||||
subsec->validcount = validcount;
|
||||
|
||||
seg_t *line = &segs[subsec->firstline];
|
||||
|
||||
for (h = 0; h < subsec->numlines; h++, line++)
|
||||
{
|
||||
if (line->linedef->special != HORIZONSPECIAL)
|
||||
continue;
|
||||
|
||||
gl_maphashorizonlines = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_LoadLevel(boolean reloadinggamestate)
|
||||
void HWR_LoadLevel(void)
|
||||
{
|
||||
HWR_CreatePlanePolygons((INT32)numnodes - 1);
|
||||
|
||||
@@ -5768,9 +5753,6 @@ void HWR_LoadLevel(boolean reloadinggamestate)
|
||||
HWR_ClearSkyDome();
|
||||
HWR_BuildSkyDome();
|
||||
|
||||
if (!reloadinggamestate)
|
||||
HWR_CheckForHorizonLines();
|
||||
|
||||
if (HWR_ShouldUsePaletteRendering())
|
||||
HWR_SetMapPalette();
|
||||
}
|
||||
@@ -5844,7 +5826,6 @@ void HWR_AddCommands(void)
|
||||
CV_RegisterVar(&cv_glshaders);
|
||||
|
||||
CV_RegisterVar(&cv_gllightdither);
|
||||
CV_RegisterVar(&cv_glsecbright);
|
||||
|
||||
CV_RegisterVar(&cv_glfiltermode);
|
||||
CV_RegisterVar(&cv_glanisotropicmode);
|
||||
@@ -6040,6 +6021,8 @@ static void HWR_DoPostProcessor(player_t *player)
|
||||
|
||||
Surf.PolyColor.s.alpha = 0xc0; // match software mode
|
||||
|
||||
V_CubeApply(&Surf.PolyColor.s.red, &Surf.PolyColor.s.green, &Surf.PolyColor.s.blue);
|
||||
|
||||
GL_DrawPolygon(&Surf, v, 4, PF_Modulated|PF_Translucent|PF_NoTexture|PF_NoDepthTest);
|
||||
}
|
||||
|
||||
|
||||
@@ -175,6 +175,7 @@ void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom
|
||||
// hw_bsp.c
|
||||
void HWR_CreatePlanePolygons(INT32 bspnum);
|
||||
extern boolean gl_maphasportals;
|
||||
extern boolean gl_maphashorizonlines;
|
||||
|
||||
// Console variables
|
||||
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
|
||||
@@ -198,7 +199,6 @@ extern consvar_t cv_glslopecontrast;
|
||||
extern consvar_t cv_glshaders;
|
||||
|
||||
extern consvar_t cv_gllightdither;
|
||||
extern consvar_t cv_glsecbright;
|
||||
|
||||
extern consvar_t cv_glfiltermode;
|
||||
extern consvar_t cv_glanisotropicmode;
|
||||
@@ -233,6 +233,12 @@ FUNCINLINE static ATTRINLINE boolean HWR_PalRenderFlashpal(void)
|
||||
return (cv_glflashpal.value && HWR_ShouldUsePaletteRendering());
|
||||
}
|
||||
|
||||
// Returns a pointer to the palette which should be used for caching textures.
|
||||
FUNCINLINE static ATTRINLINE RGBA_t *HWR_GetTexturePalette(void)
|
||||
{
|
||||
return HWR_ShouldUsePaletteRendering() ? mapPalette : pLocalPalette;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}// extern "C"
|
||||
#endif
|
||||
|
||||
@@ -695,6 +695,7 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
|
||||
UINT16 w = gpatch->width, h = gpatch->height;
|
||||
UINT32 size = w*h;
|
||||
RGBA_t *image, *blendimage, *cur, blendcolor;
|
||||
RGBA_t *palette = HWR_GetTexturePalette();
|
||||
UINT8 translation[17]; // First the color index
|
||||
UINT8 cutoff[17]; // Brightness cutoff before using the next color
|
||||
UINT8 translen = 0;
|
||||
@@ -702,7 +703,7 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
|
||||
UINT8 colorbrightnesses[17];
|
||||
UINT8 color_match_lookup[256]; // optimization attempt
|
||||
|
||||
blendcolor = V_GetColor(0); // initialize
|
||||
blendcolor = palette[0]; // initialize
|
||||
memset(translation, 0, sizeof(translation));
|
||||
memset(cutoff, 0, sizeof(cutoff));
|
||||
|
||||
@@ -781,7 +782,7 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
|
||||
|
||||
for (i = 0; i < translen; i++) // moved from inside the loop to here
|
||||
{
|
||||
RGBA_t tempc = V_GetColor(translation[i]);
|
||||
RGBA_t tempc = palette[translation[i]];
|
||||
SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison
|
||||
}
|
||||
// generate lookup table for color brightness matching
|
||||
@@ -958,11 +959,11 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi
|
||||
mul = cutoff[firsti] - brightness;
|
||||
}
|
||||
|
||||
blendcolor = V_GetColor(translation[firsti]);
|
||||
blendcolor = palette[translation[firsti]];
|
||||
|
||||
if (mul > 0) // If it's 0, then we only need the first color.
|
||||
{
|
||||
nextcolor = V_GetColor(translation[secondi]);
|
||||
nextcolor = palette[translation[secondi]];
|
||||
|
||||
// Find difference between points
|
||||
r = (INT32)(nextcolor.s.red - blendcolor.s.red);
|
||||
@@ -1150,7 +1151,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
|
||||
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
|
||||
lightlevel = *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (sector->lightlist[light].extra_colormap)
|
||||
colormap = sector->lightlist[light].extra_colormap;
|
||||
@@ -1158,7 +1159,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
else
|
||||
{
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
|
||||
lightlevel = sector->lightlevel;
|
||||
|
||||
if (sector->extra_colormap)
|
||||
colormap = sector->extra_colormap;
|
||||
|
||||
@@ -2031,8 +2031,7 @@ void GL_SetTexture(GLMipmap_t *pTexInfo)
|
||||
{
|
||||
if (pTexInfo->downloaded != tex_downloaded)
|
||||
{
|
||||
if (!currently_batching)
|
||||
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
|
||||
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
|
||||
tex_downloaded = pTexInfo->downloaded;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-3
@@ -110,13 +110,21 @@ HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
|
||||
|
||||
buffer = userdata;
|
||||
|
||||
if (n >= (size_t)( buffer->end - buffer->needle ))
|
||||
while (n >= (size_t)( buffer->end - buffer->needle ))
|
||||
{
|
||||
/* resize to next multiple of buffer size */
|
||||
blocks = ( n / DEFAULT_BUFFER_SIZE + 1 );
|
||||
buffer->end += ( blocks * DEFAULT_BUFFER_SIZE );
|
||||
|
||||
buffer->buffer = realloc(buffer->buffer, buffer->end);
|
||||
void *tmp = realloc(buffer->buffer, buffer->end);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
// not enough memory to read it, bail
|
||||
free(buffer->buffer);
|
||||
buffer->buffer = NULL;
|
||||
return 0;
|
||||
}
|
||||
buffer->buffer = tmp;
|
||||
}
|
||||
|
||||
memcpy(&buffer->buffer[buffer->needle], s, n);
|
||||
@@ -220,7 +228,11 @@ HMS_connect (const char *format, ...)
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, (long)CURL_IPRESOLVE_V4);
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (!M_CheckParm("-ipv6"))
|
||||
#endif
|
||||
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, (long)CURL_IPRESOLVE_V4);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)cv_masterserver_timeout.value);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
|
||||
|
||||
+100
-16
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "m_menu.h" // gametype_cons_t
|
||||
#include "m_cond.h" // emblems
|
||||
#include "m_emotes.h"
|
||||
|
||||
#include "d_clisrv.h"
|
||||
|
||||
@@ -94,6 +95,9 @@ static textinput_t w_chat;
|
||||
static boolean headsupactive = false;
|
||||
boolean hu_showscores; // draw rankings
|
||||
static char hu_tick;
|
||||
static tic_t hu_emoteanim = 0;
|
||||
#define MAXEMOTESUGGESTIONS 8
|
||||
static emote_t *emote_suggestions[MAXEMOTESUGGESTIONS] = {0};
|
||||
|
||||
static huddrawlist_h luahuddrawlist_scores;
|
||||
|
||||
@@ -1106,6 +1110,7 @@ void HU_Ticker(void)
|
||||
return;
|
||||
|
||||
hu_tick++;
|
||||
hu_emoteanim++;
|
||||
hu_tick &= 7; // currently only to blink chat input cursor
|
||||
|
||||
if (PLAYER1INPUTDOWN(gc_scores))
|
||||
@@ -1399,7 +1404,7 @@ boolean HU_Responder(event_t *ev)
|
||||
&& ev->data1 != gamecontrol[0][gc_talkkey][1]))
|
||||
return false;
|
||||
|
||||
M_TextInputHandle(&w_chat, c);
|
||||
M_TextInputHandleEmotes(&w_chat, c, emote_suggestions, MAXEMOTESUGGESTIONS);
|
||||
|
||||
if (c == KEY_ENTER)
|
||||
{
|
||||
@@ -1439,6 +1444,8 @@ boolean HU_Responder(event_t *ev)
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
#define HU_DrawEmote(x, y, emote, flags) M_DrawEmote((x), (y), (emote), hu_emoteanim, (flags))
|
||||
|
||||
// Precompile a wordwrapped string to any given width.
|
||||
// This is a muuuch better method than V_WORDWRAP.
|
||||
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
|
||||
@@ -1450,6 +1457,8 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
size_t slen;
|
||||
char *newstring = Z_StrDup(string);
|
||||
INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
|
||||
slen = strlen(string);
|
||||
x = 0;
|
||||
@@ -1471,7 +1480,12 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
c = toupper(c);
|
||||
c -= HU_FONTSTART;
|
||||
|
||||
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
|
||||
if ((emote = M_VerifyEmote(string+i, &emotelen)))
|
||||
{
|
||||
chw = EMOTEWIDTH;
|
||||
i += emotelen-1; // Will be incremented on next loop iteration, hence -1
|
||||
}
|
||||
else if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
|
||||
{
|
||||
chw = spacewidth;
|
||||
lastusablespace = i;
|
||||
@@ -1493,7 +1507,6 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
|
||||
return newstring;
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
@@ -1526,6 +1539,8 @@ static void HU_drawMiniChat(void)
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
size_t j = 0;
|
||||
INT32 linescount = 0;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
|
||||
while(msg[j]) // iterate through msg
|
||||
{
|
||||
@@ -1550,6 +1565,11 @@ static void HU_drawMiniChat(void)
|
||||
|
||||
++j;
|
||||
}
|
||||
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
|
||||
{
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
j += emotelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
j++;
|
||||
@@ -1595,6 +1615,8 @@ static void HU_drawMiniChat(void)
|
||||
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.
|
||||
UINT8 *colormap = NULL;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
|
||||
while(msg[j]) // iterate through msg
|
||||
{
|
||||
@@ -1621,6 +1643,16 @@ static void HU_drawMiniChat(void)
|
||||
|
||||
++j;
|
||||
}
|
||||
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);
|
||||
|
||||
HU_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag);
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
|
||||
j += emotelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
@@ -1698,6 +1730,9 @@ static void HU_drawChatLog(INT32 offset)
|
||||
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.
|
||||
UINT8 *colormap = NULL;
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
|
||||
while(msg[j]) // iterate through msg
|
||||
{
|
||||
if (msg[j] < HU_FONTSTART) // don't draw
|
||||
@@ -1719,6 +1754,15 @@ static void HU_drawChatLog(INT32 offset)
|
||||
|
||||
++j;
|
||||
}
|
||||
else if ((emote = M_VerifyEmote(msg+j, &emotelen)))
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
{
|
||||
HU_DrawEmote(x+dx+2, y+dy, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
dx += EMOTEWIDTH - charwidth;
|
||||
}
|
||||
j += emotelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
@@ -1844,7 +1888,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+charwidth*w_chat.cursor, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
V_DrawChatCharacter(chatx+2+c, y+1, '_'|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||
|
||||
if (w_chat.select != w_chat.cursor)
|
||||
{
|
||||
@@ -1855,30 +1899,40 @@ static void HU_DrawChat(void)
|
||||
while (w_chat_buf[i])
|
||||
{
|
||||
boolean skippedline = false;
|
||||
if (w_chat.cursor == (i+1))
|
||||
emote_t *emote = NULL;
|
||||
int emotelen = 0;
|
||||
int drawwidth = charwidth; // if we've drawn emote, selection needs to account for that
|
||||
|
||||
if ((emote = M_VerifyEmote(w_chat_buf+i, &emotelen)))
|
||||
{
|
||||
HU_DrawEmote(chatx + c + 2, y-1, emote, V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
c += EMOTEWIDTH - charwidth;
|
||||
i += emotelen-1;
|
||||
drawwidth = EMOTEWIDTH;
|
||||
}
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
++i;
|
||||
|
||||
if (w_chat.cursor == i)
|
||||
{
|
||||
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);
|
||||
|
||||
if (cursorx == chatx+1 && saylen == i) // a weirdo hack
|
||||
if (cursorx == chatx+1 && saylen == i-1) // a weirdo hack
|
||||
{
|
||||
typelines += 1;
|
||||
skippedline = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Hurdler: isn't it better like that?
|
||||
if (w_chat_buf[i] >= HU_FONTSTART)
|
||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat_buf[i] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
||||
|
||||
// Draw selection
|
||||
if (i >= select_start && i < select_end)
|
||||
V_DrawFill(chatx + c + 2, y-1, charwidth, charheight, 103|V_TRANSLUCENT|V_SNAPTOBOTTOM|V_SNAPTOLEFT|t);
|
||||
|
||||
++i;
|
||||
|
||||
c += charwidth;
|
||||
if (c > boxw-(charwidth*2) && !skippedline)
|
||||
{
|
||||
@@ -1888,6 +1942,36 @@ static void HU_DrawChat(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (emote_suggestions[0])
|
||||
{
|
||||
// A bit of copy-paste from /pm code :p
|
||||
INT32 suggesty = chaty - charheight - 1;
|
||||
size_t longest_suggestion_length = 0;
|
||||
|
||||
for (i = 0; i < MAXEMOTESUGGESTIONS && emote_suggestions[i]; ++i)
|
||||
{
|
||||
longest_suggestion_length = max(longest_suggestion_length, strlen(emote_suggestions[i]->name));
|
||||
}
|
||||
|
||||
#ifdef NETSPLITSCREEN
|
||||
if (splitscreen)
|
||||
{
|
||||
suggesty -= BASEVIDHEIGHT/2;
|
||||
if (splitscreen > 1)
|
||||
suggesty += 16;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
suggesty -= (cv_kartspeedometer.value ? 16 : 0);
|
||||
|
||||
for (i = 0; i < MAXEMOTESUGGESTIONS && emote_suggestions[i]; ++i)
|
||||
{
|
||||
V_DrawFillConsoleMap(chatx + boxw + 2, suggesty - (7*i), (longest_suggestion_length+2)*4 + EMOTEWIDTH, 6, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
V_DrawSmallString(chatx + boxw + 4 + EMOTEWIDTH, suggesty - (7*i), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va(":%s:", emote_suggestions[i]->name));
|
||||
HU_DrawEmote(chatx + boxw + 2, suggesty - i*7, emote_suggestions[i], V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
|
||||
+4
-4
@@ -82,6 +82,8 @@ typedef struct
|
||||
char data[MAXPACKETLENGTH];
|
||||
} ATTRPACK doomcom_t;
|
||||
|
||||
#define DOOMCOM_DATA(d) (doomdata_t *)&(d)->data
|
||||
|
||||
#ifdef HOLEPUNCH
|
||||
typedef struct
|
||||
{
|
||||
@@ -89,6 +91,8 @@ typedef struct
|
||||
INT32 addr;
|
||||
INT16 port;
|
||||
} ATTRPACK holepunch_t;
|
||||
|
||||
#define HOLEPUNCH_DATA(d) (holepunch_t *)&(d)->data
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
@@ -97,10 +101,6 @@ typedef struct
|
||||
|
||||
extern doomcom_t *doomcom;
|
||||
|
||||
#ifdef HOLEPUNCH
|
||||
extern holepunch_t *holepunchpacket;
|
||||
#endif
|
||||
|
||||
/** \brief return packet in doomcom struct
|
||||
*/
|
||||
extern boolean (*I_NetGet)(void);
|
||||
|
||||
+4
-3
@@ -43,8 +43,9 @@ extern UINT8 sound_started;
|
||||
|
||||
/** \brief info of samplerate
|
||||
*/
|
||||
#if defined(HAVE_SDL) && SOUND==SOUND_SDL
|
||||
extern consvar_t cv_samplerate;
|
||||
//extern consvar_t cv_rndsoundpitch;
|
||||
#endif
|
||||
|
||||
/** \brief The I_GetSfx function
|
||||
|
||||
@@ -83,7 +84,7 @@ void I_ShutdownSound(void);
|
||||
|
||||
\return sfx handle
|
||||
*/
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel);
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, INT32 channel);
|
||||
|
||||
/** \brief Stops a sound channel.
|
||||
|
||||
@@ -114,7 +115,7 @@ boolean I_SoundIsPlaying(INT32 handle);
|
||||
|
||||
\return void
|
||||
*/
|
||||
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch);
|
||||
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep);
|
||||
|
||||
/** \brief The I_SetSfxVolume function
|
||||
|
||||
|
||||
+77
-21
@@ -371,8 +371,16 @@ static inline void I_UPnP_rem(const char *port, const char * servicetype)
|
||||
|
||||
static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||
{
|
||||
static char s[64]; // 255.255.255.255:65535 or IPv6:65535
|
||||
static char s[64]; // 255.255.255.255:65535 or
|
||||
// [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535
|
||||
|
||||
#ifdef HAVE_NTOP
|
||||
#ifdef HAVE_IPV6
|
||||
int v6 = (sk->any.sa_family == AF_INET6);
|
||||
#else
|
||||
int v6 = 0;
|
||||
#endif
|
||||
|
||||
void *addr;
|
||||
int e = 0; // save error code so it can't be modified later code and avoid calling WSAGetLastError() more then once
|
||||
|
||||
@@ -387,14 +395,20 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||
|
||||
if(addr == NULL)
|
||||
sprintf(s, "No address");
|
||||
else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL)
|
||||
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));
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
|
||||
else if(sk->any.sa_family == AF_INET6)
|
||||
{
|
||||
s[0] = '[';
|
||||
strcat(s, "]");
|
||||
|
||||
if (sk->ip6.sin6_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
|
||||
}
|
||||
#endif
|
||||
else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
|
||||
@@ -486,10 +500,30 @@ static time_t SOCK_GetUnbanTime(size_t ban)
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
static boolean SOCK_cmpipv6(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
||||
{
|
||||
UINT8 bitmask;
|
||||
I_Assert(mask <= 128);
|
||||
if (mask == 0)
|
||||
mask = 128;
|
||||
if (memcmp(&a->ip6.sin6_addr.s6_addr, &b->ip6.sin6_addr.s6_addr, mask / 8) != 0)
|
||||
return false;
|
||||
if (mask % 8 == 0)
|
||||
return true;
|
||||
bitmask = 255 << (mask % 8);
|
||||
return (a->ip6.sin6_addr.s6_addr[mask / 8] & bitmask) == (b->ip6.sin6_addr.s6_addr[mask / 8] & bitmask);
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
||||
{
|
||||
UINT32 bitmask = INADDR_NONE;
|
||||
|
||||
if (a->any.sa_family != b->any.sa_family)
|
||||
return false;
|
||||
|
||||
if (mask && mask < 32)
|
||||
bitmask = htonl((UINT32)(-1) << (32 - mask));
|
||||
|
||||
@@ -498,13 +532,14 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
||||
&& (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port));
|
||||
#ifdef HAVE_IPV6
|
||||
else if (b->any.sa_family == AF_INET6)
|
||||
return memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr))
|
||||
return SOCK_cmpipv6(a, b, mask)
|
||||
&& (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port));
|
||||
#endif
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// This is a hack. For some reason, nodes aren't being freed properly.
|
||||
// This goes through and cleans up what nodes were supposed to be freed.
|
||||
/** \warning This function causes the file downloading to stop if someone joins.
|
||||
@@ -620,6 +655,7 @@ is_external_address (UINT32 p)
|
||||
|
||||
static boolean hole_punch(ssize_t c)
|
||||
{
|
||||
holepunch_t *holepunchpacket = HOLEPUNCH_DATA(doomcom);
|
||||
|
||||
/* See ../doc/Holepunch-Protocol.txt */
|
||||
if (cv_rendezvousserver.string[0] &&
|
||||
@@ -659,6 +695,7 @@ static boolean SOCK_Get(void)
|
||||
fromlen = (socklen_t)sizeof(fromaddress);
|
||||
c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0,
|
||||
(void *)&fromaddress, &fromlen);
|
||||
|
||||
if (c > 0)
|
||||
{
|
||||
#ifdef USE_STUN
|
||||
@@ -868,11 +905,11 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||
unsigned long trueval = true;
|
||||
#endif
|
||||
mysockaddr_t straddr;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
socklen_t len = sizeof(straddr);
|
||||
|
||||
if (s == (SOCKET_TYPE)ERRSOCKET)
|
||||
return (SOCKET_TYPE)ERRSOCKET;
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
{ // Alam_GBC: disable the new UDP connection reset behavior for Win2k and up
|
||||
#ifdef USE_WINSOCK2
|
||||
@@ -892,14 +929,12 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||
}
|
||||
#endif
|
||||
|
||||
straddr.any = *addr;
|
||||
memcpy(&straddr, addr, addrlen);
|
||||
I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr));
|
||||
|
||||
if (family == AF_INET)
|
||||
{
|
||||
mysockaddr_t tmpaddr;
|
||||
tmpaddr.any = *addr ;
|
||||
if (tmpaddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
|
||||
if (straddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
|
||||
{
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
@@ -924,7 +959,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
if (memcmp(addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
|
||||
if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
|
||||
{
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
@@ -939,7 +974,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||
// make it IPv6 ony
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
rc = setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts);
|
||||
rc = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts);
|
||||
if (rc <= -1)
|
||||
{
|
||||
e = errno;
|
||||
@@ -969,7 +1004,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||
|
||||
inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &maddr.ipv6mr_multiaddr);
|
||||
maddr.ipv6mr_interface = 0;
|
||||
rc = setsockopt(s, SOL_SOCKET, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr));
|
||||
rc = setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr));
|
||||
if (rc <= -1)
|
||||
{
|
||||
e = errno;
|
||||
@@ -1032,7 +1067,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
||||
}
|
||||
|
||||
rc = getsockname(s, (struct sockaddr *)&sin, &len);
|
||||
rc = getsockname(s, &straddr.any, &len);
|
||||
if (rc != 0)
|
||||
{
|
||||
e = errno;
|
||||
@@ -1040,7 +1075,14 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||
I_OutputMsg("getsockname failed: #%u, %s\n", e, strerror(e));
|
||||
}
|
||||
else
|
||||
current_port = (UINT16)ntohs(sin.sin_port);
|
||||
{
|
||||
if (family == AF_INET)
|
||||
current_port = (UINT16)ntohs(straddr.ip4.sin_port);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6)
|
||||
current_port = (UINT16)ntohs(straddr.ip6.sin6_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -1121,6 +1163,7 @@ static boolean UDP_Socket(void)
|
||||
I_freeaddrinfo(ai);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (b_ipv6)
|
||||
{
|
||||
@@ -1319,12 +1362,13 @@ static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const
|
||||
{
|
||||
struct my_addrinfo *ai = NULL, *runp, hints;
|
||||
int gaie;
|
||||
size_t i;
|
||||
|
||||
if (!port || !port[0])
|
||||
port = DEFAULTPORT;
|
||||
|
||||
memset (&hints, 0x00, sizeof (hints));
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
@@ -1343,10 +1387,19 @@ static boolean SOCK_GetAddr(struct sockaddr_in *sin, const char *address, const
|
||||
{
|
||||
while (runp != NULL)
|
||||
{
|
||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
break;
|
||||
// test ip address of server
|
||||
for (i = 0; i < mysocketses; ++i)
|
||||
{
|
||||
if (runp->ai_addr->sa_family == myfamily[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
runp = runp->ai_next;
|
||||
if (i >= mysocketses)
|
||||
runp = runp->ai_next;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1390,6 +1443,8 @@ static void rendezvous(int size)
|
||||
|
||||
tic_t tic = I_GetTime();
|
||||
|
||||
holepunch_t *holepunchpacket = HOLEPUNCH_DATA(doomcom);
|
||||
|
||||
if (tic != refreshtic)
|
||||
{
|
||||
if (SOCK_GetAddr(&rzv.ip4, host, (port ? port : "7777"), false))
|
||||
@@ -1415,6 +1470,7 @@ static void rendezvous(int size)
|
||||
static void SOCK_RequestHolePunch(INT32 node)
|
||||
{
|
||||
mysockaddr_t * addr = &clientaddress[node];
|
||||
holepunch_t *holepunchpacket = HOLEPUNCH_DATA(doomcom);
|
||||
|
||||
holepunchpacket->addr = addr->ip4.sin_addr.s_addr;
|
||||
holepunchpacket->port = addr->ip4.sin_port;
|
||||
@@ -1736,7 +1792,7 @@ boolean I_InitTcpNetwork(void)
|
||||
|
||||
// server address only in ip
|
||||
if (serverhostname[0])
|
||||
{
|
||||
{
|
||||
CONS_Printf("SERVERNAME: %s\n", serverhostname);
|
||||
COM_BufAddText("connect \"");
|
||||
COM_BufAddText(serverhostname);
|
||||
|
||||
+1
-1
@@ -2563,7 +2563,7 @@ state_t states[NUMSTATES] =
|
||||
{SPR_KINV, FF_FULLBRIGHT|2, 1, NULL, 0, 0, S_KARTINVULN_LARGE3}, // S_KARTINVULN_LARGE2
|
||||
{SPR_KINV, FF_FULLBRIGHT|5, 1, NULL, 0, 0, S_KARTINVULN_LARGE4}, // S_KARTINVULN_LARGE3
|
||||
{SPR_KINV, FF_FULLBRIGHT|6, 1, NULL, 0, 0, S_KARTINVULN_LARGE5}, // S_KARTINVULN_LARGE4
|
||||
{SPR_KINV, FF_FULLBRIGHT|7, 1, NULL, 0, 0, S_NULL}, // S_KARTINVULN_LARGE5
|
||||
{SPR_KINV, FF_FULLBRIGHT|7, 1, NULL, 0, 0, S_NULL}, // S_KARTINVULN_LARGE5
|
||||
|
||||
{SPR_KINF, FF_FULLBRIGHT|FF_TRANS90, 1, NULL, 0, 0, S_INVULNFLASH2}, // S_INVULNFLASH1
|
||||
{SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, NULL, 0, 0, S_INVULNFLASH3}, // S_INVULNFLASH2
|
||||
|
||||
+25
-36
@@ -1315,14 +1315,6 @@ static void K_drawKartStats(void)
|
||||
|
||||
flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
||||
|
||||
UINT8 splitnum = 0;
|
||||
|
||||
for (; splitnum < MAXSPLITSCREENPLAYERS; ++splitnum)
|
||||
{
|
||||
if (stplyrnum == splitnum)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!LUA_HudEnabled(hud_statdisplay))
|
||||
return;
|
||||
|
||||
@@ -1362,7 +1354,7 @@ static void K_drawKartStats(void)
|
||||
|
||||
// If we are in 2-player splitscreen, for player 1 we move hud to up and remove snapping
|
||||
// to bottom
|
||||
if (splitnum == 0)
|
||||
if (stplyrnum == 0)
|
||||
{
|
||||
y /= 2;
|
||||
flags = V_SNAPTOLEFT;
|
||||
@@ -1375,28 +1367,28 @@ static void K_drawKartStats(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (splitnum == 0 || splitnum == 2) // If we are P1 or P3...
|
||||
if (stplyrnum == 0 || stplyrnum == 2) // If we are P1 or P3...
|
||||
{
|
||||
// ye i just align it to position number lol
|
||||
x = POSI_X + 19;
|
||||
y = POSI_Y - 6;
|
||||
flags = V_SNAPTOLEFT|((splitnum == 2) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
|
||||
flags = V_SNAPTOLEFT|((stplyrnum == 2) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
|
||||
}
|
||||
else // else, that means we're P2 or P4.
|
||||
{
|
||||
x = POSI2_X - 75;
|
||||
y = POSI2_Y - 6;
|
||||
flags = V_SNAPTORIGHT|((splitnum == 3) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
|
||||
flags = V_SNAPTORIGHT|((stplyrnum == 3) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
|
||||
}
|
||||
}
|
||||
|
||||
flags |= V_HUDTRANS;
|
||||
|
||||
skin_t *fakeskin;
|
||||
fakeskin = K_GetPlayerSkin(stplyr);
|
||||
|
||||
if (!splitscreen)
|
||||
{
|
||||
skin_t *fakeskin;
|
||||
fakeskin = K_GetPlayerSkin(stplyr);
|
||||
|
||||
// Skin name
|
||||
if (K_IsHighResolution()) // V_DrawSmallString becomes a mess at low resolutions lel
|
||||
{
|
||||
@@ -1812,6 +1804,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
||||
if (!mode)
|
||||
{
|
||||
splitflags = V_HUDTRANS|K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTORIGHT);
|
||||
|
||||
if (cv_timelimit.value && timelimitintics > 0)
|
||||
{
|
||||
if (drawtime >= timelimitintics)
|
||||
@@ -2175,9 +2168,7 @@ static boolean K_drawKartPositionFaces(void)
|
||||
|
||||
if (!playeringame[rankplayer[i]])
|
||||
continue;
|
||||
if (player->spectator)
|
||||
continue;
|
||||
if (!player->mo)
|
||||
if (player->spectator || !player->mo)
|
||||
continue;
|
||||
|
||||
const UINT8 mocolor = player->mo->color;
|
||||
@@ -2186,9 +2177,10 @@ static boolean K_drawKartPositionFaces(void)
|
||||
|
||||
if (mocolor)
|
||||
{
|
||||
colormap = R_GetTranslationColormap(player->skin, mocolor, GTC_CACHE);
|
||||
if (player->mo->colorized)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, mocolor, GTC_CACHE);
|
||||
else
|
||||
colormap = R_GetTranslationColormap(player->skin, mocolor, GTC_CACHE);
|
||||
|
||||
if (K_UseHighResPortraits())
|
||||
V_DrawSmallMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, R_GetSkinFaceWant(player), colormap);
|
||||
@@ -2217,8 +2209,10 @@ static boolean K_drawKartPositionFaces(void)
|
||||
else
|
||||
{
|
||||
INT32 pos = player->kartstuff[k_position];
|
||||
|
||||
if (pos < 0 || pos > MAXPLAYERS)
|
||||
pos = 0;
|
||||
|
||||
// Draws the little number over the face
|
||||
V_DrawScaledPatch(FACE_X-5, Y+10, V_HUDTRANS|V_SNAPTOLEFT, kp_facenum[pos]);
|
||||
}
|
||||
@@ -2244,6 +2238,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
||||
//I_Assert(scorelines <= 9); -- not today bitch, kart fixed it up
|
||||
|
||||
V_DrawFill(1-duptweak, 26, dupadjust-2, 1, 0); // Draw a horizontal line because it looks nice!
|
||||
|
||||
if (scorelines > 8)
|
||||
{
|
||||
V_DrawFill(160, 26, 1, 147, 0); // Draw a vertical line to separate the two sides.
|
||||
@@ -3168,7 +3163,7 @@ static void K_drawDriftGauge(void)
|
||||
SKINCOLOR_SALMON,
|
||||
};
|
||||
|
||||
static UINT8 driftrainbow[18] = {
|
||||
static const UINT8 driftrainbow[18] = {
|
||||
0, 31, 47, 63, 79, 95, 111, 119, 127, 143, 159, 175, 183, 191, 199, 207, 223, 247
|
||||
};
|
||||
|
||||
@@ -3274,7 +3269,6 @@ skipcrap:
|
||||
}
|
||||
|
||||
// right, also draw a cool number
|
||||
//SG_DrawPaddedNum(v, basex + (dup*32), basey, driftcharge*100 / driftval, 3, "PINGN", V_NOSCALESTART|V_OFFSET|drifttrans, cmap)
|
||||
if (cv_driftgaugestyle.value == 3)
|
||||
V_DrawPaddedTallColorNum(basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap);
|
||||
else
|
||||
@@ -3283,10 +3277,10 @@ skipcrap:
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE);
|
||||
|
||||
if (driftcharge >= driftval*4)
|
||||
cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE);
|
||||
else
|
||||
cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE);
|
||||
|
||||
V_DrawPaddedTallColorNum(basex + (dup*16), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap);
|
||||
}
|
||||
@@ -3305,6 +3299,7 @@ static fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fix
|
||||
range *= gamespeed+1;
|
||||
|
||||
dist = abs(R_PointToDist2(px, py, mx, my));
|
||||
|
||||
if (dist > range)
|
||||
return -BASEVIDWIDTH;
|
||||
|
||||
@@ -3404,17 +3399,14 @@ static void K_drawKartPlayerCheck(void)
|
||||
UINT8 *colormap;
|
||||
INT32 x;
|
||||
|
||||
const INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM);
|
||||
|
||||
if (!stplyr->mo || stplyr->spectator)
|
||||
return;
|
||||
|
||||
if (stplyr->awayviewtics)
|
||||
if (!stplyr->mo || stplyr->spectator || stplyr->awayviewtics)
|
||||
return;
|
||||
|
||||
if (camspin[0])
|
||||
return;
|
||||
|
||||
const INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
UINT8 pnum = 0;
|
||||
@@ -3532,7 +3524,7 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags)
|
||||
skin = K_GetMobjSkin(mo);
|
||||
minimaphead = (skinlocal ? localfacemmapprefix : facemmapprefix)[K_GetMobjSkinNum(skin, skinlocal)];
|
||||
|
||||
amnumxpos = (FixedMul(lerp(mo->old_x, mo->x), minimapinfo.zoom) - minimapinfo.offs_x);
|
||||
amnumxpos = (FixedMul(lerp(mo->old_x, mo->x), minimapinfo.zoom) - minimapinfo.offs_x);
|
||||
amnumypos = -(FixedMul(lerp(mo->old_y, mo->y), minimapinfo.zoom) - minimapinfo.offs_y);
|
||||
|
||||
if (encoremode)
|
||||
@@ -3965,7 +3957,7 @@ static void K_drawBattleFullscreen(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (netgame && !stplyr->spectator && timeinmap > 113) // FREE PLAY?
|
||||
if (netgame && cv_showfreeplay.value && !stplyr->spectator && timeinmap > 113) // FREE PLAY?
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
@@ -4386,10 +4378,6 @@ static void K_drawLapStartAnim(void)
|
||||
void K_drawKartFreePlay(UINT32 flashtime)
|
||||
{
|
||||
// no splitscreen support because it's not FREE PLAY if you have more than one player in-game
|
||||
|
||||
if (!cv_showfreeplay.value)
|
||||
return;
|
||||
|
||||
if ((flashtime % TICRATE) < TICRATE/2)
|
||||
return;
|
||||
|
||||
@@ -4503,6 +4491,7 @@ static void K_drawCheckpointDebugger(void)
|
||||
V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Can finish)", stplyr->starpostnum, numstarposts));
|
||||
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]));
|
||||
}
|
||||
|
||||
@@ -4765,7 +4754,7 @@ void K_drawKartHUD(void)
|
||||
V_DrawScaledPatch(BASEVIDWIDTH/2 - (kp_yougotem->width/2), 32, V_HUDTRANS, kp_yougotem);
|
||||
|
||||
// Draw FREE PLAY.
|
||||
if (isfreeplay && !stplyr->spectator && timeinmap > 113)
|
||||
if (isfreeplay && cv_showfreeplay.value && !stplyr->spectator && timeinmap > 113)
|
||||
{
|
||||
if (LUA_HudEnabled(hud_freeplay))
|
||||
K_drawKartFreePlay(leveltime);
|
||||
|
||||
+92
-42
@@ -551,26 +551,41 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor)
|
||||
*/
|
||||
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, boolean local)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 starttranscolor;
|
||||
INT32 i, starttranscolor;
|
||||
|
||||
// Handle a couple of simple special cases
|
||||
if (skinnum == TC_BOSS
|
||||
|| skinnum == TC_ALLWHITE
|
||||
|| skinnum == TC_METALSONIC
|
||||
|| skinnum == TC_BLINK
|
||||
|| color == SKINCOLOR_NONE)
|
||||
if (skinnum < TC_DEFAULT)
|
||||
{
|
||||
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
|
||||
switch (skinnum)
|
||||
{
|
||||
if (skinnum == TC_ALLWHITE)
|
||||
dest_colormap[i] = 0;
|
||||
else if (skinnum == TC_BLINK)
|
||||
dest_colormap[i] = colortranslations[color][3];
|
||||
else
|
||||
dest_colormap[i] = (UINT8)i;
|
||||
case TC_ALLWHITE:
|
||||
memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8));
|
||||
return;
|
||||
case TC_RAINBOW:
|
||||
if (color >= MAXTRANSLATIONS)
|
||||
I_Error("Invalid skin color #%hu.", (UINT16)color);
|
||||
if (color != SKINCOLOR_NONE)
|
||||
{
|
||||
K_RainbowColormap(dest_colormap, color);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case TC_BLINK:
|
||||
if (color >= MAXTRANSLATIONS)
|
||||
I_Error("Invalid skin color #%hu.", (UINT16)color);
|
||||
if (color != SKINCOLOR_NONE)
|
||||
{
|
||||
memset(dest_colormap, colortranslations[color][3], NUM_PALETTE_ENTRIES * sizeof(UINT8));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
|
||||
dest_colormap[i] = (UINT8)i;
|
||||
|
||||
// White!
|
||||
if (skinnum == TC_BOSS)
|
||||
dest_colormap[31] = 0;
|
||||
@@ -579,14 +594,25 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, bo
|
||||
|
||||
return;
|
||||
}
|
||||
else if (skinnum == TC_RAINBOW)
|
||||
else if (color == SKINCOLOR_NONE)
|
||||
{
|
||||
K_RainbowColormap(dest_colormap, color);
|
||||
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
|
||||
dest_colormap[i] = (UINT8)i;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (color >= MAXTRANSLATIONS)
|
||||
I_Error("Invalid skin color #%hu.", (UINT16)color);
|
||||
|
||||
if (skinnum < 0 && skinnum > TC_DEFAULT)
|
||||
I_Error("Invalid translation colormap index %d.", skinnum);
|
||||
|
||||
starttranscolor = (skinnum != TC_DEFAULT) ? K_GetSkinArray(local)[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR;
|
||||
|
||||
if (starttranscolor >= NUM_PALETTE_ENTRIES)
|
||||
I_Error("Invalid startcolor #%d.", starttranscolor);
|
||||
|
||||
// Fill in the entries of the palette that are fixed
|
||||
for (i = 0; i < starttranscolor; i++)
|
||||
dest_colormap[i] = (UINT8)i;
|
||||
@@ -1586,7 +1612,7 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo)
|
||||
|
||||
// we will do essentially the same checks as above instead of bothering with top/bottom height of the FOF.
|
||||
// Reminder that an FOF's floor is its bottom, silly!
|
||||
if ( ((s2->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == cel) // "floor" check
|
||||
if ( ((s2->flags & SF_FLIPSPECIAL_FLOOR) && mo->z == cel) // "floor" check
|
||||
|| ((s2->flags & SF_FLIPSPECIAL_CEILING) && (mo->z + mo->height) == flr) ) // "ceiling" check.
|
||||
|
||||
for (i = 2; i < 5; i++) // check for sector special
|
||||
@@ -1670,10 +1696,10 @@ static void K_SpawnDashDustRelease(player_t *player)
|
||||
I_Assert(player->mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(player->mo));
|
||||
|
||||
if (!P_IsObjectOnGround(player->mo))
|
||||
if (!player->speed && !player->kartstuff[k_startboost])
|
||||
return;
|
||||
|
||||
if (!player->speed && !player->kartstuff[k_startboost])
|
||||
if (!P_IsObjectOnGround(player->mo))
|
||||
return;
|
||||
|
||||
travelangle = player->mo->angle;
|
||||
@@ -1903,11 +1929,11 @@ static void K_PlayGenericCombatSound(mobj_t *source, mobj_t *other, sfxenum_t sf
|
||||
|
||||
boolean alwaysHear = false;
|
||||
|
||||
if (other != NULL && P_MobjWasRemoved(other) == false && other->player != NULL)
|
||||
if (cv_kartvoices.value && !P_MobjWasRemoved(other) && other->player != NULL)
|
||||
{
|
||||
alwaysHear = P_IsDisplayPlayer(other->player);
|
||||
|
||||
if (cv_kartvoices.value)
|
||||
S_StartSound(alwaysHear ? NULL : source, skin->soundsid[S_sfx[sfx_id].skinsound]);
|
||||
}
|
||||
|
||||
K_RegularVoiceTimers(source->player);
|
||||
}
|
||||
@@ -1929,7 +1955,7 @@ void K_PlayAttackTaunt(mobj_t *source)
|
||||
void K_PlayBoostTaunt(mobj_t *source)
|
||||
{
|
||||
sfxenum_t pick = P_RandomKey(2); // Gotta roll the RNG every time this is called for sync reasons
|
||||
boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]);
|
||||
const boolean tasteful = (!source->player || !source->player->kartstuff[k_tauntvoices]);
|
||||
|
||||
if (cv_kartvoices.value && (tasteful || cv_kartvoices.value == 2))
|
||||
S_StartSound(source, sfx_kbost1+pick);
|
||||
@@ -1942,8 +1968,6 @@ void K_PlayBoostTaunt(mobj_t *source)
|
||||
|
||||
void K_PlayOvertakeSound(mobj_t *source)
|
||||
{
|
||||
boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]);
|
||||
|
||||
if (!G_RaceGametype()) // Only in race
|
||||
return;
|
||||
|
||||
@@ -1951,6 +1975,8 @@ void K_PlayOvertakeSound(mobj_t *source)
|
||||
if (leveltime < starttime+(10*TICRATE))
|
||||
return;
|
||||
|
||||
const boolean tasteful = (!source->player || !source->player->kartstuff[k_voices]);
|
||||
|
||||
if (cv_kartvoices.value && (tasteful || cv_kartvoices.value == 2))
|
||||
S_StartSound(source, sfx_kslow);
|
||||
|
||||
@@ -2186,6 +2212,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
|
||||
|
||||
if (doboostpower)
|
||||
return FixedMul(finalspeed, player->kartstuff[k_boostpower]+player->kartstuff[k_speedboost]);
|
||||
|
||||
return finalspeed;
|
||||
}
|
||||
|
||||
@@ -2222,10 +2249,14 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove
|
||||
{
|
||||
fixed_t accelmax = 4000;
|
||||
fixed_t newspeed, oldspeed, finalspeed;
|
||||
fixed_t p_speed = K_GetKartSpeed(player, true);
|
||||
fixed_t p_accel = K_GetKartAccel(player);
|
||||
fixed_t p_speed, p_accel;
|
||||
|
||||
if (!onground) return 0; // If the player isn't on the ground, there is no change in speed
|
||||
// If the player isn't on the ground, there is no change in speed
|
||||
if (!onground)
|
||||
return 0;
|
||||
|
||||
p_speed = K_GetKartSpeed(player, true);
|
||||
p_accel = K_GetKartAccel(player);
|
||||
|
||||
// ACCELCODE!!!1!11!
|
||||
oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale);
|
||||
@@ -2329,6 +2360,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
|
||||
|
||||
if (P_MobjWasRemoved(player->mo))
|
||||
return; // mobj was removed (in theory that shouldn't happen)
|
||||
|
||||
if (shouldForce == 1)
|
||||
force = true;
|
||||
else if (shouldForce == 2)
|
||||
@@ -2469,8 +2501,10 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor)
|
||||
// PS: Inflictor is unused for all purposes here and is actually only ever relevant to Lua. It may be nil too.
|
||||
boolean force = false; // Used to check if Lua ShouldSquish should get us damaged reguardless of flashtics or heck knows what.
|
||||
UINT8 shouldForce = LUA_HookShouldSquish(player, inflictor, source);
|
||||
|
||||
if (P_MobjWasRemoved(player->mo))
|
||||
return; // mobj was removed (in theory that shouldn't happen)
|
||||
|
||||
if (shouldForce == 1)
|
||||
force = true;
|
||||
else if (shouldForce == 2)
|
||||
@@ -2583,6 +2617,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
|
||||
|
||||
if (P_MobjWasRemoved(player->mo))
|
||||
return; // mobj was removed (in theory that shouldn't happen)
|
||||
|
||||
if (shouldForce == 1)
|
||||
force = true;
|
||||
else if (shouldForce == 2)
|
||||
@@ -2668,6 +2703,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
|
||||
player->powers[pw_flashing] = K_GetKartFlashing(player);
|
||||
|
||||
upgoer = (18*mapobjectscale*P_MobjFlip(player->mo));
|
||||
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
upgoer = (117 * upgoer) / 200;
|
||||
|
||||
@@ -3540,11 +3576,14 @@ void K_SpawnSparkleTrail(mobj_t *mo)
|
||||
fixed_t newz = mo->z + mo->momz + (P_RandomRange(0, mo->height>>FRACBITS)<<FRACBITS);
|
||||
|
||||
sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL);
|
||||
|
||||
K_FlipFromObject(sparkle, mo);
|
||||
|
||||
P_SetTarget(&sparkle->target, mo);
|
||||
|
||||
sparkle->destscale = mo->destscale;
|
||||
P_SetScale(sparkle, mo->scale);
|
||||
|
||||
sparkle->color = mo->color;
|
||||
|
||||
if (cv_playerblendeffects.value && mo->player && K_SpeedLinesShouldBlend(mo->player))
|
||||
@@ -3603,7 +3642,6 @@ void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
|
||||
void K_DriftDustHandling(mobj_t *spawner)
|
||||
{
|
||||
angle_t anglediff;
|
||||
const INT16 spawnrange = spawner->radius>>FRACBITS;
|
||||
|
||||
if (!P_IsObjectOnGround(spawner) || leveltime % 2 != 0)
|
||||
return;
|
||||
@@ -3640,6 +3678,8 @@ void K_DriftDustHandling(mobj_t *spawner)
|
||||
if (anglediff > ANGLE_180)
|
||||
anglediff = InvAngle(anglediff);
|
||||
|
||||
const INT16 spawnrange = spawner->radius>>FRACBITS;
|
||||
|
||||
if (anglediff > ANG10*4) // Trying to turn further than 40 degrees
|
||||
{
|
||||
fixed_t spawnx = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
|
||||
@@ -3899,9 +3939,8 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
|
||||
|
||||
void K_PuntMine(mobj_t *thismine, mobj_t *punter)
|
||||
{
|
||||
angle_t fa = R_PointToAngle2(0, 0, punter->momx, punter->momy) >> ANGLETOFINESHIFT;
|
||||
fixed_t z = 30*mapobjectscale + punter->momz;
|
||||
fixed_t spd;
|
||||
angle_t fa;
|
||||
fixed_t z, spd;
|
||||
mobj_t *mine;
|
||||
|
||||
if (P_MobjWasRemoved(thismine))
|
||||
@@ -3936,6 +3975,9 @@ void K_PuntMine(mobj_t *thismine, mobj_t *punter)
|
||||
if (P_MobjWasRemoved(mine))
|
||||
return;
|
||||
|
||||
fa = R_PointToAngle2(0, 0, punter->momx, punter->momy) >> ANGLETOFINESHIFT;
|
||||
z = 30*mapobjectscale + punter->momz;
|
||||
|
||||
spd = K_GetProjectileSpeed();
|
||||
|
||||
mine->flags |= MF_NOCLIPTHING;
|
||||
@@ -4147,8 +4189,10 @@ static void K_DoShrink(player_t *user)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || !players[i].mo)
|
||||
continue;
|
||||
|
||||
if (&players[i] == user)
|
||||
continue;
|
||||
|
||||
if (players[i].kartstuff[k_position] < user->kartstuff[k_position])
|
||||
{
|
||||
//P_FlashPal(&players[i], PAL_NUKE, 10);
|
||||
@@ -5033,6 +5077,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source)
|
||||
|
||||
// Find the angle, see who's got the best.
|
||||
thisang = actor->angle - R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y);
|
||||
|
||||
if (thisang > ANGLE_180)
|
||||
thisang = InvAngle(thisang);
|
||||
|
||||
@@ -5229,10 +5274,11 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
||||
static void K_UpdateInvincibilitySounds(player_t *player)
|
||||
{
|
||||
INT32 sfxnum = sfx_None;
|
||||
const boolean localplayer = P_IsLocalPlayer(player);
|
||||
|
||||
if (player->mo->health > 0)
|
||||
{
|
||||
const boolean localplayer = P_IsLocalPlayer(player);
|
||||
|
||||
if (player->kartstuff[k_growshrinktimer] > 0 && (!localplayer || cv_growmusic.value == 2)) // Prioritize Grow
|
||||
sfxnum = cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow;
|
||||
else if (player->kartstuff[k_invincibilitytimer] > 0 && (!localplayer || cv_supermusic.value == 2))
|
||||
@@ -5772,7 +5818,7 @@ boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y)
|
||||
static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
|
||||
{
|
||||
INT16 basedrift, driftangle;
|
||||
fixed_t driftweight = player->kartweight*14; // 12
|
||||
fixed_t driftweight;
|
||||
|
||||
// If they aren't drifting or on the ground this doesn't apply
|
||||
if (player->kartstuff[k_drift] == 0 || !P_IsObjectOnGround(player->mo))
|
||||
@@ -5783,6 +5829,8 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
|
||||
return -266*player->kartstuff[k_drift]; // Drift has ended and we are tweaking their angle back a bit
|
||||
}
|
||||
|
||||
driftweight = player->kartweight*14; // 12
|
||||
|
||||
//basedrift = 90*player->kartstuff[k_drift]; // 450
|
||||
//basedrift = 93*player->kartstuff[k_drift] - driftweight*3*player->kartstuff[k_drift]/10; // 447 - 303
|
||||
basedrift = 83*player->kartstuff[k_drift] - (driftweight - 14)*player->kartstuff[k_drift]/5; // 415 - 303
|
||||
@@ -5793,6 +5841,9 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
|
||||
|
||||
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
||||
{
|
||||
fixed_t p_topspeed, p_curspeed, p_maxspeed;
|
||||
fixed_t adjustangle;
|
||||
|
||||
if (player->spectator)
|
||||
return turnvalue;
|
||||
|
||||
@@ -5811,10 +5862,10 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
||||
return turnvalue;
|
||||
}
|
||||
|
||||
fixed_t p_topspeed = K_GetKartSpeed(player, false);
|
||||
fixed_t p_curspeed = min(player->speed, p_topspeed * 2);
|
||||
fixed_t p_maxspeed = p_topspeed * 3;
|
||||
fixed_t adjustangle = FixedDiv((p_maxspeed>>16) - (p_curspeed>>16), (p_maxspeed>>16) + player->kartweight);
|
||||
p_topspeed = K_GetKartSpeed(player, false);
|
||||
p_curspeed = min(player->speed, p_topspeed * 2);
|
||||
p_maxspeed = p_topspeed * 3;
|
||||
adjustangle = FixedDiv((p_maxspeed>>16) - (p_curspeed>>16), (p_maxspeed>>16) + player->kartweight);
|
||||
|
||||
turnvalue = FixedMul(turnvalue, adjustangle); // Weight has a small effect on turning
|
||||
|
||||
@@ -6216,7 +6267,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||
|
||||
K_KartUpdatePosition(player);
|
||||
|
||||
if (!player->exiting)
|
||||
if (LIKELY(!player->exiting))
|
||||
{
|
||||
if (player->kartstuff[k_oldposition] < player->kartstuff[k_position]) // But first, if you lost a place,
|
||||
{
|
||||
@@ -6796,10 +6847,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||
|
||||
K_KartDrift(player, onground);
|
||||
|
||||
if ((!player->kartstuff[k_aizdriftstrat]) || (!P_IsObjectOnGround(player->mo)) || (player->kartstuff[k_drift]))
|
||||
if (player->sliproll && ((!player->kartstuff[k_aizdriftstrat]) || (!P_IsObjectOnGround(player->mo)) || (player->kartstuff[k_drift])))
|
||||
{
|
||||
if (player->sliproll && (player->sliproll > 0))
|
||||
player->sliproll -= (4*ANG1);
|
||||
player->sliproll -= (4*ANG1);
|
||||
}
|
||||
|
||||
// funneh Saturn sprite stuff
|
||||
|
||||
+12
-6
@@ -393,6 +393,16 @@ FUNCINLINE static ATTRINLINE boolean prepare_string_hook
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean prepare_hud_hook
|
||||
(
|
||||
Hook_State * hook,
|
||||
int hook_type
|
||||
){
|
||||
return init_hook_type(hook, 0,
|
||||
hook_type, 0, NULL,
|
||||
hudHookIds[hook_type].numHooks);
|
||||
}
|
||||
|
||||
FUNCINLINE static ATTRINLINE void init_hook_call
|
||||
(
|
||||
Hook_State * hook,
|
||||
@@ -663,20 +673,16 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type)
|
||||
|
||||
void LUA_HookHUD(int hook_type, huddrawlist_h list)
|
||||
{
|
||||
const hook_t * map = &hudHookIds[hook_type];
|
||||
Hook_State hook;
|
||||
if (map->numHooks > 0)
|
||||
if (prepare_hud_hook(&hook, hook_type))
|
||||
{
|
||||
start_hook_stack();
|
||||
begin_hook_values(&hook);
|
||||
|
||||
LUA_SetHudHook(hook_type, list);
|
||||
|
||||
hud_running = true; // local hook
|
||||
hud_interpcounter = 0;
|
||||
hud_interpolate = hud_interpstring = hud_interplatch = false;
|
||||
init_hook_call(&hook, 1, res_hud);
|
||||
call_mapped(&hook, map);
|
||||
call_mapped(&hook, &hudHookIds[hook_type]);
|
||||
lua_settop(gL, 0); // destroy le stack!! >:3
|
||||
hud_running = false;
|
||||
|
||||
|
||||
+3
-3
@@ -1189,7 +1189,7 @@ static void UnArchiveTables(UINT8 **p, boolean network)
|
||||
}
|
||||
}
|
||||
|
||||
void LUA_Step(void)
|
||||
/*void LUA_Step(void)
|
||||
{
|
||||
if (!gL)
|
||||
return;
|
||||
@@ -1200,7 +1200,7 @@ void LUA_Step(void)
|
||||
lua_settop(gL, 0);
|
||||
lua_gc(gL, LUA_GCSTEP, 1);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void LUA_Archive(savebuffer_t *save, boolean network)
|
||||
{
|
||||
@@ -1212,7 +1212,7 @@ void LUA_Archive(savebuffer_t *save, boolean network)
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
|
||||
if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
|
||||
continue;
|
||||
// all players in game will be archived, even if they just add a 0.
|
||||
ArchiveExtVars(&save->p, &players[i], "player");
|
||||
|
||||
+9
-4
@@ -10,6 +10,9 @@
|
||||
/// \file lua_script.h
|
||||
/// \brief Lua scripting basics
|
||||
|
||||
#ifndef LUA_SCRIPT_H
|
||||
#define LUA_SCRIPT_H
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "doomtype.h"
|
||||
#include "d_player.h"
|
||||
@@ -55,7 +58,7 @@ void LUA_InvalidateUserdata(void *data);
|
||||
void LUA_InvalidateLevel(void);
|
||||
void LUA_InvalidateMapthings(void);
|
||||
void LUA_InvalidatePlayer(player_t *player);
|
||||
void LUA_Step(void);
|
||||
//void LUA_Step(void);
|
||||
void LUA_Archive(savebuffer_t *save, boolean network);
|
||||
void LUA_UnArchive(savebuffer_t *save, boolean network);
|
||||
|
||||
@@ -75,7 +78,7 @@ void COM_Lua_f(void);
|
||||
#define LUA_Deprecated(L,this_func,use_instead)\
|
||||
{\
|
||||
static UINT8 seen = 0;\
|
||||
if (!seen) {\
|
||||
if (UNLIKELY(!seen)) {\
|
||||
seen = 1;\
|
||||
CONS_Alert(CONS_WARNING,"\"%s\" is deprecated and will be removed.\nUse \"%s\" instead.\n", this_func, use_instead);\
|
||||
}\
|
||||
@@ -84,7 +87,7 @@ void COM_Lua_f(void);
|
||||
#define LUA_LogDeprecated(L,this_func,use_instead)\
|
||||
{\
|
||||
static UINT8 seen = 0;\
|
||||
if (!seen) {\
|
||||
if (UNLIKELY(!seen)) {\
|
||||
seen = 1;\
|
||||
CON_LogMessage(va("\"%s\" is deprecated and will be removed.\nUse \"%s\" instead.\n", this_func, use_instead));\
|
||||
}\
|
||||
@@ -95,8 +98,10 @@ void COM_Lua_f(void);
|
||||
#define LUA_UsageWarning(L, warningmsg)\
|
||||
{\
|
||||
static UINT8 seen = 0;\
|
||||
if (!seen) {\
|
||||
if (UNLIKELY(!seen)) {\
|
||||
seen = 1;\
|
||||
CONS_Alert(CONS_WARNING,"%s\n", warningmsg);\
|
||||
}\
|
||||
}
|
||||
|
||||
#endif/*LUA_SCRIPT_H*/
|
||||
+51
-34
@@ -20,17 +20,17 @@
|
||||
|
||||
typedef struct aatree_node_s
|
||||
{
|
||||
INT32 level;
|
||||
INT32 key;
|
||||
void* value;
|
||||
INT32 key;
|
||||
INT32 depth;
|
||||
void *value;
|
||||
|
||||
struct aatree_node_s *left, *right;
|
||||
} aatree_node_t;
|
||||
|
||||
struct aatree_s
|
||||
{
|
||||
aatree_node_t *root;
|
||||
UINT32 flags;
|
||||
aatree_node_t *root;
|
||||
UINT32 flags;
|
||||
};
|
||||
|
||||
aatree_t *M_AATreeAlloc(UINT32 flags)
|
||||
@@ -56,40 +56,48 @@ void M_AATreeFree(aatree_t *aatree)
|
||||
Z_Free(aatree);
|
||||
}
|
||||
|
||||
static aatree_node_t *M_AATreeSkew(aatree_node_t *node)
|
||||
static aatree_node_t *M_AATreeRotateRight(aatree_node_t *node)
|
||||
{
|
||||
if (node && node->left && node->left->level == node->level)
|
||||
{
|
||||
// Not allowed: horizontal left-link. Reverse the
|
||||
// horizontal link and hook the orphan back in.
|
||||
aatree_node_t *oldleft = node->left;
|
||||
node->left = oldleft->right;
|
||||
oldleft->right = node;
|
||||
|
||||
return oldleft;
|
||||
}
|
||||
|
||||
// No change needed.
|
||||
return node;
|
||||
aatree_node_t *newnode = node->left;
|
||||
aatree_node_t *tmp = newnode->right;
|
||||
newnode->right = node;
|
||||
node->left = tmp;
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static aatree_node_t *M_AATreeSplit(aatree_node_t *node)
|
||||
static aatree_node_t *M_AATreeRotateLeft(aatree_node_t *node)
|
||||
{
|
||||
if (node && node->right && node->right->right && node->level == node->right->right->level)
|
||||
aatree_node_t *newnode = node->right;
|
||||
aatree_node_t *tmp = newnode->left;
|
||||
newnode->left = node;
|
||||
node->right = tmp;
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static aatree_node_t *M_AATreeRebalance(aatree_node_t *node)
|
||||
{
|
||||
INT32 balance;
|
||||
if (node->left == NULL && node->right == NULL)
|
||||
return node;
|
||||
if (node->left == NULL)
|
||||
balance = -node->right->depth;
|
||||
else if (node->right == NULL)
|
||||
balance = node->left->depth;
|
||||
else
|
||||
{
|
||||
// Not allowed: two consecutive horizontal right-links.
|
||||
// The middle one becomes the new root at this point,
|
||||
// with suitable adjustments below.
|
||||
I_Assert(node->left->key < node->right->key);
|
||||
balance = node->left->depth - node->right->depth;
|
||||
}
|
||||
|
||||
aatree_node_t *oldright = node->right;
|
||||
node->right = oldright->left;
|
||||
oldright->left = node;
|
||||
oldright->level++;
|
||||
|
||||
return oldright;
|
||||
if (balance > 1)
|
||||
{
|
||||
return M_AATreeRotateRight(node);
|
||||
}
|
||||
else if (balance < -1)
|
||||
{
|
||||
return M_AATreeRotateLeft(node);
|
||||
}
|
||||
|
||||
// No change needed.
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -99,11 +107,11 @@ static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32
|
||||
{
|
||||
// Nothing here, so just add where we are
|
||||
node = Z_Malloc(sizeof (aatree_node_t), PU_STATIC, NULL);
|
||||
node->level = 1;
|
||||
node->key = key;
|
||||
if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
|
||||
else node->value = value;
|
||||
node->left = node->right = NULL;
|
||||
node->depth = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -117,8 +125,17 @@ static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32
|
||||
else node->value = value;
|
||||
}
|
||||
|
||||
node = M_AATreeSkew(node);
|
||||
node = M_AATreeSplit(node);
|
||||
node = M_AATreeRebalance(node);
|
||||
if (node->left == NULL && node->right == NULL)
|
||||
node->depth = 1;
|
||||
else if (node->left == NULL)
|
||||
node->depth = node->right->depth + 1;
|
||||
else if (node->right == NULL)
|
||||
node->depth = node->left->depth + 1;
|
||||
else if (node->left->depth > node->right->depth)
|
||||
node->depth = node->left->depth + 1;
|
||||
else
|
||||
node->depth = node->right->depth + 1;
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
#include "m_emotes.h"
|
||||
|
||||
extern "C" {
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "v_video.h"
|
||||
}
|
||||
|
||||
consvar_t cv_emotes = {"emotes", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};;
|
||||
|
||||
static std::map<std::string, emote_t> emotes;
|
||||
|
||||
// TODO - Would be really nice to generalize soc-like file parsing and not reimplement it 100 times :)))))
|
||||
void M_LoadEmotes(UINT16 wadnum)
|
||||
{
|
||||
UINT16 lumpnum = W_CheckNumForNamePwad("EMOTES", wadnum, 0);
|
||||
|
||||
if (lumpnum == INT16_MAX)
|
||||
return;
|
||||
|
||||
char *lump = static_cast<char*>(W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE));
|
||||
size_t size = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
std::istringstream file(std::string(lump, size));
|
||||
std::string line;
|
||||
|
||||
emote_t *emote = nullptr;
|
||||
std::string emote_name;
|
||||
|
||||
// Just smol lambda to remove all the trailing chars we might not want
|
||||
auto trim = [](std::string &str) {
|
||||
str.erase(0, str.find_first_not_of(" \t\n\r\f\v"));
|
||||
str.erase(str.find_last_not_of(" \t\n\r\f\v")+1);
|
||||
};
|
||||
|
||||
int numemotes = 0;
|
||||
int linenum = 0;
|
||||
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
++linenum;
|
||||
|
||||
trim(line);
|
||||
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
size_t split = line.find('=');
|
||||
|
||||
// Didn't find the =, means we're about to parse `Emote <name>`
|
||||
if (split == line.npos)
|
||||
{
|
||||
split = line.find(' ');
|
||||
|
||||
if (split == line.npos)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized line. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strnicmp(line.c_str(), "emote", 5))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: 'Emote' expected. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
emote_name = line.substr(split+1);
|
||||
|
||||
if (emote_name.find_first_of(" \t\n\r\f\v:") != emote_name.npos)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Emote name cannot contain spaces or ':' symbols. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (emote_name.size() > MAXEMOTENAME)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Emote name is too long, truncating. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
emote_name = emote_name.substr(0, MAXEMOTENAME);
|
||||
}
|
||||
|
||||
emote = &emotes[emote_name];
|
||||
strlcpy(emote->name, emote_name.c_str(), MAXEMOTENAME);
|
||||
|
||||
emote->timeperframe = 1;
|
||||
emote->numframes = 0;
|
||||
std::memset(emote->frames, 0, sizeof(emote->frames));
|
||||
|
||||
++numemotes;
|
||||
}
|
||||
else if (emote)
|
||||
{
|
||||
std::string field = line.substr(0, split);
|
||||
std::string value = line.substr(split+1);
|
||||
|
||||
trim(field);
|
||||
trim(value);
|
||||
|
||||
if (stricmp(field.c_str(), "frames") == 0)
|
||||
{
|
||||
UINT8 numframes = 0;
|
||||
|
||||
auto copy_frame = [&] {
|
||||
if (numframes == MAXEMOTEFRAMES)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Too many frames. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t list_split = value.find(',');
|
||||
std::string framelumpname = value.substr(0, list_split);
|
||||
trim(framelumpname);
|
||||
|
||||
if (list_split == value.npos)
|
||||
value = "";
|
||||
else
|
||||
value = value.substr(list_split+1, value.npos);
|
||||
|
||||
// End of list of frames
|
||||
if (framelumpname.size() == 0)
|
||||
return false;
|
||||
|
||||
if (framelumpname.size() > 8)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Frame %d name is too long. (file %s, line %d)", numframes, wadfiles[wadnum]->filename, linenum);
|
||||
framelumpname = framelumpname.substr(0, 8);
|
||||
}
|
||||
|
||||
std::strncpy(emote->frames[numframes], framelumpname.c_str(), framelumpname.size()+1);
|
||||
|
||||
++numframes;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
while (copy_frame()) {}
|
||||
|
||||
if (numframes == 0)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Expected list of frames. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
|
||||
}
|
||||
|
||||
emote->numframes = numframes;
|
||||
}
|
||||
else if (stricmp(field.c_str(), "timeperframe") == 0)
|
||||
{
|
||||
emote->timeperframe = std::stoi(value);
|
||||
|
||||
if (emote->timeperframe <= 0)
|
||||
{
|
||||
emote->timeperframe = 1;
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Bad value for 'timeperframe'. (file %s, line %d)", wadfiles[wadnum]->filename, linenum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized field '%s'. (file %s, line %d)", field.c_str(), wadfiles[wadnum]->filename, linenum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "EMOTES: Unrecognized line. (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum);
|
||||
}
|
||||
}
|
||||
|
||||
CONS_Printf("Added %d emotes\n", numemotes);
|
||||
}
|
||||
|
||||
void M_InitEmotes(void)
|
||||
{
|
||||
UINT16 i;
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
M_LoadEmotes(i);
|
||||
}
|
||||
|
||||
emote_t *M_FindEmote(const char *name, int len, int skip)
|
||||
{
|
||||
if (!cv_emotes.value)
|
||||
return nullptr;
|
||||
|
||||
char query[MAXEMOTENAME+1] = {0};
|
||||
std::strncpy(query, name, std::min(len, MAXEMOTENAME));
|
||||
|
||||
for (auto &pair: emotes)
|
||||
{
|
||||
if (pair.first.rfind(query, 0, std::min(len, MAXEMOTENAME)) != 0)
|
||||
continue;
|
||||
|
||||
if (skip > 0)
|
||||
{
|
||||
--skip;
|
||||
continue;
|
||||
}
|
||||
|
||||
return &pair.second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
emote_t *M_VerifyEmote(const char *name, int *emotelen)
|
||||
{
|
||||
if (*name != ':')
|
||||
return nullptr;
|
||||
|
||||
if (!cv_emotes.value)
|
||||
return nullptr;
|
||||
|
||||
const char *p = name+1; // skip ':'
|
||||
emote_t *match = nullptr;
|
||||
|
||||
while (*p && (p - name) < MAXEMOTENAME)
|
||||
{
|
||||
if (*p == ':')
|
||||
{
|
||||
std::string checkname = std::string(name+1, (p-name)-1);
|
||||
auto it = emotes.find(checkname);
|
||||
|
||||
if (it != emotes.end())
|
||||
match = &it->second;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
if (match && emotelen)
|
||||
*emotelen = p-name+1;
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
void M_DrawEmote(INT32 x, INT32 y, emote_t *emote, tic_t anim, INT32 flags)
|
||||
{
|
||||
if (emote->numframes == 0)
|
||||
return;
|
||||
|
||||
const char *lumpname = emote->frames[(anim/emote->timeperframe) % emote->numframes];
|
||||
patch_t *emotepatch = (patch_t*)W_CachePatchName(lumpname, PU_CACHE);
|
||||
|
||||
const int CHARHEIGHT = 6;
|
||||
|
||||
fixed_t scale = FRACUNIT;
|
||||
|
||||
x *= FRACUNIT;
|
||||
y *= FRACUNIT;
|
||||
|
||||
if (emotepatch->width > EMOTEWIDTH)
|
||||
scale = (FRACUNIT/emotepatch->width)*EMOTEWIDTH;
|
||||
else if (emotepatch->width < EMOTEWIDTH)
|
||||
x += (EMOTEWIDTH-emotepatch->width)*FRACUNIT/2;
|
||||
|
||||
y -= (scale*emotepatch->height-CHARHEIGHT*FRACUNIT)/2;
|
||||
|
||||
V_DrawFixedPatch(x, y, scale, flags, emotepatch, NULL);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef __M_EMOTES__
|
||||
#define __M_EMOTES__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "command.h"
|
||||
|
||||
extern consvar_t cv_emotes;
|
||||
|
||||
#define MAXEMOTENAME 32
|
||||
#define MAXEMOTEFRAMES 32
|
||||
#define EMOTEWIDTH 6
|
||||
|
||||
typedef struct emote_s {
|
||||
char name[MAXEMOTENAME+1];
|
||||
char frames[MAXEMOTEFRAMES][9];
|
||||
UINT8 numframes;
|
||||
tic_t timeperframe;
|
||||
} emote_t;
|
||||
|
||||
// Reads and adds emotes from EMOTES lump, with syntax similar to soc
|
||||
void M_LoadEmotes(UINT16 wadnum);
|
||||
|
||||
// Load emotes from all base wads
|
||||
void M_InitEmotes(void);
|
||||
|
||||
// Finds first matching emote, ignoring first few matches
|
||||
emote_t *M_FindEmote(const char *name, int len, int skips);
|
||||
|
||||
// If first character is not ':', instantly returns null
|
||||
// Starts from ':' character, goes until it finds ':' or end of string
|
||||
// If end of string is found, or closing ':' is found but resulting emote name doesn't exist,
|
||||
// it returns null, otherwise it returns emote and stores into *emotelen how much characters
|
||||
// needs to be skipped to get past emote name
|
||||
emote_t *M_VerifyEmote(const char *name, int *emotelen);
|
||||
|
||||
// Draw the emote, anim should be some kind of timer ticking every game tic
|
||||
// for animated emotes
|
||||
void M_DrawEmote(INT32 x, INT32 y, emote_t *emote, tic_t anim, INT32 flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __M_EMOTES__
|
||||
+288
-3596
File diff suppressed because it is too large.
Load diff
+2946
File diff suppressed because it is too large.
Load diff
@@ -2294,6 +2294,50 @@ void M_MkdirEach(const char *path, int start, int mode)
|
||||
M_MkdirEachUntil(path, start, -1, mode);
|
||||
}
|
||||
|
||||
// Hashes some message using FNV-1a
|
||||
#define FNV1A_OFFSET_BASIS 0x811C9DC5
|
||||
#define FNV1A_PRIME 0x01000193
|
||||
|
||||
UINT32 FNV1a_Hash(const char *message, size_t size)
|
||||
{
|
||||
UINT32 hash = FNV1A_OFFSET_BASIS;
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
hash ^= message[i];
|
||||
hash *= FNV1A_PRIME;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
UINT32 FNV1a_HashString(const char *message)
|
||||
{
|
||||
UINT32 hash = FNV1A_OFFSET_BASIS;
|
||||
|
||||
while (*message)
|
||||
{
|
||||
hash ^= *message;
|
||||
hash *= FNV1A_PRIME;
|
||||
message++;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
UINT32 FNV1a_HashLowercaseString(const char *message)
|
||||
{
|
||||
UINT32 hash = FNV1A_OFFSET_BASIS;
|
||||
|
||||
while (*message)
|
||||
{
|
||||
hash ^= tolower(*message);
|
||||
hash *= FNV1A_PRIME;
|
||||
message++;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@@ -124,6 +124,11 @@ const char * M_Ftrim (double);
|
||||
// counting bits, for weapon ammo code, usually
|
||||
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
|
||||
|
||||
// Hashes some message using FNV-1a
|
||||
UINT32 FNV1a_Hash(const char *message, size_t size);
|
||||
UINT32 FNV1a_HashString(const char *message);
|
||||
UINT32 FNV1a_HashLowercaseString(const char *message);
|
||||
|
||||
#include "w_wad.h"
|
||||
extern char configfile[MAX_WADPATH];
|
||||
|
||||
|
||||
+169
-5
@@ -130,6 +130,82 @@ static void M_TextInputPaste(textinput_t *input)
|
||||
M_TextInputAddString(input, paste);
|
||||
}
|
||||
|
||||
static void M_TextInputLeft(textinput_t *input, boolean emotes)
|
||||
{
|
||||
// Just do it simple way if possible
|
||||
if (!emotes || input->cursor < 2 || input->buffer[input->cursor-1] != ':')
|
||||
{
|
||||
if (input->cursor != 0)
|
||||
--input->cursor;
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise we need to check if we have to skip emote
|
||||
size_t start = input->cursor-2;
|
||||
|
||||
while (input->buffer[start] != ':')
|
||||
{
|
||||
// We reached start of string and didn't find ':' symbol, thats definitely not an emote
|
||||
// so just do it simple way
|
||||
if (start == 0)
|
||||
{
|
||||
M_TextInputLeft(input, false);
|
||||
return;
|
||||
}
|
||||
|
||||
--start;
|
||||
}
|
||||
|
||||
int emotelen = 0;
|
||||
if (M_VerifyEmote(input->buffer+start, &emotelen))
|
||||
input->cursor -= emotelen; // also skip the :
|
||||
else
|
||||
M_TextInputLeft(input, false); // Not a valid emote, do the simple thing
|
||||
}
|
||||
|
||||
static void M_TextInputRight(textinput_t *input, boolean emotes)
|
||||
{
|
||||
// Just do it simple way if possible
|
||||
if (!emotes || input->cursor == input->length || input->buffer[input->cursor] != ':')
|
||||
{
|
||||
if (input->cursor < input->length)
|
||||
++input->cursor;
|
||||
return;
|
||||
}
|
||||
|
||||
int emotelen = 0;
|
||||
if (M_VerifyEmote(input->buffer+input->cursor, &emotelen))
|
||||
input->cursor += emotelen; // Also skip the :
|
||||
else
|
||||
M_TextInputRight(input, false); // Not a valid emote, do the simple thing
|
||||
}
|
||||
|
||||
// Check if we're inside a valid emote
|
||||
static boolean M_TextInputCheckEmote(textinput_t *input)
|
||||
{
|
||||
int start = input->cursor;
|
||||
|
||||
// Definitely not an emote
|
||||
if (start == 0)
|
||||
return false;
|
||||
|
||||
// Might be closing :, need to skip it just in case
|
||||
if (input->buffer[start] == ':')
|
||||
--start;
|
||||
|
||||
while (input->buffer[start] != ':')
|
||||
{
|
||||
// No ':' found, definitely not inside emote
|
||||
if (start == 0)
|
||||
return false;
|
||||
|
||||
--start;
|
||||
}
|
||||
|
||||
// Found what may be emote start, now we can check
|
||||
return M_VerifyEmote(input->buffer+start, NULL) != NULL;
|
||||
}
|
||||
|
||||
void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size)
|
||||
{
|
||||
input->buffer = buffer;
|
||||
@@ -156,7 +232,7 @@ void M_TextInputSetString(textinput_t *input, const char *c)
|
||||
input->cursor = input->select = input->length = strlen(c);
|
||||
}
|
||||
|
||||
boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
static boolean M_TextInputHandleBase(textinput_t *input, INT32 key, boolean emotes)
|
||||
{
|
||||
if (key == KEY_LSHIFT || key == KEY_RSHIFT
|
||||
|| key == KEY_LCTRL || key == KEY_RCTRL
|
||||
@@ -241,16 +317,14 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
|
||||
if (key == KEY_LEFTARROW)
|
||||
{
|
||||
if (input->cursor != 0)
|
||||
--input->cursor;
|
||||
M_TextInputLeft(input, emotes);
|
||||
if (!shiftdown)
|
||||
input->select = input->cursor;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_RIGHTARROW)
|
||||
{
|
||||
if (input->cursor < input->length)
|
||||
++input->cursor;
|
||||
M_TextInputRight(input, emotes);
|
||||
if (!shiftdown)
|
||||
input->select = input->cursor;
|
||||
return true;
|
||||
@@ -320,6 +394,96 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Just an alias, more or less
|
||||
boolean M_TextInputHandle(textinput_t *input, INT32 key)
|
||||
{
|
||||
return M_TextInputHandleBase(input, key, false);
|
||||
}
|
||||
|
||||
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_t *suggestions[], int maxsuggestions)
|
||||
{
|
||||
boolean ret = M_TextInputHandleBase(input, key, true);
|
||||
|
||||
// After this handled key we ended up inside an emote, lets fix that
|
||||
if (M_TextInputCheckEmote(input))
|
||||
M_TextInputToWordEnd(input, !shiftdown);
|
||||
|
||||
// Always clear the first entry
|
||||
suggestions[0] = NULL;
|
||||
|
||||
// For autocomplete
|
||||
int emotestart = 0;
|
||||
|
||||
// Try find suggestions for emote names
|
||||
for (int i = input->cursor-1; i >= 0 && input->cursor-i <= MAXEMOTENAME; --i)
|
||||
{
|
||||
// Space can't be part of emote name
|
||||
if (isspace(input->buffer[i]))
|
||||
break;
|
||||
|
||||
// Found a :, try suggest emotes
|
||||
if (input->buffer[i] == ':')
|
||||
{
|
||||
emotestart = i+1;
|
||||
// ...But only if we typed at least something
|
||||
if ((int)input->cursor-(i-1) < 3)
|
||||
break;
|
||||
|
||||
for (int skip = 0; skip < maxsuggestions; ++skip)
|
||||
{
|
||||
suggestions[skip] = M_FindEmote(input->buffer+i+1, input->cursor-i-1, skip);
|
||||
|
||||
// No more suggestions
|
||||
if (!suggestions[skip])
|
||||
break;
|
||||
}
|
||||
|
||||
// In any case, we found what we wanted, can exit the loop now
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we suggest emotes, try autocomplete
|
||||
if (key == '\t' && suggestions[0])
|
||||
{
|
||||
int pos = (input->cursor-emotestart);
|
||||
boolean autocomplete = true;
|
||||
|
||||
while (autocomplete)
|
||||
{
|
||||
// Check if current character matches for all suggestions
|
||||
char c = suggestions[0]->name[pos];
|
||||
|
||||
// End of string reached
|
||||
if (!c)
|
||||
break;
|
||||
|
||||
for (int i = 1; i < maxsuggestions && suggestions[i]; ++i)
|
||||
{
|
||||
if (suggestions[i]->name[pos] != c)
|
||||
{
|
||||
autocomplete = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++pos;
|
||||
|
||||
if (autocomplete)
|
||||
M_TextInputAddChar(input, c);
|
||||
}
|
||||
|
||||
// This was the only suggestion, finish autocomplete with a ':' and clear suggestions
|
||||
if (maxsuggestions == 1 || !suggestions[1])
|
||||
{
|
||||
M_TextInputAddChar(input, ':');
|
||||
suggestions[0] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH)
|
||||
{
|
||||
if (renderisnewtic)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __M_TEXTINPUT__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "m_emotes.h" // M_VerifyEmote, M_FindEmote
|
||||
|
||||
typedef struct textinput_s {
|
||||
size_t cursor;
|
||||
@@ -22,6 +23,10 @@ void M_TextInputSetString(textinput_t *input, const char *c);
|
||||
|
||||
boolean M_TextInputHandle(textinput_t *input, INT32 key);
|
||||
|
||||
// Does everything same as M_TextInputHandle, but also handles emotes in input string
|
||||
// If currently typing something that looks like an existing emote, return suggestions for it
|
||||
boolean M_TextInputHandleEmotes(textinput_t *input, INT32 key, emote_t *suggestions[], int maxsuggestions);
|
||||
|
||||
#define M_DrawTextInput(x, y, input, flags) M_DrawTextInputScroll((x), (y), (input), (flags), ((input)->buffer_size-1)*8)
|
||||
void M_DrawTextInputScroll(INT32 x, INT32 y, textinput_t *input, INT32 flags, INT32 MAXINPUTWIDTH);
|
||||
|
||||
|
||||
@@ -30,7 +30,11 @@ typedef union
|
||||
typedef struct
|
||||
{
|
||||
msg_header_t header;
|
||||
#ifndef HAVE_IPV6
|
||||
char ip[16];
|
||||
#else
|
||||
char ip[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
|
||||
#endif
|
||||
char port[8];
|
||||
char contact[32];
|
||||
char version[8]; // format is: x.yy.z (like 1.30.2 or 1.31)
|
||||
|
||||
+3
-2
@@ -250,7 +250,7 @@ boolean P_Move(mobj_t *actor, fixed_t speed)
|
||||
I_Assert(movedir < NUMDIRS);
|
||||
|
||||
tryx = actor->x + FixedMul(speed*xspeed[movedir], actor->scale);
|
||||
if (twodlevel || actor->flags2 & MF2_TWOD)
|
||||
if (UNLIKELY(twodlevel || actor->flags2 & MF2_TWOD))
|
||||
tryy = actor->y;
|
||||
else
|
||||
tryy = actor->y + FixedMul(speed*yspeed[movedir], actor->scale);
|
||||
@@ -481,6 +481,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
|
||||
if (!allaround)
|
||||
{
|
||||
an = R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y) - actor->angle;
|
||||
|
||||
if (an > ANGLE_90 && an < ANGLE_270)
|
||||
{
|
||||
dist = P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y);
|
||||
@@ -4387,7 +4388,7 @@ void A_MouseThink(void *thing)
|
||||
|| (actor->eflags & MFE_VERTICALFLIP && actor->z + actor->height == actor->ceilingz))
|
||||
&& !actor->reactiontime)
|
||||
{
|
||||
if (twodlevel || actor->flags2 & MF2_TWOD)
|
||||
if (UNLIKELY(twodlevel || actor->flags2 & MF2_TWOD))
|
||||
{
|
||||
if (P_RandomChance(FRACUNIT/2))
|
||||
actor->angle += ANGLE_180;
|
||||
|
||||
+14
-13
@@ -587,7 +587,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
special->momx = special->momy = special->momz = 0;
|
||||
P_GivePlayerRings(player, 1);
|
||||
|
||||
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING)
|
||||
if (UNLIKELY((maptol & TOL_NIGHTS) && special->type != MT_FLINGRING))
|
||||
P_DoNightsScore(player);
|
||||
break;
|
||||
|
||||
@@ -599,7 +599,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
special->momx = special->momy = 0;
|
||||
P_GivePlayerRings(player, 1);
|
||||
|
||||
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN)
|
||||
if (UNLIKELY((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN))
|
||||
P_DoNightsScore(player);
|
||||
break;
|
||||
case MT_BLUEBALL:
|
||||
@@ -615,7 +615,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
else
|
||||
special->scalespeed = 4*FRACUNIT/5;
|
||||
|
||||
if (maptol & TOL_NIGHTS)
|
||||
if (UNLIKELY(maptol & TOL_NIGHTS))
|
||||
P_DoNightsScore(player);
|
||||
break;
|
||||
case MT_AUTOPICKUP:
|
||||
@@ -832,6 +832,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
if (player->bumpertime < TICRATE/4)
|
||||
{
|
||||
S_StartSound(toucher, special->info->seesound);
|
||||
|
||||
if (player->pflags & PF_NIGHTSMODE)
|
||||
{
|
||||
player->bumpertime = TICRATE/2;
|
||||
@@ -1226,9 +1227,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||
return; // SRB2kart - don't need bubbles mucking with the player
|
||||
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL)
|
||||
return;
|
||||
if (maptol & TOL_NIGHTS)
|
||||
if (UNLIKELY(maptol & TOL_NIGHTS))
|
||||
return;
|
||||
if (mariomode)
|
||||
if (UNLIKELY(mariomode))
|
||||
return;
|
||||
else if (toucher->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
@@ -2352,11 +2353,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
if (player->exiting)
|
||||
return false;
|
||||
|
||||
if (!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS))
|
||||
if (UNLIKELY(!(target->player->pflags & (PF_NIGHTSMODE|PF_NIGHTSFALL)) && (maptol & TOL_NIGHTS)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player->pflags & PF_NIGHTSMODE) // NiGHTS damage handling
|
||||
if (UNLIKELY(player->pflags & PF_NIGHTSMODE)) // NiGHTS damage handling
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
@@ -2601,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 (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 8*FRACUNIT, false);
|
||||
@@ -2625,7 +2626,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
|
||||
ns = FixedMul(momxy, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
ns = momz;
|
||||
@@ -2732,7 +2733,7 @@ void P_PlayerWeaponPanelBurst(player_t *player)
|
||||
ns = FixedMul(3*FRACUNIT, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa),ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 4*FRACUNIT, false);
|
||||
@@ -2816,7 +2817,7 @@ void P_PlayerWeaponAmmoBurst(player_t *player)
|
||||
ns = FixedMul(2*FRACUNIT, mo->scale);
|
||||
mo->momx = FixedMul(FINECOSINE(fa), ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
mo->momy = FixedMul(FINESINE(fa),ns);
|
||||
|
||||
P_SetObjectMomZ(mo, 3*FRACUNIT, false);
|
||||
@@ -2932,7 +2933,7 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss)
|
||||
|
||||
momx = FixedMul(FINECOSINE(fa), ns);
|
||||
|
||||
if (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
momy = FixedMul(FINESINE(fa),ns);
|
||||
else
|
||||
momy = 0;
|
||||
@@ -2989,7 +2990,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 (!(twodlevel || (player->mo->flags2 & MF2_TWOD)))
|
||||
if (LIKELY(!(twodlevel || (player->mo->flags2 & MF2_TWOD))))
|
||||
flag->momy = FixedMul(FINESINE(fa), FixedMul(6*FRACUNIT, player->mo->scale));
|
||||
}
|
||||
|
||||
|
||||
+9
-9
@@ -140,7 +140,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||
if (object->player && object->player->spectator)
|
||||
return false;
|
||||
|
||||
if (object->player && (object->player->pflags & PF_NIGHTSMODE))
|
||||
if (UNLIKELY(object->player && (object->player->pflags & PF_NIGHTSMODE)))
|
||||
{
|
||||
/*Someone want to make these work like bumpers?*/
|
||||
return false;
|
||||
@@ -335,7 +335,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
#ifdef SEENAMES
|
||||
// Do name checks all the way up here
|
||||
// So that NOTHING ELSE can see MT_NAMECHECK because it is client-side.
|
||||
if (tmthing->type == MT_NAMECHECK)
|
||||
if (UNLIKELY(tmthing->type == MT_NAMECHECK))
|
||||
{
|
||||
// Ignore things that aren't players, ignore spectators, ignore yourself.
|
||||
// (also don't bother to check that tmthing->target->player is non-NULL because we're not actually using it here.)
|
||||
@@ -361,8 +361,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||
return true;
|
||||
|
||||
// Don't collide with your buddies while NiGHTS-flying.
|
||||
if (tmthing->player && thing->player && (maptol & TOL_NIGHTS)
|
||||
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE)))
|
||||
if (UNLIKELY(tmthing->player && thing->player && (maptol & TOL_NIGHTS)
|
||||
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))))
|
||||
return true;
|
||||
|
||||
blockdist = thing->radius + tmthing->radius;
|
||||
@@ -2004,7 +2004,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
|
||||
mapcampointer = thiscam;
|
||||
|
||||
if (GETSECSPECIAL(newsec->special, 4) == 12)
|
||||
if (UNLIKELY(GETSECSPECIAL(newsec->special, 4) == 12))
|
||||
{ // Camera noclip on entire sector.
|
||||
tmfloorz = tmdropoffz = thiscam->z;
|
||||
tmceilingz = tmdrpoffceilz = thiscam->z + thiscam->height;
|
||||
@@ -2045,10 +2045,10 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(thiscam, newsec, rover, x, y, NULL);
|
||||
topheight = P_CameraGetFOFTopZ(thiscam, newsec, rover, x, y, NULL);
|
||||
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsec, rover, x, y, NULL);
|
||||
|
||||
delta1 = thiscam->z - (bottomheight
|
||||
@@ -2120,7 +2120,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
|
||||
// We're inside it! Yess...
|
||||
polysec = po->lines[0]->backsector;
|
||||
|
||||
if (GETSECSPECIAL(polysec->special, 4) == 12)
|
||||
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
|
||||
{ // Camera noclip polyobj.
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
continue;
|
||||
@@ -3183,7 +3183,7 @@ stairstep:
|
||||
|
||||
P_HitSlideLine(bestslideline); // clip the moves
|
||||
|
||||
if ((twodlevel || (mo->flags2 & MF2_TWOD)) && mo->player)
|
||||
if (UNLIKELY((twodlevel || (mo->flags2 & MF2_TWOD)) && mo->player))
|
||||
{
|
||||
mo->momx = tmxmove;
|
||||
tmymove = 0;
|
||||
|
||||
+2
-2
@@ -366,7 +366,7 @@ void P_CameraLineOpening(line_t *linedef)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
|
||||
@@ -394,7 +394,7 @@ void P_CameraLineOpening(line_t *linedef)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
|
||||
|
||||
+53
-41
@@ -371,7 +371,7 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state)
|
||||
//
|
||||
boolean P_WeaponOrPanel(mobjtype_t type)
|
||||
{
|
||||
if (type >= MT_BOUNCERING && type <= MT_GRENADEPICKUP)
|
||||
if (UNLIKELY(type >= MT_BOUNCERING && type <= MT_GRENADEPICKUP)) // doubt those get used at all in kart tbh
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -461,6 +461,7 @@ void P_ExplodeMissile(mobj_t *mo)
|
||||
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
return false;
|
||||
|
||||
@@ -891,7 +892,7 @@ static void P_PlayerFlip(mobj_t *mo)
|
||||
G_GhostAddFlip((INT32) (mo->player - players));
|
||||
// Flip aiming to match!
|
||||
|
||||
if (mo->player->pflags & PF_NIGHTSMODE) // NiGHTS doesn't use flipcam
|
||||
if (UNLIKELY(mo->player->pflags & PF_NIGHTSMODE)) // NiGHTS doesn't use flipcam
|
||||
{
|
||||
if (mo->tracer)
|
||||
mo->tracer->eflags ^= MFE_VERTICALFLIP;
|
||||
@@ -989,7 +990,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
||||
//|| (mo->player->charability == CA_FLY && (mo->player->powers[pw_tailsfly]
|
||||
// || (mo->state >= &states[S_PLAY_SPC1] && mo->state <= &states[S_PLAY_SPC4]))))
|
||||
// gravityadd = gravityadd/3; // less gravity while flying/gliding
|
||||
if (mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE))
|
||||
if (UNLIKELY(mo->player->climbing || (mo->player->pflags & PF_NIGHTSMODE)))
|
||||
return 0;
|
||||
|
||||
if (!(mo->flags2 & MF2_OBJECTFLIP) != !(mo->player->powers[pw_gravityboots])) // negated to turn numeric into bool - would be double negated, but not needed if both would be
|
||||
@@ -1607,7 +1608,7 @@ void P_XYMovement(mobj_t *mo)
|
||||
// Check the gravity status.
|
||||
P_CheckGravity(mo, false);
|
||||
|
||||
if (player && !moved && player->pflags & PF_NIGHTSMODE && mo->target)
|
||||
if (UNLIKELY(player && !moved && player->pflags & PF_NIGHTSMODE && mo->target))
|
||||
{
|
||||
angle_t fa;
|
||||
|
||||
@@ -1652,7 +1653,7 @@ void P_XYMovement(mobj_t *mo)
|
||||
if (player && player->homing) // no friction for homing
|
||||
return;
|
||||
|
||||
if (player && player->pflags & PF_NIGHTSMODE)
|
||||
if (UNLIKELY(player && player->pflags & PF_NIGHTSMODE))
|
||||
return; // no friction for NiGHTS players
|
||||
|
||||
if ((mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED)
|
||||
@@ -1735,9 +1736,6 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||
|
||||
if (mo->player && P_CheckSolidLava(mo, rover)) // only the player should be affected
|
||||
;
|
||||
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
|
||||
@@ -1747,6 +1745,10 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
||||
else if (!((rover->flags & FF_BLOCKPLAYER && mo->player) // solid to players?
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mo->player))) // solid to others?
|
||||
continue;
|
||||
|
||||
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||
|
||||
if (rover->flags & FF_QUICKSAND)
|
||||
{
|
||||
switch (motype)
|
||||
@@ -1770,6 +1772,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
|
||||
|
||||
delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2));
|
||||
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
|
||||
|
||||
if (topheight > mo->floorz && abs(delta1) < abs(delta2)
|
||||
&& !(rover->flags & FF_REVERSEPLATFORM)
|
||||
&& ((P_MobjFlip(mo)*mo->momz >= 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference)
|
||||
@@ -1803,7 +1806,7 @@ static void P_AdjustMobjFloorZ_PolyObjs(mobj_t *mo, subsector_t *subsec)
|
||||
|
||||
thingtop = mo->z + mo->height;
|
||||
|
||||
while(po)
|
||||
while (po)
|
||||
{
|
||||
if (!P_MobjInsidePolyobj(po, mo) || !(po->flags & POF_SOLID))
|
||||
{
|
||||
@@ -1855,6 +1858,7 @@ static void P_RingZMovement(mobj_t *mo)
|
||||
mo->momz += mo->pmomz;
|
||||
mo->eflags &= ~MFE_APPLYPMOMZ;
|
||||
}
|
||||
|
||||
mo->z += mo->momz;
|
||||
|
||||
// clip movement
|
||||
@@ -1925,6 +1929,7 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||
mo->momz += mo->pmomz;
|
||||
mo->eflags &= ~MFE_APPLYPMOMZ;
|
||||
}
|
||||
|
||||
mo->z += mo->momz;
|
||||
|
||||
if (mo->standingslope)
|
||||
@@ -2209,7 +2214,7 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||
|| mo->type == MT_CANNONBALLDECOR
|
||||
|| mo->type == MT_FALLINGROCK)
|
||||
{
|
||||
if (maptol & TOL_NIGHTS)
|
||||
if (UNLIKELY(maptol & TOL_NIGHTS))
|
||||
mom.z = -FixedDiv(mom.z, 10*FRACUNIT);
|
||||
else
|
||||
mom.z = -FixedMul(mom.z, FixedDiv(17*FRACUNIT,20*FRACUNIT));
|
||||
@@ -2349,9 +2354,9 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||
mo->momz = -mo->momz;
|
||||
else
|
||||
// Flags bounce
|
||||
if (mo->type == MT_REDFLAG || mo->type == MT_BLUEFLAG)
|
||||
if (UNLIKELY(mo->type == MT_REDFLAG || mo->type == MT_BLUEFLAG))
|
||||
{
|
||||
if (maptol & TOL_NIGHTS)
|
||||
if (UNLIKELY(maptol & TOL_NIGHTS))
|
||||
mo->momz = -FixedDiv(mo->momz, 10*FRACUNIT);
|
||||
else
|
||||
mo->momz = -FixedMul(mo->momz, FixedDiv(17*FRACUNIT,20*FRACUNIT));
|
||||
@@ -2418,7 +2423,7 @@ static void P_PlayerZMovement(mobj_t *mo)
|
||||
else
|
||||
mo->z = mo->floorz;
|
||||
|
||||
if (mo->player->pflags & PF_NIGHTSMODE)
|
||||
if (UNLIKELY(mo->player->pflags & PF_NIGHTSMODE))
|
||||
{
|
||||
// bounce off floor if you were flying towards it
|
||||
if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 0 && mo->player->flyangle < 180)
|
||||
@@ -2608,7 +2613,7 @@ nightsdone:
|
||||
else
|
||||
mo->z = mo->ceilingz - mo->height;
|
||||
|
||||
if (mo->player->pflags & PF_NIGHTSMODE)
|
||||
if (UNLIKELY(mo->player->pflags & PF_NIGHTSMODE))
|
||||
{
|
||||
// bounce off ceiling if you were flying towards it
|
||||
if ((mo->eflags & MFE_VERTICALFLIP && mo->player->flyangle > 180 && mo->player->flyangle <= 359)
|
||||
@@ -2653,7 +2658,7 @@ nightsdone:
|
||||
}
|
||||
|
||||
// hit the ceiling
|
||||
if (mariomode)
|
||||
if (UNLIKELY(mariomode))
|
||||
S_StartSound(mo, sfx_mario1);
|
||||
|
||||
if (!mo->player->climbing)
|
||||
@@ -3114,8 +3119,6 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
|
||||
if (!thiscam || !thiscam->subsector)
|
||||
return false;
|
||||
|
||||
halfheight = thiscam->z + (thiscam->height >> 1);
|
||||
|
||||
// see if we are in water
|
||||
sector = thiscam->subsector->sector;
|
||||
|
||||
@@ -3126,6 +3129,8 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
halfheight = thiscam->z + (thiscam->height >> 1);
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
@@ -3152,8 +3157,6 @@ static boolean P_CameraCheckWater(camera_t *thiscam)
|
||||
if (!thiscam || !thiscam->subsector)
|
||||
return false;
|
||||
|
||||
halfheight = thiscam->z + (thiscam->height >> 1);
|
||||
|
||||
// see if we are in water
|
||||
sector = thiscam->subsector->sector;
|
||||
|
||||
@@ -3161,6 +3164,8 @@ static boolean P_CameraCheckWater(camera_t *thiscam)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
halfheight = thiscam->z + (thiscam->height >> 1);
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS)
|
||||
@@ -3489,15 +3494,18 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(mobj->player->pflags & PF_NIGHTSMODE)) // "jumping" is used for drilling
|
||||
if (LIKELY(!(mobj->player->pflags & PF_NIGHTSMODE))) // "jumping" is used for drilling
|
||||
mobj->player->jumping = 0;
|
||||
|
||||
mobj->player->pflags &= ~PF_JUMPED;
|
||||
|
||||
if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
|
||||
{
|
||||
mobj->player->secondjump = 0;
|
||||
mobj->player->powers[pw_tailsfly] = 0;
|
||||
P_SetPlayerMobjState(mobj, S_KART_WALK1); // SRB2kart - was S_PLAY_RUN1
|
||||
}
|
||||
|
||||
mobj->eflags &= ~MFE_JUSTHITFLOOR;
|
||||
}
|
||||
|
||||
@@ -4185,7 +4193,7 @@ static void P_Boss3Thinker(mobj_t *mobj)
|
||||
// Move Boss4's sectors by delta.
|
||||
static boolean P_Boss4MoveCage(fixed_t delta)
|
||||
{
|
||||
const UINT16 tag = 65534;
|
||||
static const UINT16 tag = 65534;
|
||||
INT32 snum;
|
||||
sector_t *sector;
|
||||
for (snum = sectors[tag%numsectors].firsttag; snum != -1; snum = sector->nexttag)
|
||||
@@ -4234,7 +4242,7 @@ static void P_Boss4PinchSpikeballs(mobj_t *mobj, angle_t angle, fixed_t fz)
|
||||
// Destroy cage FOFs.
|
||||
static void P_Boss4DestroyCage(void)
|
||||
{
|
||||
const UINT16 tag = 65534;
|
||||
static const UINT16 tag = 65534;
|
||||
INT32 snum, next;
|
||||
size_t a;
|
||||
sector_t *sector, *rsec;
|
||||
@@ -5403,8 +5411,6 @@ static void P_GimmeAxisXYPos(mobj_t *closestaxis, degenmobj_t *mobj)
|
||||
|
||||
static void P_MoveHoop(mobj_t *mobj)
|
||||
{
|
||||
const fixed_t fuse = (mobj->fuse*mobj->extravalue2);
|
||||
const angle_t fa = mobj->movedir*(FINEANGLES/mobj->extravalue1);
|
||||
TVector v;
|
||||
TVector *res;
|
||||
fixed_t finalx, finaly, finalz;
|
||||
@@ -5414,6 +5420,9 @@ static void P_MoveHoop(mobj_t *mobj)
|
||||
if (!mobj->target) /// \todo DEBUG ME! Target was P_RemoveMobj'd at some point, and therefore no longer valid!
|
||||
return;
|
||||
|
||||
const fixed_t fuse = (mobj->fuse*mobj->extravalue2);
|
||||
const angle_t fa = mobj->movedir*(FINEANGLES/mobj->extravalue1);
|
||||
|
||||
x = mobj->target->x;
|
||||
y = mobj->target->y;
|
||||
z = mobj->target->z+mobj->target->height/2;
|
||||
@@ -8967,7 +8976,7 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
I_Assert(mobj != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
if (mobj->flags & MF_NOTHINK)
|
||||
if (UNLIKELY(mobj->flags & MF_NOTHINK))
|
||||
return;
|
||||
|
||||
// Remove dead target/tracer.
|
||||
@@ -8986,11 +8995,12 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
|
||||
tmfloorthing = tmhitthing = NULL;
|
||||
|
||||
const sector_t *sec1 = mobj->subsector ? mobj->subsector->sector : NULL;
|
||||
|
||||
// 970 allows ANY mobj to trigger a linedef exec
|
||||
if (UNLIKELY(!mobj->islocal && sec1 && GETSECSPECIAL(sec1->special, 2) == 8)) // BEWARE: islocal does not exist in vanilla
|
||||
{
|
||||
sector_t *sec2;
|
||||
|
||||
sec2 = P_ThingOnSpecial3DFloor(mobj);
|
||||
if (sec2 && GETSECSPECIAL(sec2->special, 2) == 1)
|
||||
P_LinedefExecute(sec2->tag, mobj, sec2);
|
||||
@@ -9054,7 +9064,7 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
if (mobj->flags2 & MF2_FIRING && mobj->target && mobj->health > 0)
|
||||
P_FiringThink(mobj);
|
||||
|
||||
if (mobj->flags & MF_AMBIENT)
|
||||
if (UNLIKELY(mobj->flags & MF_AMBIENT))
|
||||
{
|
||||
if (leveltime % mobj->health)
|
||||
return;
|
||||
@@ -9104,7 +9114,7 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
|| mobj->type == MT_FLINGEMERALD
|
||||
|| mobj->type == MT_BIGTUMBLEWEED
|
||||
|| mobj->type == MT_LITTLETUMBLEWEED
|
||||
|| mobj->type == MT_CANNONBALLDECOR
|
||||
|| mobj->type == MT_CANNONBALLDECOR)
|
||||
|| mobj->type == MT_FALLINGROCK)
|
||||
{
|
||||
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
|
||||
@@ -9195,6 +9205,9 @@ void P_PushableThinker(mobj_t *mobj)
|
||||
I_Assert(mobj != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
if (!mobj)
|
||||
return;
|
||||
|
||||
sec = mobj->subsector->sector;
|
||||
|
||||
if (GETSECSPECIAL(sec->special, 2) == 1 && mobj->z == sec->floorheight)
|
||||
@@ -9211,9 +9224,6 @@ void P_PushableThinker(mobj_t *mobj)
|
||||
if (mobj->flags & MF_PUSHABLE && !(mobj->momx || mobj->momy))
|
||||
P_TryMove(mobj, mobj->x, mobj->y, true);
|
||||
|
||||
if (!mobj)
|
||||
return;
|
||||
|
||||
if (mobj->fuse == 1) // it would explode in the MobjThinker code
|
||||
{
|
||||
mobj_t *spawnmo;
|
||||
@@ -9982,6 +9992,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
||||
else
|
||||
{
|
||||
const INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1);
|
||||
|
||||
if (special == 7 || special == 6 || mobj->subsector->sector->floorpic == skyflatnum)
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
}
|
||||
@@ -10313,9 +10324,11 @@ void P_PrecipitationEffects(void)
|
||||
P_SpawnLightningFlash(ss); // Spawn a quick flash thinker
|
||||
}
|
||||
|
||||
const mobj_t *pmo = players[displayplayers[0]].mo;
|
||||
|
||||
// Local effects from here on out!
|
||||
// If we're not in game fully yet, we don't worry about them.
|
||||
if (!playeringame[displayplayers[0]] || !players[displayplayers[0]].mo)
|
||||
if (!playeringame[displayplayers[0]] || !pmo)
|
||||
return;
|
||||
|
||||
if (sound_disabled)
|
||||
@@ -10324,7 +10337,7 @@ void P_PrecipitationEffects(void)
|
||||
if (!sounds_rain && !sounds_thunder)
|
||||
return; // no need to calculate volume at ALL
|
||||
|
||||
if (players[displayplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum)
|
||||
if (pmo->subsector->sector->ceilingpic == skyflatnum)
|
||||
volume = 255; // Sky above? We get it full blast.
|
||||
else
|
||||
{
|
||||
@@ -10335,7 +10348,7 @@ void P_PrecipitationEffects(void)
|
||||
// Essentially check in a 1024 unit radius of the player for an outdoor area.
|
||||
#define RADIUSSTEP (64*FRACUNIT)
|
||||
#define SEARCHRADIUS (16*RADIUSSTEP)
|
||||
yl = yh = players[displayplayers[0]].mo->y;
|
||||
yl = yh = pmo->y;
|
||||
yl -= SEARCHRADIUS;
|
||||
while (yl < INT32_MIN)
|
||||
yl += RADIUSSTEP;
|
||||
@@ -10343,7 +10356,7 @@ void P_PrecipitationEffects(void)
|
||||
while (yh > INT32_MAX)
|
||||
yh -= RADIUSSTEP;
|
||||
|
||||
xl = xh = players[displayplayers[0]].mo->x;
|
||||
xl = xh = pmo->x;
|
||||
xl -= SEARCHRADIUS;
|
||||
while (xl < INT32_MIN)
|
||||
xl += RADIUSSTEP;
|
||||
@@ -10359,20 +10372,19 @@ void P_PrecipitationEffects(void)
|
||||
if (R_PointInSubsectorFast((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors!
|
||||
continue;
|
||||
|
||||
newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0);
|
||||
newdist = S_CalculateSoundDistance(pmo->x, pmo->y, 0, (fixed_t)x, (fixed_t)y, 0);
|
||||
|
||||
if (newdist < closedist)
|
||||
closedist = newdist;
|
||||
}
|
||||
|
||||
volume = 255 - (closedist>>(FRACBITS+2));
|
||||
volume = CLAMP(volume, 0, 255);
|
||||
}
|
||||
#undef RADIUSSTEP
|
||||
|
||||
volume = CLAMP(volume, 0, 255);
|
||||
|
||||
if (sounds_rain)
|
||||
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume);
|
||||
S_StartSoundAtVolume(pmo, sfx_rainin, volume);
|
||||
|
||||
if (!sounds_thunder)
|
||||
return;
|
||||
@@ -10380,7 +10392,7 @@ void P_PrecipitationEffects(void)
|
||||
if (effects_lightning && lightningStrike && volume)
|
||||
{
|
||||
// Large, close thunder sounds to go with our lightning.
|
||||
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_litng1 + M_RandomKey(4), volume);
|
||||
S_StartSoundAtVolume(pmo, sfx_litng1 + M_RandomKey(4), volume);
|
||||
}
|
||||
else if (thunderchance < 20)
|
||||
{
|
||||
@@ -10388,7 +10400,7 @@ void P_PrecipitationEffects(void)
|
||||
if (volume < 80)
|
||||
volume = 80;
|
||||
|
||||
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_athun1 + M_RandomKey(2), volume);
|
||||
S_StartSoundAtVolume(pmo, sfx_athun1 + M_RandomKey(2), volume);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-15
@@ -34,6 +34,7 @@
|
||||
#include "r_fps.h" // R_ResetViewInterpolation in level load
|
||||
|
||||
#include "s_sound.h"
|
||||
#include "m_emotes.h"
|
||||
#include "st_stuff.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
@@ -411,7 +412,7 @@ static inline float P_SegLengthFloat(seg_t *seg)
|
||||
dx = FIXED_TO_FLOAT(seg->v2->x - seg->v1->x);
|
||||
dy = FIXED_TO_FLOAT(seg->v2->y - seg->v1->y);
|
||||
|
||||
return (float)hypot(dx, dy);
|
||||
return hypotf(dx, dy);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2344,9 +2345,7 @@ static void P_RunLevelScript(const char *scriptname)
|
||||
lumpnum_t lumpnum;
|
||||
char newname[9];
|
||||
|
||||
strncpy(newname, scriptname, 8);
|
||||
|
||||
newname[8] = '\0';
|
||||
strlcpy(newname, scriptname, sizeof(newname));
|
||||
|
||||
lumpnum = W_CheckNumForName(newname);
|
||||
|
||||
@@ -2572,6 +2571,7 @@ static void P_InitMinimapInfo(void)
|
||||
lumpnum_t lumpnum;
|
||||
fixed_t a;
|
||||
fixed_t b;
|
||||
|
||||
node_t *bsp = &nodes[numnodes-1];
|
||||
|
||||
minimapinfo.minimap_pic = NULL;
|
||||
@@ -3008,9 +3008,8 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
#ifdef HWRENDER // not win32 only 19990829 by Kin
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
HWR_FreeExtraSubsectors();
|
||||
// Create plane polygons.
|
||||
HWR_LoadLevel(reloadinggamestate);
|
||||
HWR_LoadLevel();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3071,7 +3070,7 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||
|
||||
if (!fromnetsave) // uglier hack
|
||||
{ // to make a newly loaded level start on the second frame.
|
||||
INT32 buf = gametic % TICQUEUE;
|
||||
INT32 buf = gametic % BACKUPTICS;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
@@ -3313,6 +3312,12 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Free GPU textures before freeing patches.
|
||||
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
|
||||
HWR_ClearAllTextures();
|
||||
#endif
|
||||
|
||||
//
|
||||
// search for sprite replacements
|
||||
//
|
||||
@@ -3323,7 +3328,7 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
// Reload it all anyway, just in case they
|
||||
// added some textures but didn't insert a
|
||||
// TEXTURES/etc. list.
|
||||
//R_LoadTexturesPwad(wadnum);
|
||||
R_LoadTexturesPwad(wadnum);
|
||||
|
||||
// everything from MultiSetupWadFile until ST_Start was here originally
|
||||
|
||||
@@ -3337,6 +3342,11 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
//
|
||||
S_LoadMusicDefs(wadnum);
|
||||
|
||||
//
|
||||
// look for emotes
|
||||
//
|
||||
M_LoadEmotes(wadnum);
|
||||
|
||||
// TODO: Experimental SPRTINFO support, test first
|
||||
R_LoadSpriteInfoLumps(wadnum, wadfiles[wadnum]->numlumps);
|
||||
|
||||
@@ -3347,7 +3357,8 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
|
||||
|
||||
// Only exists to make sure there's no way to overwrite partadd_stage externally
|
||||
// unless you really push yourself.
|
||||
SINT8 P_PartialAddGetStage(void) {
|
||||
SINT8 P_PartialAddGetStage(void)
|
||||
{
|
||||
return partadd_stage;
|
||||
}
|
||||
|
||||
@@ -3381,13 +3392,8 @@ boolean P_MultiSetupWadFiles(boolean fullsetup)
|
||||
|
||||
if (partadd_stage == 1)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
// Free GPU textures before freeing patches.
|
||||
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
|
||||
HWR_ClearAllTextures();
|
||||
#endif
|
||||
// Reload all textures, unconditionally for better or worse.
|
||||
R_LoadTextures();
|
||||
//R_LoadTextures();
|
||||
|
||||
if (fullsetup)
|
||||
++partadd_stage;
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ void P_SetupLevelSky(INT32 skynum, boolean global);
|
||||
boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate);
|
||||
|
||||
#ifdef HWRENDER
|
||||
void HWR_LoadLevel(boolean reloadinggamestate);
|
||||
void HWR_LoadLevel(void);
|
||||
#endif
|
||||
|
||||
boolean P_AddWadFile(const char *wadfilename, boolean local);
|
||||
|
||||
+3
-3
@@ -3913,7 +3913,7 @@ DoneSection2:
|
||||
|
||||
player->kartstuff[k_lapanimation] = 80;
|
||||
|
||||
if (player->pflags & PF_NIGHTSMODE)
|
||||
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
|
||||
player->drillmeter += 48*20;
|
||||
|
||||
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
|
||||
@@ -7103,7 +7103,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)) || thing->player->pflags & PF_NIGHTSMODE))
|
||||
if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || UNLIKELY(thing->player->pflags & PF_NIGHTSMODE)))
|
||||
{
|
||||
INT32 dist;
|
||||
INT32 speed;
|
||||
@@ -7134,7 +7134,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 (!(thing->player->pflags & PF_NIGHTSMODE))
|
||||
if (LIKELY(!(thing->player->pflags & PF_NIGHTSMODE)))
|
||||
{
|
||||
// only push wrt Z if health & 1 (mapthing has ambush flag)
|
||||
if (tmpusher->source->health & 1)
|
||||
|
||||
+47
-27
@@ -190,7 +190,7 @@ void Command_CountMobjs_f(void)
|
||||
void P_InitThinkers(void)
|
||||
{
|
||||
thinkercap.prev = thinkercap.next = &thinkercap;
|
||||
precipcap.prev = precipcap.next = &precipcap;
|
||||
precipcap.prev = precipcap.next = &precipcap;
|
||||
waypointcap = NULL;
|
||||
}
|
||||
|
||||
@@ -461,6 +461,9 @@ static inline void P_RunThinkers(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Controller rumble!
|
||||
// this keeps track of a bunch of things
|
||||
// and makes your controller rumble accordingly
|
||||
static void P_DeviceRumbleTick(void)
|
||||
{
|
||||
UINT8 i;
|
||||
@@ -472,27 +475,31 @@ static void P_DeviceRumbleTick(void)
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
UINT16 low = 0;
|
||||
UINT16 high = 0;
|
||||
|
||||
if (!cv_usejoystick[i].value || !cv_rumble[i].value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
player_t *player = ((i == 0) ? &players[consoleplayer] : &players[displayplayers[i]]);
|
||||
|
||||
if (player->spectator || !player->mo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (camera[i].freecam)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->exiting)
|
||||
UINT16 low = 0, high = 0;
|
||||
UINT16 lenght = 57; // in ms
|
||||
|
||||
const player_t *player = ((i == 0) ? &players[consoleplayer] : &players[displayplayers[i]]);
|
||||
|
||||
// allow lua to do some crap for spectators
|
||||
if (player->spectator || !player->mo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// reset the rumble if you exit or are ded lel
|
||||
if (player->exiting ||
|
||||
player->playerstate == PST_DEAD ||
|
||||
player->kartstuff[k_respawn] > 1)
|
||||
{
|
||||
G_PlayerDeviceRumble(i, low, high, 0);
|
||||
continue;
|
||||
@@ -501,15 +508,17 @@ static void P_DeviceRumbleTick(void)
|
||||
if (player->kartstuff[k_spinouttimer])
|
||||
{
|
||||
//low = high = FRACUNIT / 6;
|
||||
low = high = FixedMul((FRACUNIT / 4), (FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2))));
|
||||
low = high = FixedMul((FRACUNIT / 4), (FixedDiv(player->kartstuff[k_spinouttimer], (3*TICRATE / 2)))); // try do some some kinda fadeout
|
||||
}
|
||||
else if (player->kartstuff[k_sneakertimer] > (sneakertime-(TICRATE/2)))
|
||||
{
|
||||
low = high = FRACUNIT / 8;
|
||||
}
|
||||
else if ((player->kartstuff[k_offroad])
|
||||
&& P_IsObjectOnGround(player->mo) && player->speed != 0)
|
||||
&& player->speed != 0
|
||||
&& P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
// weaken this depending on if you got hyu or invinc
|
||||
if (player->kartstuff[k_hyudorotimer])
|
||||
{
|
||||
high = FRACUNIT / 128;
|
||||
@@ -524,7 +533,8 @@ static void P_DeviceRumbleTick(void)
|
||||
}
|
||||
}
|
||||
else if ((player->kartstuff[k_bananadrag] > TICRATE)
|
||||
&& P_IsObjectOnGround(player->mo) && player->speed != 0)
|
||||
&& player->speed != 0
|
||||
&& P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (leveltime & 1) // this is actually funny lel
|
||||
high = FRACUNIT / 64;
|
||||
@@ -541,7 +551,7 @@ static void P_DeviceRumbleTick(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
G_PlayerDeviceRumble(i, low, high, 57);
|
||||
G_PlayerDeviceRumble(i, low, high, lenght);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,7 +566,11 @@ void P_RunChaseCameras(void)
|
||||
player_t *p = &players[displayplayers[i]];
|
||||
camera_t *cam = &camera[i];
|
||||
|
||||
if (cv_verticallook[i].value && leveltime > starttime && p->mo && p->kartstuff[k_respawn] == 0 && p->kartstuff[k_throwdir] != 0)
|
||||
if (cv_verticallook[i].value &&
|
||||
leveltime > starttime
|
||||
&& p->mo
|
||||
&& p->kartstuff[k_respawn] == 0
|
||||
&& p->kartstuff[k_throwdir] != 0)
|
||||
{
|
||||
if (p->speed < 6 * p->mo->scale && abs(cam->dpad_y_held) < 2*TICRATE)
|
||||
cam->dpad_y_held += p->kartstuff[k_throwdir];
|
||||
@@ -599,6 +613,11 @@ static void P_RunQuakes(void)
|
||||
--quake.time;
|
||||
}
|
||||
|
||||
// Reset our Sprite scales and offsets
|
||||
// at the start of our tic
|
||||
// this is just to make things simpler
|
||||
// as we dont have to reset it ourselves after use
|
||||
// done at the start so lua can still overwrite everything
|
||||
static inline void P_ResetSpriteStuff(void)
|
||||
{
|
||||
thinker_t *th;
|
||||
@@ -735,8 +754,10 @@ void P_Ticker(boolean run)
|
||||
PS_START_TIMING(ps_playerthink_time);
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !P_MobjWasRemoved(players[i].mo))
|
||||
P_PlayerThink(&players[i]);
|
||||
if (!playeringame[i] || P_MobjWasRemoved(players[i].mo))
|
||||
continue;
|
||||
|
||||
P_PlayerThink(&players[i]);
|
||||
}
|
||||
PS_STOP_TIMING(ps_playerthink_time);
|
||||
}
|
||||
@@ -757,8 +778,10 @@ void P_Ticker(boolean run)
|
||||
// Run any "after all the other thinkers" stuff
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !P_MobjWasRemoved(players[i].mo))
|
||||
P_PlayerAfterThink(&players[i]);
|
||||
if (!playeringame[i] || P_MobjWasRemoved(players[i].mo))
|
||||
continue;
|
||||
|
||||
P_PlayerAfterThink(&players[i]);
|
||||
}
|
||||
|
||||
// Apply rumble to local players
|
||||
@@ -837,12 +860,12 @@ void P_Ticker(boolean run)
|
||||
|
||||
if (demo.recording)
|
||||
{
|
||||
INT32 axis = JoyAxis(AXISLOOKBACK, 1);
|
||||
|
||||
G_WriteAllGhostTics();
|
||||
|
||||
if (cv_recordmultiplayerdemos.value)
|
||||
{
|
||||
const INT32 axis = JoyAxis(AXISLOOKBACK, 1);
|
||||
|
||||
if (demo.savemode == DSM_NOTSAVING || demo.savemode == DSM_WILLAUTOSAVE)
|
||||
if (demo.savebutton && demo.savebutton + 3*TICRATE < leveltime && (InputDown(gc_lookback, 1) || (cv_usejoystick[0].value && axis > 0)))
|
||||
demo.savemode = DSM_TITLEENTRY;
|
||||
@@ -958,10 +981,7 @@ void P_PreTicker(INT32 frames)
|
||||
// Run any "after all the other thinkers" stuff
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
if (P_MobjWasRemoved(players[i].mo))
|
||||
if (!playeringame[i] || P_MobjWasRemoved(players[i].mo))
|
||||
continue;
|
||||
|
||||
P_PlayerAfterThink(&players[i]);
|
||||
|
||||
+37
-35
@@ -73,7 +73,7 @@ void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move)
|
||||
|
||||
mo->momx += FixedMul(move, FINECOSINE(angle));
|
||||
|
||||
if (!(twodlevel || (mo->flags2 & MF2_TWOD)))
|
||||
if (LIKELY(!(twodlevel || (mo->flags2 & MF2_TWOD))))
|
||||
mo->momy += FixedMul(move, FINESINE(angle));
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move)
|
||||
|
||||
mo->momx = FixedMul(move, FINECOSINE(angle));
|
||||
|
||||
if (!(twodlevel || (mo->flags2 & MF2_TWOD)))
|
||||
if (LIKELY(!(twodlevel || (mo->flags2 & MF2_TWOD))))
|
||||
mo->momy = FixedMul(move,FINESINE(angle));
|
||||
}
|
||||
|
||||
@@ -498,9 +498,9 @@ void P_PlayLivesJingle(player_t *player)
|
||||
if (player && !P_IsLocalPlayer(player))
|
||||
return;
|
||||
|
||||
if (use1upSound)
|
||||
if (UNLIKELY(use1upSound))
|
||||
S_StartSound(NULL, sfx_oneup);
|
||||
else if (mariomode)
|
||||
else if (UNLIKELY(mariomode))
|
||||
S_StartSound(NULL, sfx_marioa);
|
||||
else
|
||||
{
|
||||
@@ -528,7 +528,7 @@ void P_PlayRinglossSound(mobj_t *source, mobj_t *damager)
|
||||
S_StartSound(NULL, sfx);
|
||||
}
|
||||
else
|
||||
S_StartSound(source, (mariomode) ? sfx_mario8 : sfx_khurt1 + key);
|
||||
S_StartSound(source, UNLIKELY(mariomode) ? sfx_mario8 : sfx_khurt1 + key);
|
||||
}
|
||||
else
|
||||
S_StartSound(source, sfx_slip);
|
||||
@@ -1287,13 +1287,14 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
|
||||
{
|
||||
sector_t *sector = mo->subsector->sector;
|
||||
fixed_t topheight, bottomheight;
|
||||
|
||||
fixed_t flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0);
|
||||
fixed_t flipoffset;
|
||||
|
||||
if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0);
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
@@ -1682,6 +1683,7 @@ static void P_DoBubbleBreath(player_t *player)
|
||||
bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_SMALLBUBBLE);
|
||||
else if (P_RandomChance(3*FRACUNIT/256))
|
||||
bubble = P_SpawnMobj(player->mo->x, player->mo->y, zh, MT_MEDIUMBUBBLE);
|
||||
|
||||
if (bubble)
|
||||
{
|
||||
bubble->threshold = 42;
|
||||
@@ -1689,8 +1691,8 @@ static void P_DoBubbleBreath(player_t *player)
|
||||
P_SetScale(bubble, bubble->destscale);
|
||||
}
|
||||
|
||||
if (player->pflags & PF_NIGHTSMODE) // NiGHTS Super doesn't spawn flight bubbles
|
||||
return;
|
||||
//if (player->pflags & PF_NIGHTSMODE) // NiGHTS Super doesn't spawn flight bubbles
|
||||
//return;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2159,7 +2161,7 @@ static void P_MovePlayer(player_t *player)
|
||||
}
|
||||
// note: don't unset stasis here
|
||||
|
||||
if (!player->spectator && G_TagGametype())
|
||||
if (UNLIKELY(!player->spectator && G_TagGametype()))
|
||||
{
|
||||
// If we have stasis already here, it's because it's forced on us
|
||||
// by a linedef executor or what have you
|
||||
@@ -2219,7 +2221,7 @@ static void P_MovePlayer(player_t *player)
|
||||
player->lturn_max[leveltime%MAXPREDICTTICS] = player->rturn_max[leveltime%MAXPREDICTTICS] = 0;
|
||||
}
|
||||
|
||||
if (leveltime >= starttime)
|
||||
if (LIKELY(leveltime >= starttime))
|
||||
{
|
||||
// KART: Don't directly apply angleturn! It may have been either A) forged by a malicious client, or B) not be a smooth turn due to a player dropping frames.
|
||||
// Instead, turn the player only up to the amount they're supposed to turn accounting for latency. Allow exactly 1 extra turn unit to try to keep old replays synced.
|
||||
@@ -2258,7 +2260,7 @@ static void P_MovePlayer(player_t *player)
|
||||
P_3dMovement(player);
|
||||
}
|
||||
|
||||
if (maptol & TOL_2D)
|
||||
if (UNLIKELY(maptol & TOL_2D)) // psure this doesent even work at all
|
||||
runspd = FixedMul(runspd, 2*FRACUNIT/3);
|
||||
|
||||
/////////////////////////
|
||||
@@ -2319,10 +2321,10 @@ static void P_MovePlayer(player_t *player)
|
||||
|
||||
// Drifting sound
|
||||
// Start looping the sound now.
|
||||
if (leveltime % 50 == 0 && onground && player->kartstuff[k_drift] != 0)
|
||||
if (onground && leveltime % 50 == 0 && player->kartstuff[k_drift] != 0)
|
||||
S_StartSound(player->mo, sfx_drift);
|
||||
// Leveltime being 50 might take a while at times. We'll start it up once, isntantly.
|
||||
else if (!S_SoundPlaying(player->mo, sfx_drift) && onground && player->kartstuff[k_drift] != 0)
|
||||
else if (onground && !S_SoundPlaying(player->mo, sfx_drift) && player->kartstuff[k_drift] != 0)
|
||||
S_StartSound(player->mo, sfx_drift);
|
||||
// Ok, we'll stop now.
|
||||
else if (player->kartstuff[k_drift] == 0 || !onground)
|
||||
@@ -2347,7 +2349,7 @@ static void P_MovePlayer(player_t *player)
|
||||
P_SetPlayerMobjState(player->mo, S_KART_STND1); // SRB2kart - was S_PLAY_STND
|
||||
}
|
||||
|
||||
if (player->gotflag) // If you can't glide, then why the heck would you be gliding?
|
||||
if (UNLIKELY(player->gotflag)) // If you can't glide, then why the heck would you be gliding?
|
||||
{
|
||||
player->pflags &= ~PF_GLIDING;
|
||||
player->glidetime = 0;
|
||||
@@ -2708,8 +2710,8 @@ boolean P_LookForEnemies(player_t *player)
|
||||
player->mo->z-mo->z) > FixedMul(RING_DIST, player->mo->scale))
|
||||
continue; // out of range
|
||||
|
||||
if ((twodlevel || player->mo->flags2 & MF2_TWOD)
|
||||
&& abs(player->mo->y-mo->y) > player->mo->radius)
|
||||
if (UNLIKELY((twodlevel || player->mo->flags2 & MF2_TWOD)
|
||||
&& abs(player->mo->y-mo->y) > player->mo->radius))
|
||||
continue; // not in your 2d plane
|
||||
|
||||
if (mo->type == MT_PLAYER) // Don't chase after other players!
|
||||
@@ -3514,7 +3516,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
|
||||
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || UNLIKELY(GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
|
||||
@@ -3579,7 +3581,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
|
||||
// We're inside it! Yess...
|
||||
polysec = po->lines[0]->backsector;
|
||||
|
||||
if (GETSECSPECIAL(polysec->special, 4) == 12)
|
||||
if (UNLIKELY(GETSECSPECIAL(polysec->special, 4) == 12))
|
||||
{ // Camera noclip polyobj.
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
continue;
|
||||
@@ -3635,7 +3637,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam,
|
||||
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
if ((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
|
||||
if (UNLIKELY((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) == 12))
|
||||
{
|
||||
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
|
||||
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
|
||||
@@ -4081,7 +4083,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
||||
// Team changing in Team Match and CTF
|
||||
// Pressing fire assigns you to a team that needs players if allowed.
|
||||
// Partial code reproduction from p_tick.c autobalance code.
|
||||
else if (G_GametypeHasTeams())
|
||||
else if (UNLIKELY(G_GametypeHasTeams()))
|
||||
{
|
||||
INT32 changeto = 0;
|
||||
INT32 z, numplayersred = 0, numplayersblue = 0;
|
||||
@@ -4323,10 +4325,10 @@ static INT32 Quaketilt(player_t *player)
|
||||
if (abs(delta) > ANGLE_90)
|
||||
delta = (INT32)(( moma + ANGLE_180 ) - player->mo->angle );
|
||||
|
||||
const boolean sliptiding = player->kartstuff[k_drift] ? 0 : player->kartstuff[k_aizdriftstrat];
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
const boolean sliptiding = player->kartstuff[k_drift] ? 0 : player->kartstuff[k_aizdriftstrat];
|
||||
|
||||
if (sliptiding)
|
||||
{
|
||||
tilt = ANGLE_45;
|
||||
@@ -4479,8 +4481,8 @@ void P_PlayerThink(player_t *player)
|
||||
{
|
||||
seenplayer = NULL;
|
||||
|
||||
if (cv_seenames.value && cv_allowseenames.value &&
|
||||
!(G_TagGametype() && (player->pflags & PF_TAGIT)))
|
||||
if (UNLIKELY(cv_seenames.value && cv_allowseenames.value &&
|
||||
!(G_TagGametype() && (player->pflags & PF_TAGIT))))
|
||||
{
|
||||
mobj_t *mo = P_SpawnNameFinder(player->mo, MT_NAMECHECK);
|
||||
|
||||
@@ -4769,8 +4771,8 @@ void P_PlayerThink(player_t *player)
|
||||
}
|
||||
|
||||
// Even if not NiGHTS, pull in nearby objects when walking around as John Q. Elliot.
|
||||
if (!objectplacing && !((netgame || multiplayer) && player->spectator)
|
||||
&& maptol & TOL_NIGHTS && (!(player->pflags & PF_NIGHTSMODE) || player->powers[pw_nights_helper]))
|
||||
if (UNLIKELY(!objectplacing && !((netgame || multiplayer) && player->spectator)
|
||||
&& maptol & TOL_NIGHTS && (!(player->pflags & PF_NIGHTSMODE) || player->powers[pw_nights_helper])))
|
||||
{
|
||||
thinker_t *th;
|
||||
mobj_t *mo2;
|
||||
@@ -4835,7 +4837,7 @@ void P_PlayerThink(player_t *player)
|
||||
player->pflags &= ~PF_FULLSTASIS;
|
||||
|
||||
if (player->onconveyor == 1)
|
||||
player->cmomy = player->cmomx = 0;
|
||||
player->cmomy = player->cmomx = 0;
|
||||
|
||||
P_DoBubbleBreath(player); // Spawn Sonic's bubbles
|
||||
P_CheckInvincibilityTimer(player); // Spawn Invincibility Sparkles
|
||||
@@ -4872,7 +4874,7 @@ void P_PlayerThink(player_t *player)
|
||||
#endif
|
||||
|
||||
// check for use
|
||||
if (!(player->pflags & PF_NIGHTSMODE))
|
||||
if (LIKELY(!(player->pflags & PF_NIGHTSMODE)))
|
||||
{
|
||||
if (cmd->buttons & BT_BRAKE)
|
||||
player->pflags |= PF_USEDOWN;
|
||||
@@ -5044,6 +5046,11 @@ void P_PlayerAfterThink(player_t *player)
|
||||
P_PlayerInSpecialSector(player);
|
||||
#endif
|
||||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
@@ -5053,12 +5060,7 @@ void P_PlayerAfterThink(player_t *player)
|
||||
}
|
||||
}
|
||||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->pflags & PF_NIGHTSMODE)
|
||||
if (UNLIKELY(player->pflags & PF_NIGHTSMODE))
|
||||
{
|
||||
player->powers[pw_gravityboots] = 0;
|
||||
}
|
||||
|
||||
+243
-152
@@ -235,6 +235,7 @@ UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UIN
|
||||
// Painfully simple texture id cacheing to make maps load faster. :3
|
||||
static struct {
|
||||
char name[9];
|
||||
UINT32 hash;
|
||||
INT32 id;
|
||||
} *tidcache = NULL;
|
||||
static INT32 tidcachelen = 0;
|
||||
@@ -484,9 +485,7 @@ UINT8 *R_GetColumn(fixed_t tex, INT32 col)
|
||||
// Odd width texture, cannot just mask.
|
||||
// Sometime gets colnum = -1 or = width, even without tiling.
|
||||
// Test LostCiv, Map 20, crates.
|
||||
col = ( col < 0 ) ?
|
||||
texwidth - (((-col - 1) % texwidth) + 1)
|
||||
: col % texwidth;
|
||||
col = ((col % texwidth) + texwidth) % texwidth;
|
||||
}
|
||||
|
||||
if (!data)
|
||||
@@ -522,32 +521,151 @@ void R_FlushTextureCache(void)
|
||||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum);
|
||||
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index);
|
||||
|
||||
//
|
||||
// R_LoadTextures
|
||||
// Initializes the texture list with the textures from the world map.
|
||||
//
|
||||
#define TX_START "TX_START"
|
||||
#define TX_END "TX_END"
|
||||
void R_LoadTextures(void)
|
||||
|
||||
static INT32
|
||||
Rloadtextures (INT32 i, INT32 w)
|
||||
{
|
||||
INT32 i, k, w;
|
||||
UINT16 j;
|
||||
INT32 k;
|
||||
UINT16 texstart, texend, texturesLumpPos;
|
||||
softwarepatch_t *patchlump;
|
||||
texpatch_t *patch;
|
||||
texture_t *texture;
|
||||
|
||||
// Free previous memory before numtextures change.
|
||||
if (numtextures)
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
for (i = 0; i < numtextures; i++)
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
Z_Free(textures[i]);
|
||||
Z_Free(texturecache[i]);
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
Z_Free(texturetranslation);
|
||||
Z_Free(textures);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
if (texturesLumpPos != INT16_MAX)
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
return i;
|
||||
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
patchlump = (softwarepatch_t *)W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC);
|
||||
|
||||
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((wadnum, lumpnum), patchlump->width, patchlump->height);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
texture->width = SHORT(patchlump->width);
|
||||
texture->height = SHORT(patchlump->height);
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = wadnum;
|
||||
patch->lump = texstart + j;
|
||||
|
||||
Z_Free(patchlump);
|
||||
|
||||
// determine width power of 2
|
||||
#if 1
|
||||
// [WDJ] only need to determine if exact power of 2.
|
||||
k = 1;
|
||||
while (k < texture->width)
|
||||
k<<=1;
|
||||
#else
|
||||
// Largest power of 2 that fits within width.
|
||||
k = 1;
|
||||
while (k << 1 <= texture->width)
|
||||
k <<= 1;
|
||||
#endif
|
||||
if (k != texture->width)
|
||||
{
|
||||
// Odd width
|
||||
k = 1; // make texturewidthmask = 0
|
||||
}
|
||||
|
||||
texturewidthmask[i] = k - 1;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static INT32
|
||||
count_range
|
||||
( const char * marker_start,
|
||||
const char * marker_end,
|
||||
const char * folder,
|
||||
UINT16 wadnum)
|
||||
{
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend;
|
||||
INT32 count = 0;
|
||||
|
||||
// Count flats
|
||||
if (W_FileHasFolders(wadfiles[wadnum]))
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0);
|
||||
texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForMarkerStartPwad(marker_start, wadnum, 0);
|
||||
texend = W_CheckNumForNamePwad(marker_end, wadnum, texstart);
|
||||
}
|
||||
|
||||
if (texstart != INT16_MAX && texend != INT16_MAX)
|
||||
{
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (W_FileHasFolders(wadfiles[wadnum]))
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder(wadnum, j)) // Check if lump is a folder; if not, then count it
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between markers
|
||||
{
|
||||
count += (texend - texstart);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static INT32 R_CountTextures(UINT16 wadnum)
|
||||
{
|
||||
UINT16 texturesLumpPos;
|
||||
INT32 count = 0;
|
||||
|
||||
// Load patches and textures.
|
||||
|
||||
@@ -556,159 +674,127 @@ void R_LoadTextures(void)
|
||||
// the markers.
|
||||
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
|
||||
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
||||
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
||||
|
||||
// Count the textures from TEXTURES lumps
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, 0);
|
||||
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
}
|
||||
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
|
||||
// Add all the textures between TX_START and TX_END
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||
continue;
|
||||
|
||||
numtextures++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
count += R_CountTexturesInTEXTURESLump(wadnum, texturesLumpPos);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, texturesLumpPos + 1);
|
||||
}
|
||||
|
||||
// If no textures found by this point, bomb out
|
||||
if (!numtextures)
|
||||
I_Error("No textures detected in any WADs!\n");
|
||||
// Count single-patch textures
|
||||
count += count_range(TX_START, TX_END, "textures/", wadnum);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
recallocuser
|
||||
( void * user,
|
||||
size_t old,
|
||||
size_t new)
|
||||
{
|
||||
char *p = Z_Realloc(*(void**)user,
|
||||
new, PU_STATIC, user);
|
||||
|
||||
if (new > old)
|
||||
memset(&p[old], 0, (new - old));
|
||||
}
|
||||
|
||||
static void R_AllocateTextures(INT32 add)
|
||||
{
|
||||
const INT32 newtextures = (numtextures + add);
|
||||
const size_t newsize = newtextures * sizeof (void*);
|
||||
const size_t oldsize = numtextures * sizeof (void*);
|
||||
|
||||
INT32 i;
|
||||
|
||||
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
||||
// There are actually 5 buffers allocated in one for convenience.
|
||||
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
|
||||
recallocuser(&textures, oldsize, newsize);
|
||||
|
||||
// Allocate texture column offset table.
|
||||
texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *)));
|
||||
recallocuser(&texturecolumnofs, oldsize, newsize);
|
||||
// Allocate texture referencing cache.
|
||||
texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2));
|
||||
// Allocate texture width mask table.
|
||||
texturewidthmask = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3));
|
||||
// Allocate texture height mask table.
|
||||
textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4));
|
||||
recallocuser(&texturecache, oldsize, newsize);
|
||||
// Allocate texture width table.
|
||||
recallocuser(&texturewidthmask, oldsize, newsize);
|
||||
// Allocate texture height table.
|
||||
recallocuser(&textureheight, oldsize, newsize);
|
||||
// Create translation table for global animation.
|
||||
texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL);
|
||||
Z_Realloc(texturetranslation, (newtextures + 1) * sizeof(*texturetranslation), PU_STATIC, &texturetranslation);
|
||||
|
||||
for (i = 0; i < numtextures; i++)
|
||||
texturetranslation[i] = i;
|
||||
|
||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||
for (i = 0; i < numtextures; ++i)
|
||||
{
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1;
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
if (texturesLumpPos != INT16_MAX)
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
|
||||
if (W_FileHasFolders(wadfiles[w]))
|
||||
{
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
patchlump = (softwarepatch_t *)W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC);
|
||||
|
||||
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad(wadnum, lumpnum), patchlump->width, patchlump->height);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->width = SHORT(patchlump->width);
|
||||
texture->height = SHORT(patchlump->height);
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = wadnum;
|
||||
patch->lump = texstart + j;
|
||||
|
||||
Z_Free(patchlump);
|
||||
|
||||
// determine width power of 2
|
||||
#if 1
|
||||
// [WDJ] only need to determine if exact power of 2.
|
||||
k = 1;
|
||||
while (k < texture->width)
|
||||
k<<=1;
|
||||
#else
|
||||
// Largest power of 2 that fits within width.
|
||||
k = 1;
|
||||
while (k << 1 <= texture->width)
|
||||
k <<= 1;
|
||||
#endif
|
||||
if (k != texture->width)
|
||||
{
|
||||
// Odd width
|
||||
k = 1; // make texturewidthmask = 0
|
||||
}
|
||||
|
||||
texturewidthmask[i] = k - 1;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
// R_FlushTextureCache relies on the user for
|
||||
// Z_Free, texturecache has been reallocated so the
|
||||
// user is now garbage memory.
|
||||
Z_SetUser(texturecache[i], (void**)&texturecache[i]);
|
||||
}
|
||||
|
||||
while (i < newtextures)
|
||||
{
|
||||
texturetranslation[i] = i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static INT32 R_DefineTextures(INT32 i, UINT16 w)
|
||||
{
|
||||
return Rloadtextures(i, w);
|
||||
}
|
||||
|
||||
static void R_FinishLoadingTextures(INT32 add)
|
||||
{
|
||||
numtextures += add;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_LoadMapTextures(numtextures);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// R_LoadTextures
|
||||
// Initializes the texture list with the textures from the world map.
|
||||
//
|
||||
void R_LoadTextures(void)
|
||||
{
|
||||
INT32 i, w;
|
||||
INT32 newtextures = 0;
|
||||
|
||||
for (w = 0; w < numwadfiles; w++)
|
||||
{
|
||||
newtextures += R_CountTextures((UINT16)w);
|
||||
}
|
||||
|
||||
// If no textures found by this point, bomb out
|
||||
if (!newtextures)
|
||||
I_Error("No textures detected in any WADs!\n");
|
||||
|
||||
R_AllocateTextures(newtextures);
|
||||
|
||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||
{
|
||||
i = R_DefineTextures(i, w);
|
||||
}
|
||||
|
||||
R_FinishLoadingTextures(i);
|
||||
}
|
||||
|
||||
void R_LoadTexturesPwad(UINT16 wadnum)
|
||||
{
|
||||
INT32 newtextures = R_CountTextures(wadnum);
|
||||
|
||||
if (!newtextures)
|
||||
return;
|
||||
|
||||
R_AllocateTextures(newtextures);
|
||||
newtextures = R_DefineTextures(numtextures, wadnum) - numtextures;
|
||||
R_FinishLoadingTextures(newtextures);
|
||||
}
|
||||
|
||||
static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
|
||||
{
|
||||
char *texturesToken;
|
||||
@@ -960,6 +1046,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
|
||||
// Allocate memory for a zero-patch texture. Obviously, we'll be adding patches momentarily.
|
||||
resultTexture = (texture_t *)Z_Calloc(sizeof(texture_t), PU_STATIC, NULL);
|
||||
M_Memcpy(resultTexture->name, newTextureName, 8);
|
||||
resultTexture->hash = quickncasehash(newTextureName, 8);
|
||||
resultTexture->width = newTextureWidth;
|
||||
resultTexture->height = newTextureHeight;
|
||||
resultTexture->type = TEXTURETYPE_COMPOSITE;
|
||||
@@ -1743,19 +1830,22 @@ void R_ClearTextureNumCache(boolean btell)
|
||||
INT32 R_CheckTextureNumForName(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 hash;
|
||||
|
||||
// "NoTexture" marker.
|
||||
if (name[0] == '-')
|
||||
return 0;
|
||||
|
||||
hash = quickncasehash(name, 8);
|
||||
|
||||
for (i = 0; i < tidcachelen; i++)
|
||||
if (!strncasecmp(tidcache[i].name, name, 8))
|
||||
if (tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
|
||||
return tidcache[i].id;
|
||||
|
||||
// Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier
|
||||
//for (i = 0; i < numtextures; i++) <- old
|
||||
for (i = (numtextures - 1); i >= 0; i--) // <- new
|
||||
if (!strncasecmp(textures[i]->name, name, 8))
|
||||
if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8))
|
||||
{
|
||||
tidcachelen++;
|
||||
Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache);
|
||||
@@ -1764,6 +1854,7 @@ INT32 R_CheckTextureNumForName(const char *name)
|
||||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name);
|
||||
#endif
|
||||
tidcache[tidcachelen-1].hash = hash;
|
||||
tidcache[tidcachelen-1].id = i;
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ typedef struct
|
||||
// Keep name for switch changing, etc.
|
||||
char name[8];
|
||||
UINT8 type; // TEXTURETYPE_
|
||||
UINT32 hash;
|
||||
INT16 width, height;
|
||||
boolean holes;
|
||||
// All the patches[patchcount] are drawn back to front into the cached texture.
|
||||
@@ -76,6 +77,7 @@ extern CV_PossibleValue_t Color_cons_t[];
|
||||
|
||||
// Load TEXTURE1/TEXTURE2/PNAMES definitions, create lookup tables
|
||||
void R_LoadTextures(void);
|
||||
void R_LoadTexturesPwad(UINT16 wadnum);
|
||||
void R_FlushTextureCache(void);
|
||||
|
||||
UINT8 *R_GenerateTexture(size_t texnum);
|
||||
|
||||
@@ -151,6 +151,7 @@ static CV_PossibleValue_t fov_cons_t[] = {{MINFOV*FRACUNIT, "MIN"}, {MAXFOV*FRAC
|
||||
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
|
||||
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
|
||||
static CV_PossibleValue_t secbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||
|
||||
static void R_SetFov(fixed_t playerfov);
|
||||
|
||||
@@ -201,6 +202,8 @@ consvar_t cv_ripplewater = {"waterripples", "On", CV_SAVE, CV_OnOff, NULL, 0
|
||||
// Okay, whoever said homremoval causes a performance hit should be shot.
|
||||
consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_secbright = {"r_secbright", "0", CV_SAVE, secbright_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_maxportals = {"maxportals", "2", CV_SAVE, maxportals_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// cap fov, fov too high tears software apart.
|
||||
@@ -1558,6 +1561,7 @@ void R_RegisterEngineStuff(void)
|
||||
CV_RegisterVar(&cv_skybox);
|
||||
CV_RegisterVar(&cv_ffloorclip);
|
||||
CV_RegisterVar(&cv_spriteclip);
|
||||
CV_RegisterVar(&cv_secbright);
|
||||
CV_RegisterVar(&cv_softcyancut);
|
||||
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
|
||||
@@ -197,9 +197,15 @@ extern consvar_t cv_tailspickup;
|
||||
extern consvar_t cv_maxinterpdist;
|
||||
extern consvar_t cv_playerfade;
|
||||
extern consvar_t cv_ripplewater;
|
||||
extern consvar_t cv_secbright;
|
||||
|
||||
extern consvar_t cv_randomdirlight;
|
||||
|
||||
static inline INT32 R_GetSoftLightlevel(INT32 llevel)
|
||||
{
|
||||
return CLAMP(llevel, cv_secbright.value, 255) >> LIGHTSEGSHIFT;
|
||||
}
|
||||
|
||||
// Called by startup code.
|
||||
void R_Init(void);
|
||||
|
||||
|
||||
+7
-5
@@ -1059,7 +1059,7 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
|
||||
#else
|
||||
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
|
||||
#endif
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
light = R_GetSoftLightlevel(pl->lightlevel);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
}
|
||||
@@ -1111,16 +1111,17 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
|
||||
#else
|
||||
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
|
||||
#endif
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
light = R_GetSoftLightlevel(pl->lightlevel);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
}
|
||||
else if (pl->ffloor->flags & FF_FOG)
|
||||
{
|
||||
spanfunctype = SPANDRAWFUNC_FOG;
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
light = R_GetSoftLightlevel(pl->lightlevel);
|
||||
}
|
||||
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = R_GetSoftLightlevel(pl->lightlevel);
|
||||
|
||||
if (pl->ffloor->flags & FF_RIPPLE && cv_ripplewater.value)
|
||||
{
|
||||
@@ -1172,7 +1173,8 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
|
||||
}
|
||||
}
|
||||
}
|
||||
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = R_GetSoftLightlevel(pl->lightlevel);
|
||||
}
|
||||
|
||||
ds->currentplane = pl;
|
||||
|
||||
+10
-11
@@ -209,11 +209,11 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
|
||||
rlight->flags = static_cast<ffloortype_e>(light->flags);
|
||||
|
||||
if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_GetSoftLightlevel(rlight->lightlevel);
|
||||
else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY))
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
else
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_GetSoftLightlevel(rlight->lightlevel);
|
||||
|
||||
if (rlight->extra_colormap && rlight->extra_colormap->fog)
|
||||
;
|
||||
@@ -227,7 +227,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
|
||||
{
|
||||
if ((R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == false)
|
||||
|| (frontsector->extra_colormap && frontsector->extra_colormap->fog))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_GetSoftLightlevel(frontsector->lightlevel);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
@@ -764,9 +764,9 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
|
||||
|
||||
// Check if the current light effects the colormap/lightlevel
|
||||
if (pfloor->flags & FF_FOG)
|
||||
rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
rlight->lightnum = R_GetSoftLightlevel(pfloor->master->frontsector->lightlevel);
|
||||
else
|
||||
rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
rlight->lightnum = R_GetSoftLightlevel(rlight->lightlevel);
|
||||
|
||||
if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
|
||||
;
|
||||
@@ -782,14 +782,13 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
|
||||
{
|
||||
// Get correct light level!
|
||||
if ((frontsector->extra_colormap && frontsector->extra_colormap->fog))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_GetSoftLightlevel(frontsector->lightlevel);
|
||||
else if (fog)
|
||||
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_GetSoftLightlevel(pfloor->master->frontsector->lightlevel);
|
||||
else if (fuzzy)
|
||||
lightnum = LIGHTLEVELS-1;
|
||||
else
|
||||
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
|
||||
->lightlevel >> LIGHTSEGSHIFT;
|
||||
lightnum = R_GetSoftLightlevel(R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)->lightlevel);
|
||||
|
||||
if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog))
|
||||
;
|
||||
@@ -1385,7 +1384,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
|
||||
for (i = 0; i < dc->numlights; i++)
|
||||
{
|
||||
INT32 lightnum;
|
||||
lightnum = (dc->lightlist[i].lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_GetSoftLightlevel(dc->lightlist[i].lightlevel);
|
||||
|
||||
if (dc->lightlist[i].extra_colormap)
|
||||
;
|
||||
@@ -2443,7 +2442,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
// use different light tables
|
||||
// for horizontal / vertical / diagonal
|
||||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_GetSoftLightlevel(frontsector->lightlevel);
|
||||
|
||||
if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
+3
-3
@@ -1061,7 +1061,7 @@ static void R_SplitSprite(vissprite_t *sprite)
|
||||
|
||||
if (!(sector->lightlist[i].caster->flags & FF_NOSHADE))
|
||||
{
|
||||
INT32 lightnum = (*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT);
|
||||
INT32 lightnum = R_GetSoftLightlevel(*sector->lightlist[i].lightlevel);
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
@@ -1660,7 +1660,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
lightnum = thing->subsector->sector->lightlevel;
|
||||
}
|
||||
|
||||
lightnum = (lightnum + R_ThingLightLevel(thing)) >> LIGHTSEGSHIFT;
|
||||
lightnum = R_GetSoftLightlevel(lightnum + R_ThingLightLevel(thing));
|
||||
|
||||
if (maplighting.directional && P_SectorUsesDirectionalLighting(thing->subsector->sector))
|
||||
{
|
||||
@@ -2057,7 +2057,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
||||
{
|
||||
if (sec->heightsec == -1) lightlevel = sec->lightlevel;
|
||||
|
||||
lightnum = (lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_GetSoftLightlevel(lightlevel);
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
|
||||
+80
-68
@@ -34,7 +34,7 @@
|
||||
#include "lua_hook.h" // MusicChange hook
|
||||
#include "lua_hud.h" // LUA_HudEnabled(hud_musiccredit)
|
||||
|
||||
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
|
||||
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, sfxinfo_t *sfxinfo);
|
||||
static void SetChannelsNum(void);
|
||||
static void Command_Tunes_f(void);
|
||||
static void Command_RestartAudio_f(void);
|
||||
@@ -59,10 +59,12 @@ static void AmigaType_OnChange(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SDL) && SOUND==SOUND_SDL
|
||||
consvar_t cv_samplerate = {"samplerate", "44100", 0, CV_Unsigned, NULL, 22050, NULL, NULL, 0, 0, NULL}; //Alam: For easy hacking?
|
||||
#endif
|
||||
|
||||
static CV_PossibleValue_t audbuffersize_cons_t[] = {{256, "256"}, {512, "512"}, {1024, "1024"}, {2048, "2048"}, {4096, "4096"}, {0, NULL}};
|
||||
consvar_t cv_audbuffersize = {"buffersize", "2048", CV_SAVE, audbuffersize_cons_t, BufferSize_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t audbuffersize_cons_t[] = {{128, "128"}, {256, "256"}, {512, "512"}, {1024, "1024"}, {2048, "2048"}, {4096, "4096"}, {0, NULL}};
|
||||
consvar_t cv_audbuffersize = {"audiobuffersize", "2048", CV_SAVE, audbuffersize_cons_t, BufferSize_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// stereo reverse
|
||||
consvar_t stereoreverse = {"stereoreverse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -79,7 +81,11 @@ consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_co
|
||||
#endif
|
||||
|
||||
// number of channels available
|
||||
consvar_t cv_numChannels = {"snd_channels", "64", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t numChannels_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_numChannels = {"snd_channels", "64", CV_SAVE|CV_CALL, numChannels_cons_t, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t samesoundlimit_cons_t[] = {{0, "MIN"}, {64, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_samesoundlimit = {"samesoundlimit", "0", CV_SAVE, samesoundlimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
//consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE|CV_NOSHOWHELP, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
@@ -274,7 +280,9 @@ void S_RegisterSoundStuff(void)
|
||||
|
||||
CV_RegisterVar(&stereoreverse);
|
||||
CV_RegisterVar(&precachesound);
|
||||
#if defined(HAVE_SDL) && SOUND==SOUND_SDL
|
||||
CV_RegisterVar(&cv_samplerate);
|
||||
#endif
|
||||
//CV_RegisterVar(&cv_resetmusic);
|
||||
CV_RegisterVar(&cv_gamesounds);
|
||||
CV_RegisterVar(&cv_gamedigimusic);
|
||||
@@ -282,6 +290,8 @@ void S_RegisterSoundStuff(void)
|
||||
CV_RegisterVar(&cv_gamemidimusic);
|
||||
#endif
|
||||
|
||||
CV_RegisterVar(&cv_samesoundlimit);
|
||||
|
||||
// bird music stuff
|
||||
CV_RegisterVar(&cv_playmusicifunfocused);
|
||||
CV_RegisterVar(&cv_playsoundifunfocused);
|
||||
@@ -324,9 +334,6 @@ static void SetChannelsNum(void)
|
||||
Z_Free(channels);
|
||||
channels = NULL;
|
||||
|
||||
if (cv_numChannels.value == 999999999) //Alam_GBC: OH MY ROD!(ROD rimmiced with GOD!)
|
||||
CV_StealthSet(&cv_numChannels,cv_numChannels.defaultvalue);
|
||||
|
||||
if (cv_numChannels.value)
|
||||
channels = (channel_t *)Z_Calloc(cv_numChannels.value * sizeof (channel_t), PU_STATIC, NULL);
|
||||
numofchannels = (channels ? cv_numChannels.value : 0);
|
||||
@@ -427,6 +434,25 @@ static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume)
|
||||
return FixedDiv(volume * FRACUNIT, root) / FRACUNIT;
|
||||
}
|
||||
|
||||
static boolean S_CheckSameSoundLimit(sfxenum_t sfx_id)
|
||||
{
|
||||
INT32 cnum, scount = 0;
|
||||
|
||||
if (!cv_samesoundlimit.value)
|
||||
return true;
|
||||
|
||||
for (cnum = 0; cnum < numofchannels; cnum++)
|
||||
if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)sfx_id)
|
||||
scount++;
|
||||
|
||||
//CONS_Printf("same sound count: %d for sfx: %d\n", scount, sfx_id);
|
||||
|
||||
if (scount >= cv_samesoundlimit.value)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
{
|
||||
const mobj_t *origin = (const mobj_t *)origin_p;
|
||||
@@ -434,7 +460,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
INT32 initial_volume;
|
||||
|
||||
sfxinfo_t *sfx;
|
||||
INT32 sep, pitch, priority, cnum;
|
||||
INT32 sep, cnum;
|
||||
boolean anyListeners = false;
|
||||
boolean itsUs = false;
|
||||
INT32 i;
|
||||
@@ -449,13 +475,16 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
if (sfx_id == sfx_None)
|
||||
return;
|
||||
|
||||
initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume);
|
||||
// reached same sound limit?
|
||||
if (!S_CheckSameSoundLimit(sfx_id))
|
||||
return;
|
||||
|
||||
memset(listener, 0, sizeof(listener));
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
player_t *player = &players[displayplayers[i]];
|
||||
|
||||
memset(&listener[i], 0, sizeof (listener[i]));
|
||||
listenmobj[i] = NULL;
|
||||
|
||||
if (player->awayviewtics)
|
||||
@@ -471,11 +500,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
{
|
||||
itsUs = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
player_t *player = &players[displayplayers[i]];
|
||||
|
||||
if (camera[i].chase && !player->awayviewtics)
|
||||
{
|
||||
@@ -514,9 +538,9 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
sfx = &S_sfx[sfx_id];
|
||||
}
|
||||
|
||||
initial_volume = (origin ? S_ScaleVolumeWithSplitscreen(volume) : volume);
|
||||
|
||||
// Initialize sound parameters
|
||||
pitch = NORM_PITCH;
|
||||
priority = NORM_PRIORITY;
|
||||
sep = NORM_SEP;
|
||||
|
||||
i = 0; // sensible default
|
||||
@@ -554,7 +578,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
|
||||
if (listenmobj[i])
|
||||
{
|
||||
audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, &pitch, sfx);
|
||||
audible = S_AdjustSoundParams(listenmobj[i], origin, &volume, &sep, sfx);
|
||||
}
|
||||
|
||||
if (!audible)
|
||||
@@ -574,12 +598,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
sfx->data = I_GetSfx(sfx);
|
||||
}
|
||||
|
||||
// increase the usefulness
|
||||
if (sfx->usefulness++ < 0)
|
||||
{
|
||||
sfx->usefulness = -1;
|
||||
}
|
||||
|
||||
// Avoid channel reverse if surround
|
||||
if (reverse)
|
||||
{
|
||||
@@ -598,7 +616,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
channels[cnum].sfxinfo = sfx;
|
||||
channels[cnum].origin = origin;
|
||||
channels[cnum].volume = initial_volume;
|
||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
|
||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, cnum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,7 +625,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
|
||||
if (S_SoundDisabled())
|
||||
return;
|
||||
|
||||
if (mariomode) // Sounds change in Mario mode!
|
||||
if (UNLIKELY(mariomode)) // Sounds change in Mario mode!
|
||||
{
|
||||
switch (sfx_id)
|
||||
{
|
||||
@@ -630,7 +648,8 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (maptol & TOL_XMAS) // Some sounds change for xmas
|
||||
|
||||
if (UNLIKELY(maptol & TOL_XMAS)) // Some sounds change for xmas
|
||||
{
|
||||
switch (sfx_id)
|
||||
{
|
||||
@@ -677,7 +696,7 @@ static INT32 actualmidimusicvolume;
|
||||
|
||||
void S_UpdateSounds(void)
|
||||
{
|
||||
INT32 cnum, volume, sep, pitch;
|
||||
INT32 cnum, volume, sep;
|
||||
boolean audible = false;
|
||||
channel_t *c;
|
||||
INT32 i;
|
||||
@@ -687,14 +706,16 @@ void S_UpdateSounds(void)
|
||||
|
||||
// Update sound/music volumes, if changed manually at console
|
||||
if (actualsfxvolume != cv_soundvolume.value)
|
||||
S_SetSfxVolume (cv_soundvolume.value);
|
||||
S_SetSfxVolume(cv_soundvolume.value);
|
||||
if (actualdigmusicvolume != cv_digmusicvolume.value)
|
||||
S_SetDigMusicVolume (cv_digmusicvolume.value);
|
||||
S_SetDigMusicVolume(cv_digmusicvolume.value);
|
||||
#ifndef NO_MIDI
|
||||
if (actualmidimusicvolume != cv_midimusicvolume.value)
|
||||
S_SetMIDIMusicVolume (cv_midimusicvolume.value);
|
||||
S_SetMIDIMusicVolume(cv_midimusicvolume.value);
|
||||
#endif
|
||||
|
||||
memset(listener, 0, sizeof(listener));
|
||||
|
||||
// We're done now, if we're not in a level.
|
||||
if (gamestate != GS_LEVEL)
|
||||
{
|
||||
@@ -714,7 +735,6 @@ void S_UpdateSounds(void)
|
||||
{
|
||||
player_t *player = &players[displayplayers[i]];
|
||||
|
||||
memset(&listener[i], 0, sizeof (listener[i]));
|
||||
listenmobj[i] = NULL;
|
||||
|
||||
if (player->awayviewtics)
|
||||
@@ -725,15 +745,6 @@ void S_UpdateSounds(void)
|
||||
{
|
||||
listenmobj[i] = player->mo;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NOMUMBLE
|
||||
I_UpdateMumble(players[consoleplayer].mo, listener[0]);
|
||||
#endif
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
player_t *player = &players[displayplayers[i]];
|
||||
|
||||
if (camera[i].chase && !player->awayviewtics)
|
||||
{
|
||||
@@ -751,6 +762,10 @@ void S_UpdateSounds(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NOMUMBLE
|
||||
I_UpdateMumble(players[consoleplayer].mo, listener[0]);
|
||||
#endif
|
||||
|
||||
for (cnum = 0; cnum < numofchannels; cnum++)
|
||||
{
|
||||
c = &channels[cnum];
|
||||
@@ -761,7 +776,6 @@ void S_UpdateSounds(void)
|
||||
{
|
||||
// initialize parameters
|
||||
volume = c->volume; // 8 bits internal volume precision
|
||||
pitch = NORM_PITCH;
|
||||
sep = NORM_SEP;
|
||||
|
||||
// check non-local sounds for distance clipping
|
||||
@@ -817,13 +831,13 @@ void S_UpdateSounds(void)
|
||||
{
|
||||
audible = S_AdjustSoundParams(
|
||||
listenmobj[i], c->origin,
|
||||
&volume, &sep, &pitch,
|
||||
&volume, &sep,
|
||||
c->sfxinfo
|
||||
);
|
||||
}
|
||||
|
||||
if (audible)
|
||||
I_UpdateSoundParams(c->handle, volume, sep, pitch);
|
||||
I_UpdateSoundParams(c->handle, volume, sep);
|
||||
else
|
||||
S_StopChannel(cnum);
|
||||
}
|
||||
@@ -876,8 +890,6 @@ static void S_StopChannel(INT32 cnum)
|
||||
if (cnum != i && c->sfxinfo == channels[i].sfxinfo)
|
||||
break;
|
||||
|
||||
// degrade usefulness of sound data
|
||||
c->sfxinfo->usefulness--;
|
||||
c->sfxinfo = 0;
|
||||
}
|
||||
|
||||
@@ -918,8 +930,7 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t
|
||||
// If the sound is not audible, returns a 0.
|
||||
// Otherwise, modifies parameters and returns 1.
|
||||
//
|
||||
boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch,
|
||||
sfxinfo_t *sfxinfo)
|
||||
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, sfxinfo_t *sfxinfo)
|
||||
{
|
||||
const boolean reverse = (stereoreverse.value ^ encoremode);
|
||||
|
||||
@@ -928,8 +939,6 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
|
||||
listener_t listensource;
|
||||
INT32 i;
|
||||
|
||||
(void)pitch;
|
||||
|
||||
if (!listener)
|
||||
return false;
|
||||
|
||||
@@ -962,13 +971,16 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
|
||||
else
|
||||
{
|
||||
// Essentially check in a 1024 unit radius of the player for an outdoor area.
|
||||
yl = listensource.y - 1024*FRACUNIT;
|
||||
yh = listensource.y + 1024*FRACUNIT;
|
||||
xl = listensource.x - 1024*FRACUNIT;
|
||||
xh = listensource.x + 1024*FRACUNIT;
|
||||
approx_dist = 1024*FRACUNIT;
|
||||
for (y = yl; y <= yh; y += FRACUNIT*64)
|
||||
for (x = xl; x <= xh; x += FRACUNIT*64)
|
||||
#define RADIUSSTEP (64*FRACUNIT)
|
||||
#define SEARCHRADIUS (16*RADIUSSTEP)
|
||||
yl = listensource.y - SEARCHRADIUS;
|
||||
yh = listensource.y + SEARCHRADIUS;
|
||||
xl = listensource.x - SEARCHRADIUS;
|
||||
xh = listensource.x + SEARCHRADIUS;
|
||||
approx_dist = SEARCHRADIUS;
|
||||
#undef SEARCHRADIUS
|
||||
for (y = yl; y <= yh; y += RADIUSSTEP)
|
||||
for (x = xl; x <= xh; x += RADIUSSTEP)
|
||||
{
|
||||
if (R_PointInSubsectorFast(x, y)->sector->ceilingpic == skyflatnum)
|
||||
{
|
||||
@@ -980,6 +992,7 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef RADIUSSTEP
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -990,14 +1003,14 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
|
||||
|
||||
// Ring loss, deaths, etc, should all be heard louder.
|
||||
if (sfxinfo->pitch & SF_X8AWAYSOUND)
|
||||
approx_dist = FixedDiv(approx_dist,8*FRACUNIT);
|
||||
approx_dist = FixedDiv(approx_dist, 8*FRACUNIT);
|
||||
|
||||
// Combine 8XAWAYSOUND with 4XAWAYSOUND and get.... 32XAWAYSOUND?
|
||||
if (sfxinfo->pitch & SF_X4AWAYSOUND)
|
||||
approx_dist = FixedDiv(approx_dist,4*FRACUNIT);
|
||||
approx_dist = FixedDiv(approx_dist, 4*FRACUNIT);
|
||||
|
||||
if (sfxinfo->pitch & SF_X2AWAYSOUND)
|
||||
approx_dist = FixedDiv(approx_dist,2*FRACUNIT);
|
||||
approx_dist = FixedDiv(approx_dist, 2*FRACUNIT);
|
||||
|
||||
if (approx_dist > S_CLIPPING_DIST)
|
||||
return false;
|
||||
@@ -1030,7 +1043,7 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32
|
||||
if (approx_dist >= S_CLOSE_DIST)
|
||||
{
|
||||
// distance effect
|
||||
INT32 n = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS));
|
||||
const INT32 n = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS));
|
||||
*vol = FixedMul(*vol * FRACUNIT / 255, n) / S_ATTENUATOR;
|
||||
}
|
||||
|
||||
@@ -1146,7 +1159,6 @@ void S_InitSfxChannels(INT32 sfxVolume)
|
||||
// Note that sounds have not been cached (yet).
|
||||
for (i = 1; i < NUMSFX; i++)
|
||||
{
|
||||
S_sfx[i].usefulness = -1; // for I_GetSfx()
|
||||
S_sfx[i].lumpnum = LUMPERROR;
|
||||
}
|
||||
|
||||
@@ -1906,12 +1918,12 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
|
||||
}
|
||||
}
|
||||
|
||||
void S_SetRestoreMusicFadeInCvar (consvar_t *cv)
|
||||
void S_SetRestoreMusicFadeInCvar(consvar_t *cv)
|
||||
{
|
||||
music_refade_cv = cv_birdmusic.value ? cv : 0;
|
||||
}
|
||||
|
||||
int S_GetRestoreMusicFadeIn (void)
|
||||
int S_GetRestoreMusicFadeIn(void)
|
||||
{
|
||||
if (music_refade_cv && cv_fading.value)
|
||||
return music_refade_cv->value;
|
||||
@@ -2020,7 +2032,6 @@ void S_KeepMusic(void)
|
||||
if (oldmap == gamemap && oldencore == encoremode)
|
||||
{
|
||||
const boolean musicchanged = S_CheckMusicException();
|
||||
|
||||
resumekeepmusic = (musicchanged && keepmusic.resume);
|
||||
keepmapmusic = (!musicchanged || resumekeepmusic);
|
||||
}
|
||||
@@ -2187,6 +2198,7 @@ static void Command_Tunes_f(void)
|
||||
mapmusic.name, (mapmusic.flags & MUSIC_TRACKMASK));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(tunearg, "-none"))
|
||||
{
|
||||
S_StopMusic();
|
||||
@@ -2205,6 +2217,7 @@ static void Command_Tunes_f(void)
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n"));
|
||||
|
||||
@@ -2214,12 +2227,11 @@ static void Command_Tunes_f(void)
|
||||
if (tunenum)
|
||||
snprintf(mapmusic.name, 7, "%sM", G_BuildMapName(tunenum));
|
||||
else
|
||||
strncpy(mapmusic.name, tunearg, 7);
|
||||
strlcpy(mapmusic.name, tunearg, sizeof(mapmusic.name));
|
||||
|
||||
if (argc > 4)
|
||||
position = (UINT32)atoi(COM_Argv(4));
|
||||
|
||||
mapmusic.name[6] = 0;
|
||||
mapmusic.flags = (track & MUSIC_TRACKMASK);
|
||||
mapmusic.position = position;
|
||||
mapmusic.resume = 0;
|
||||
@@ -2246,7 +2258,7 @@ static void Command_RestartAudio_f(void)
|
||||
I_StartupSound();
|
||||
I_InitMusic();
|
||||
|
||||
// These must be called or no sound and music until manually set.
|
||||
// These must be called or no sound and music until manually set.
|
||||
|
||||
I_SetSfxVolume(cv_soundvolume.value);
|
||||
#ifdef NO_MIDI
|
||||
|
||||
@@ -32,6 +32,8 @@ extern consvar_t stereoreverse;
|
||||
extern consvar_t cv_soundvolume, cv_digmusicvolume;//, cv_midimusicvolume;
|
||||
extern consvar_t cv_numChannels;
|
||||
|
||||
extern consvar_t cv_samesoundlimit;
|
||||
|
||||
extern consvar_t cv_audbuffersize;
|
||||
//extern consvar_t cv_resetmusic;
|
||||
extern consvar_t cv_gamedigimusic;
|
||||
|
||||
+14
-5
@@ -1806,13 +1806,22 @@ void I_SleepDuration(precise_t duration)
|
||||
{
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
|
||||
UINT64 precision = I_GetPrecisePrecision();
|
||||
struct timespec ts = {
|
||||
precise_t dest = I_GetPreciseTime() + duration;
|
||||
precise_t slack = (precision / 5000); // 0.2 ms slack
|
||||
if (duration > slack)
|
||||
{
|
||||
duration -= slack;
|
||||
struct timespec ts = {
|
||||
.tv_sec = static_cast<__time_t>(duration / precision),
|
||||
.tv_nsec = static_cast<__syscall_slong_t>(duration * 1000000000 / precision % 1000000000),
|
||||
};
|
||||
int status;
|
||||
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
|
||||
while (status == EINTR);
|
||||
};
|
||||
int status;
|
||||
do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
|
||||
while (status == EINTR);
|
||||
}
|
||||
|
||||
// busy-wait the rest
|
||||
while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0);
|
||||
#elif defined (MIN_SLEEP_DURATION_MS)
|
||||
UINT64 precision = I_GetPrecisePrecision();
|
||||
INT32 sleepvalue = cv_sleep.value;
|
||||
|
||||
@@ -1361,6 +1361,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
||||
{
|
||||
wasfullscreen = SDL_FALSE;
|
||||
SDL_SetWindowFullscreen(window, 0);
|
||||
I_SetBorderlessWindow();
|
||||
}
|
||||
|
||||
// Reposition window only in windowed mode
|
||||
@@ -1380,6 +1381,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
||||
if (fullscreen)
|
||||
{
|
||||
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
I_SetBorderlessWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -528,14 +528,12 @@ void I_FreeSfx(sfxinfo_t *sfx)
|
||||
sfx->lumpnum = LUMPERROR;
|
||||
}
|
||||
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, INT32 channel)
|
||||
{
|
||||
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
|
||||
INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
|
||||
Mix_Volume(handle, volume);
|
||||
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
|
||||
(void)pitch; // Mixer can't handle pitch
|
||||
(void)priority; // priority and channel management is handled by SRB2...
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -549,12 +547,11 @@ boolean I_SoundIsPlaying(INT32 handle)
|
||||
return Mix_Playing(handle);
|
||||
}
|
||||
|
||||
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch)
|
||||
void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep)
|
||||
{
|
||||
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
|
||||
Mix_Volume(handle, volume);
|
||||
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
|
||||
(void)pitch;
|
||||
}
|
||||
|
||||
void I_SetSfxVolume(UINT8 volume)
|
||||
|
||||
+1
-1
@@ -1079,7 +1079,7 @@ void I_StartupSound(void)
|
||||
{
|
||||
#ifndef HAVE_MIXER
|
||||
#ifndef NO_MIDI
|
||||
midi_disabled =
|
||||
midi_disabled =
|
||||
#endif
|
||||
digital_disabled = true;
|
||||
#endif
|
||||
|
||||
+888
-891
File diff suppressed because it is too large.
Load diff
@@ -78,9 +78,6 @@ struct sfxinfo_struct
|
||||
// pitch if a link
|
||||
INT32 pitch;
|
||||
|
||||
// volume if a link
|
||||
INT32 volume;
|
||||
|
||||
// sound data
|
||||
void *data;
|
||||
|
||||
@@ -91,11 +88,6 @@ struct sfxinfo_struct
|
||||
// 0 up to (NUMSKINSOUNDS-1), -1 = not skin specifc
|
||||
INT32 skinsound;
|
||||
|
||||
// this is checked every second to see if sound
|
||||
// can be thrown out (if 0, then decrement, if -1,
|
||||
// then throw out, if > 0, then it is in use)
|
||||
INT32 usefulness;
|
||||
|
||||
// lump number of sfx
|
||||
lumpnum_t lumpnum;
|
||||
};
|
||||
|
||||
+75
-47
@@ -126,6 +126,10 @@ void W_Shutdown(void)
|
||||
Z_Free(wad->lumpinfo[wad->numlumps].longname);
|
||||
Z_Free(wad->lumpinfo[wad->numlumps].fullname);
|
||||
}
|
||||
|
||||
M_AATreeFree(wad->startfolders);
|
||||
M_AATreeFree(wad->endfolders);
|
||||
|
||||
Z_Free(wad->lumpinfo);
|
||||
Z_Free(wad);
|
||||
}
|
||||
@@ -338,6 +342,11 @@ static void W_InvalidateLumpnumCache(void)
|
||||
memset(lumpnumcache, 0, sizeof (lumpnumcache));
|
||||
}
|
||||
|
||||
UINT32 W_HashLumpName(const char *name)
|
||||
{
|
||||
return FNV1a_HashLowercaseString(name);
|
||||
}
|
||||
|
||||
/** Detect a file type.
|
||||
* \todo Actually detect the wad/pkzip headers and whatnot, instead of just checking the extensions.
|
||||
*/
|
||||
@@ -362,11 +371,24 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const
|
||||
fseek(handle, 0, SEEK_END);
|
||||
lumpinfo->size = ftell(handle);
|
||||
fseek(handle, 0, SEEK_SET);
|
||||
strlcpy(lumpinfo->name, lumpname, 9);
|
||||
|
||||
// Allocate the lump's full and long name.
|
||||
lumpinfo->fullname = Z_StrDup(lumpname);
|
||||
lumpinfo->longname = Z_StrDup(lumpname);
|
||||
strlcpy(lumpinfo->name, lumpname, sizeof(lumpinfo->name));
|
||||
lumpinfo->namelength = strlen(lumpinfo->name);
|
||||
lumpinfo->hash.name = W_HashLumpName(lumpname);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lumpinfo->longname = Z_Malloc((lumpinfo->namelength + 1) * sizeof(char), PU_STATIC, NULL);
|
||||
strcpy(lumpinfo->longname, lumpname);
|
||||
lumpinfo->longname[lumpinfo->namelength] = '\0';
|
||||
lumpinfo->longnamelength = lumpinfo->namelength;
|
||||
lumpinfo->hash.longname = lumpinfo->hash.name;
|
||||
|
||||
// Allocate the lump's full name.
|
||||
lumpinfo->fullname = Z_Malloc((lumpinfo->namelength + 1) * sizeof(char), PU_STATIC, NULL);
|
||||
strcpy(lumpinfo->fullname, lumpname);
|
||||
lumpinfo->fullname[lumpinfo->namelength] = '\0';
|
||||
lumpinfo->fullnamelength = lumpinfo->namelength;
|
||||
lumpinfo->hash.fullname = lumpinfo->hash.name;
|
||||
|
||||
*numlumps = 1;
|
||||
return lumpinfo;
|
||||
@@ -454,16 +476,22 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
||||
lump_p->compression = CM_NOCOMPRESSION;
|
||||
memset(lump_p->name, 0x00, 9);
|
||||
strncpy(lump_p->name, fileinfo->name, 8);
|
||||
lump_p->namelength = strlen(lump_p->name);
|
||||
lump_p->hash.name = W_HashLumpName(lump_p->name);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->longname, fileinfo->name, 8);
|
||||
lump_p->longname[8] = '\0';
|
||||
lump_p->longnamelength = lump_p->namelength;
|
||||
lump_p->hash.longname = lump_p->hash.name;
|
||||
|
||||
// Allocate the lump's full name.
|
||||
lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->fullname, fileinfo->name, 8);
|
||||
lump_p->fullname[8] = '\0';
|
||||
lump_p->fullnamelength = lump_p->namelength;
|
||||
lump_p->hash.fullname = lump_p->hash.name;
|
||||
}
|
||||
free(fileinfov);
|
||||
*nlmp = numlumps;
|
||||
@@ -656,12 +684,18 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
|
||||
|
||||
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
|
||||
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
|
||||
lump_p->namelength = strlen(lump_p->name);
|
||||
lump_p->hash.name = W_HashLumpName(lump_p->name);
|
||||
|
||||
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
|
||||
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
|
||||
lump_p->longnamelength = strlen(lump_p->longname);
|
||||
lump_p->hash.longname = W_HashLumpName(lump_p->longname);
|
||||
|
||||
lump_p->fullname = (char*)(Z_Calloc(SHORT(zentry->namelen) + 1, PU_STATIC, NULL));
|
||||
strncpy(lump_p->fullname, fullname, SHORT(zentry->namelen));
|
||||
lump_p->fullnamelength = zentry->namelen;
|
||||
lump_p->hash.fullname = W_HashLumpName(lump_p->fullname);
|
||||
|
||||
switch(SHORT(zentry->compression))
|
||||
{
|
||||
@@ -817,6 +851,8 @@ UINT16 W_InitFile(const char *filename, boolean local)
|
||||
fseek(handle, 0, SEEK_END);
|
||||
wadfile->filesize = (unsigned)ftell(handle);
|
||||
wadfile->type = type;
|
||||
wadfile->startfolders = M_AATreeAlloc(0);
|
||||
wadfile->endfolders = M_AATreeAlloc(0);
|
||||
|
||||
// already generated, just copy it over
|
||||
M_Memcpy(&wadfile->md5sum, &md5sum, 16);
|
||||
@@ -872,7 +908,6 @@ UINT16 W_InitFile(const char *filename, boolean local)
|
||||
return wadfile->numlumps;
|
||||
}
|
||||
|
||||
|
||||
/** Tries to load a series of files.
|
||||
* All files are wads unless they have an extension of ".soc" or ".lua".
|
||||
*
|
||||
@@ -976,6 +1011,8 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||
{
|
||||
UINT16 i;
|
||||
static char uname[9];
|
||||
UINT32 hash;
|
||||
size_t namelen;
|
||||
|
||||
if (!TestValidLump(wad,0))
|
||||
return INT16_MAX;
|
||||
@@ -983,6 +1020,8 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||
memset(uname, 0, sizeof uname);
|
||||
strncpy(uname, name, sizeof(uname)-1);
|
||||
strupr(uname);
|
||||
namelen = strlen(uname);
|
||||
hash = W_HashLumpName(uname);
|
||||
|
||||
//
|
||||
// scan forward
|
||||
@@ -993,7 +1032,9 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||
{
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
if (memcmp(lump_p->name, uname, sizeof(uname) - 1) == 0)
|
||||
if (lump_p->namelength == namelen
|
||||
&& lump_p->hash.name == hash
|
||||
&& !memcmp(lump_p->name, uname, sizeof(uname) - 1))
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -1010,13 +1051,12 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||
UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||
{
|
||||
UINT16 i;
|
||||
static char uname[256 + 1];
|
||||
|
||||
if (!TestValidLump(wad,0))
|
||||
return INT16_MAX;
|
||||
|
||||
strlcpy(uname, name, sizeof uname);
|
||||
strupr(uname);
|
||||
size_t namelen = strlen(name);
|
||||
UINT32 hash = W_HashLumpName(name);
|
||||
|
||||
//
|
||||
// scan forward
|
||||
@@ -1027,7 +1067,9 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
||||
{
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
if (!strcmp(lump_p->longname, uname))
|
||||
if (lump_p->longnamelength == namelen
|
||||
&& lump_p->hash.longname == hash
|
||||
&& !stricmp(lump_p->longname, name))
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -1051,6 +1093,12 @@ UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlum
|
||||
INT32 i;
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
name_length = strlen(name);
|
||||
UINT32 hash = quickncasehash(name, name_length);
|
||||
|
||||
void *val = M_AATreeGet(wadfiles[wad]->startfolders, hash);
|
||||
if (val != NULL)
|
||||
return (uintptr_t)val;
|
||||
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, lump_p->fullname, name_length) == 0)
|
||||
@@ -1058,10 +1106,16 @@ UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlum
|
||||
/* SLADE is special and puts a single directory entry. Skip that. */
|
||||
if (strlen(lump_p->fullname) == name_length)
|
||||
i++;
|
||||
break;
|
||||
|
||||
M_AATreeSet(wadfiles[wad]->startfolders, hash, (void *)(uintptr_t)i);
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
|
||||
M_AATreeSet(wadfiles[wad]->startfolders, hash, (void *)INT16_MAX);
|
||||
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
// In a PK3 type of resource file, it looks for the next lumpinfo entry that doesn't share the specified pathfile.
|
||||
@@ -1072,11 +1126,20 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||
INT32 i;
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
size_t name_length = strlen(name);
|
||||
UINT32 hash = quickncasehash(name, name_length);
|
||||
|
||||
void *val = M_AATreeGet(wadfiles[wad]->endfolders, hash);
|
||||
if (val != NULL)
|
||||
return (uintptr_t)val;
|
||||
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, lump_p->fullname, name_length))
|
||||
break;
|
||||
}
|
||||
|
||||
M_AATreeSet(wadfiles[wad]->endfolders, hash, (void *)(uintptr_t)i);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -1201,41 +1264,6 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
// Look for valid map data through all added files in descendant order.
|
||||
// Get a map marker for WADs, and a standalone WAD file lump inside PK3s.
|
||||
// TODO: Make it search through cache first, maybe...?
|
||||
lumpnum_t W_CheckNumForMap(const char *name)
|
||||
{
|
||||
UINT16 lumpNum, end;
|
||||
UINT32 i;
|
||||
for (i = numwadfiles - 1; i < numwadfiles; i--)
|
||||
{
|
||||
if (wadfiles[i]->type == RET_WAD)
|
||||
{
|
||||
for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++)
|
||||
if (!strncmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
|
||||
return (i<<16) + lumpNum;
|
||||
}
|
||||
else if (wadfiles[i]->type == RET_PK3)
|
||||
{
|
||||
lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0);
|
||||
if (lumpNum != INT16_MAX)
|
||||
end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum);
|
||||
else
|
||||
continue;
|
||||
// Now look for the specified map.
|
||||
for (; lumpNum < end; lumpNum++)
|
||||
if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
|
||||
{
|
||||
const char *extension = strrchr(wadfiles[i]->lumpinfo[lumpNum].fullname, '.');
|
||||
if (!(extension && stricmp(extension, ".wad")))
|
||||
return (i<<16) + lumpNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
return LUMPERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// W_GetNumForName
|
||||
//
|
||||
|
||||
+17
-1
@@ -22,6 +22,8 @@ extern "C" {
|
||||
#include "hardware/hw_data.h"
|
||||
#endif
|
||||
|
||||
#include "m_aatree.h"
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
#endif
|
||||
@@ -75,8 +77,19 @@ typedef struct
|
||||
char name[9]; // filelump_t name[] e.g. "LongEntr"
|
||||
char *longname; // e.g. "LongEntryName"
|
||||
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
|
||||
|
||||
size_t namelength; // length of name
|
||||
size_t longnamelength; // length of longname
|
||||
size_t fullnamelength; // length of fullname
|
||||
|
||||
size_t size; // real (uncompressed) size
|
||||
compmethod compression; // lump compression method
|
||||
|
||||
struct {
|
||||
UINT32 name; // hash of name
|
||||
UINT32 longname; // hash of longname
|
||||
UINT32 fullname; // hash of fullname
|
||||
} hash;
|
||||
} lumpinfo_t;
|
||||
|
||||
// =========================================================================
|
||||
@@ -131,6 +144,8 @@ typedef struct wadfile_s
|
||||
#ifdef ROTSPRITE
|
||||
lumpcache_t *rotcache; // Cache rotsprites for rotating patches.
|
||||
#endif
|
||||
aatree_t *startfolders;
|
||||
aatree_t *endfolders;
|
||||
UINT16 numlumps; // this wad's number of resources
|
||||
FILE *handle;
|
||||
UINT32 filesize; // for network
|
||||
@@ -167,6 +182,8 @@ INT32 W_AddAutoloadedLocalFiles(char **filenames);
|
||||
|
||||
#define W_FileHasFolders(wadfile) ((wadfile)->type == RET_PK3)
|
||||
|
||||
UINT32 W_HashLumpName(const char *name);
|
||||
|
||||
const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
|
||||
const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
||||
|
||||
@@ -180,7 +197,6 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
|
||||
lumpnum_t W_CheckNumForMap(const char *name);
|
||||
lumpnum_t W_CheckNumForName(const char *name);
|
||||
lumpnum_t W_CheckNumForLongName(const char *name);
|
||||
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
|
||||
|
||||
Reference in new issue
Block a user